Bug 944074 - Remove the ParallelArray constructor. (r=nmatsakis)
authorShu-yu Guo <shu@rfrn.org>
Thu, 12 Dec 2013 23:18:43 -0800
changeset 177385 b07452dd6d7f111495b6027f594c5869b425bb61
parent 177384 273e7ed05fa39854599426618ea692d903b6e14a
child 177386 daa324f7e65a2910fe12a4eab2b91b441d2860cb
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs944074
milestone29.0a1
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 944074 - Remove the ParallelArray constructor. (r=nmatsakis)
dom/tests/mochitest/general/test_interfaces.html
js/src/Makefile.in
js/src/builtin/Array.js
js/src/builtin/ParallelArray.cpp
js/src/builtin/ParallelArray.h
js/src/builtin/ParallelArray.js
js/src/builtin/Utilities.js
js/src/jit-test/lib/parallelarray-helpers.js
js/src/jit-test/tests/auto-regress/bug755564.js
js/src/jit-test/tests/auto-regress/bug783923.js
js/src/jit-test/tests/auto-regress/bug784011.js
js/src/jit-test/tests/auto-regress/bug786106.js
js/src/jit-test/tests/auto-regress/bug789107.js
js/src/jit-test/tests/auto-regress/bug791445.js
js/src/jit-test/tests/baseline/bug846072.js
js/src/jit-test/tests/baseline/bug857579.js
js/src/jit-test/tests/basic/bug815652.js
js/src/jit-test/tests/parallel/binary-arith-numbers.js
js/src/jit-test/tests/parallel/bug783924.js
js/src/jit-test/tests/parallel/bug787282.js
js/src/jit-test/tests/parallel/bug853555.js
js/src/jit-test/tests/parallel/bug853573.js
js/src/jit-test/tests/parallel/bug854021.js
js/src/jit-test/tests/parallel/bug854050.js
js/src/jit-test/tests/parallel/bug854381.js
js/src/jit-test/tests/parallel/bug857846.js
js/src/jit-test/tests/parallel/bug858077.js
js/src/jit-test/tests/parallel/bug858582.js
js/src/jit-test/tests/parallel/bug890465.js
js/src/jit-test/tests/parallel/bug894782.js
js/src/jit-test/tests/parallel/bug895782.js
js/src/jit-test/tests/parallel/bug908939.js
js/src/jit-test/tests/parallel/bug909599.js
js/src/jit-test/tests/parallel/compare-values.js
js/src/jit-test/tests/parallel/comprehension-2.js
js/src/jit-test/tests/parallel/comprehension-fn-args.js
js/src/jit-test/tests/parallel/comprehension-scale.js
js/src/jit-test/tests/parallel/constructor-1.js
js/src/jit-test/tests/parallel/constructor-2.js
js/src/jit-test/tests/parallel/constructor-3.js
js/src/jit-test/tests/parallel/constructor-4.js
js/src/jit-test/tests/parallel/constructor-5.js
js/src/jit-test/tests/parallel/constructor-throws.js
js/src/jit-test/tests/parallel/element-1.js
js/src/jit-test/tests/parallel/element-2.js
js/src/jit-test/tests/parallel/element-3.js
js/src/jit-test/tests/parallel/flatten-1.js
js/src/jit-test/tests/parallel/flatten-2.js
js/src/jit-test/tests/parallel/flatten-3.js
js/src/jit-test/tests/parallel/flatten-throws.js
js/src/jit-test/tests/parallel/get-1.js
js/src/jit-test/tests/parallel/get-2.js
js/src/jit-test/tests/parallel/get-3.js
js/src/jit-test/tests/parallel/get-4.js
js/src/jit-test/tests/parallel/get-6.js
js/src/jit-test/tests/parallel/holes-1.js
js/src/jit-test/tests/parallel/holes-2.js
js/src/jit-test/tests/parallel/index-1.js
js/src/jit-test/tests/parallel/index-2.js
js/src/jit-test/tests/parallel/index-3.js
js/src/jit-test/tests/parallel/index-4.js
js/src/jit-test/tests/parallel/inline-new-bad-type.js
js/src/jit-test/tests/parallel/length-1.js
js/src/jit-test/tests/parallel/length-2.js
js/src/jit-test/tests/parallel/length-3.js
js/src/jit-test/tests/parallel/mandelbrot.js
js/src/jit-test/tests/parallel/map-3.js
js/src/jit-test/tests/parallel/overflow-throws.js
js/src/jit-test/tests/parallel/partition-1.js
js/src/jit-test/tests/parallel/partition-throws.js
js/src/jit-test/tests/parallel/reduce-higher-dim.js
js/src/jit-test/tests/parallel/reduce-throws.js
js/src/jit-test/tests/parallel/scan-3.js
js/src/jit-test/tests/parallel/scan-throws.js
js/src/jit-test/tests/parallel/scatter-1.js
js/src/jit-test/tests/parallel/scatter-10.js
js/src/jit-test/tests/parallel/scatter-11.js
js/src/jit-test/tests/parallel/scatter-12.js
js/src/jit-test/tests/parallel/scatter-13.js
js/src/jit-test/tests/parallel/scatter-2.js
js/src/jit-test/tests/parallel/scatter-3.js
js/src/jit-test/tests/parallel/scatter-4.js
js/src/jit-test/tests/parallel/scatter-5.js
js/src/jit-test/tests/parallel/scatter-6.js
js/src/jit-test/tests/parallel/scatter-7.js
js/src/jit-test/tests/parallel/scatter-8.js
js/src/jit-test/tests/parallel/scatter-9.js
js/src/jit-test/tests/parallel/scatter-regression-1.js
js/src/jit-test/tests/parallel/scatter-throws.js
js/src/jit-test/tests/parallel/shape-1.js
js/src/jit-test/tests/parallel/shape-2.js
js/src/jit-test/tests/parallel/shape-3.js
js/src/jit-test/tests/parallel/shape-4.js
js/src/jit-test/tests/parallel/shape-5.js
js/src/jit-test/tests/parallel/stack-overflow.js
js/src/jit-test/tests/parallel/toString-1.js
js/src/jit/BaselineIC.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/IonBuilder.h
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.h
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/ParallelSafetyAnalysis.cpp
js/src/jit/VMFunctions.cpp
js/src/js.msg
js/src/jsapi.cpp
js/src/jsinferinlines.h
js/src/jsprototypes.h
js/src/moz.build
js/src/vm/ForkJoin.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/SelfHosting.cpp
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -64,17 +64,16 @@ var ecmaGlobals =
     {name: "Intl", desktop: true},
     "Iterator",
     "JSON",
     "Map",
     "Math",
     {name: "NaN", xbl: false},
     "Number",
     "Object",
-    {name: "ParallelArray", nightly: true},
     "Proxy",
     "RangeError",
     "ReferenceError",
     "RegExp",
     "Set",
     "StopIteration",
     "String",
     "SyntaxError",
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -574,17 +574,16 @@ selfhosting_srcs := \
   $(srcdir)/builtin/Utilities.js \
   $(srcdir)/builtin/Array.js \
   $(srcdir)/builtin/Date.js \
   $(srcdir)/builtin/Intl.js \
   $(srcdir)/builtin/IntlData.js \
   $(srcdir)/builtin/Iterator.js \
   $(srcdir)/builtin/Map.js \
   $(srcdir)/builtin/Number.js \
-  $(srcdir)/builtin/ParallelArray.js \
   $(srcdir)/builtin/String.js \
   $(srcdir)/builtin/Set.js \
   $(srcdir)/builtin/TypedObject.js \
   $(NULL)
 
 selfhosted_out_h_deps := \
   $(selfhosting_srcs) \
   $(srcdir)/js.msg \
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -551,16 +551,18 @@ function ArrayValues() {
 function ArrayEntries() {
     return CreateArrayIterator(this, ITEM_KIND_KEY_AND_VALUE);
 }
 
 function ArrayKeys() {
     return CreateArrayIterator(this, ITEM_KIND_KEY);
 }
 
+#ifdef ENABLE_PARALLEL_JS
+
 /*
  * Strawman spec:
  *   http://wiki.ecmascript.org/doku.php?id=strawman:data_parallelism
  */
 
 /* The mode asserts options object. */
 #define TRY_PARALLEL(MODE) \
   ((!MODE || MODE.mode !== "seq"))
@@ -644,18 +646,16 @@ function ComputeAllSliceBounds(numItems,
   }
   for (; i < numSlices; i++) {
     ARRAY_PUSH(info, SLICE_INFO(counter, counter + sliceWidth));
     counter += sliceWidth;
   }
   return info;
 }
 
-#ifdef ENABLE_PARALLEL_JS
-
 /**
  * Creates a new array by applying |func(e, i, self)| for each element |e|
  * with index |i|.
  */
 function ArrayMapPar(func, mode) {
   if (!IsCallable(func))
     ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, func));
 
deleted file mode 100644
--- a/js/src/builtin/ParallelArray.cpp
+++ /dev/null
@@ -1,247 +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:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "builtin/ParallelArray.h"
-
-#include "jsobj.h"
-
-#include "vm/GlobalObject.h"
-#include "vm/String.h"
-
-#include "jsobjinlines.h"
-
-using namespace js;
-
-//
-// ParallelArrayObject
-//
-
-FixedHeapPtr<PropertyName> ParallelArrayObject::ctorNames[NumCtors];
-
-const JSFunctionSpec ParallelArrayObject::methods[] = {
-    JS_SELF_HOSTED_FN("map",       "ParallelArrayMap",       2, 0),
-    JS_SELF_HOSTED_FN("reduce",    "ParallelArrayReduce",    2, 0),
-    JS_SELF_HOSTED_FN("scan",      "ParallelArrayScan",      2, 0),
-    JS_SELF_HOSTED_FN("scatter",   "ParallelArrayScatter",   5, 0),
-    JS_SELF_HOSTED_FN("filter",    "ParallelArrayFilter",    2, 0),
-    JS_SELF_HOSTED_FN("partition", "ParallelArrayPartition", 1, 0),
-    JS_SELF_HOSTED_FN("flatten",   "ParallelArrayFlatten",   0, 0),
-
-    // FIXME #838906. Note that `get()` is not currently defined on this table but
-    // rather is assigned to each instance of ParallelArray as an own
-    // property.  This is a bit of a hack designed to supply a
-    // specialized version of get() based on the dimensionality of the
-    // receiver.  In the future we can improve this by (1) extending
-    // TI to track the dimensionality of the receiver and (2) using a
-    // hint to aggressively inline calls to get().
-    // JS_SELF_HOSTED_FN("get", "ParallelArrayGet", 1, 0),
-
-    JS_SELF_HOSTED_FN("toString",  "ParallelArrayToString",  0, 0),
-    JS_FS_END
-};
-
-const JSPropertySpec ParallelArrayObject::properties[] = {
-    JS_SELF_HOSTED_GET("length", "ParallelArrayLength", JSPROP_PERMANENT),
-    JS_PS_END
-};
-
-const Class ParallelArrayObject::protoClass = {
-    "ParallelArray",
-    JSCLASS_HAS_CACHED_PROTO(JSProto_ParallelArray),
-    JS_PropertyStub,         // addProperty
-    JS_DeletePropertyStub,   // delProperty
-    JS_PropertyStub,         // getProperty
-    JS_StrictPropertyStub,   // setProperty
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub
-};
-
-const Class ParallelArrayObject::class_ = {
-    "ParallelArray",
-    JSCLASS_HAS_CACHED_PROTO(JSProto_ParallelArray),
-    JS_PropertyStub,         // addProperty
-    JS_DeletePropertyStub,   // delProperty
-    JS_PropertyStub,         // getProperty
-    JS_StrictPropertyStub,   // setProperty
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub
-};
-
-/*static*/ bool
-ParallelArrayObject::initProps(JSContext *cx, HandleObject obj)
-{
-    RootedValue undef(cx, UndefinedValue());
-    RootedValue zero(cx, Int32Value(0));
-
-    if (!JSObject::defineProperty(cx, obj, cx->names().buffer, undef))
-        return false;
-    if (!JSObject::defineProperty(cx, obj, cx->names().offset, zero))
-        return false;
-    if (!JSObject::defineProperty(cx, obj, cx->names().shape, undef))
-        return false;
-    if (!JSObject::defineProperty(cx, obj, cx->names().get, undef))
-        return false;
-
-    return true;
-}
-
-/*static*/ bool
-ParallelArrayObject::construct(JSContext *cx, unsigned argc, Value *vp)
-{
-    RootedFunction ctor(cx, getConstructor(cx, argc));
-    if (!ctor)
-        return false;
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return constructHelper(cx, &ctor, args);
-}
-
-/* static */ JSFunction *
-ParallelArrayObject::maybeGetConstructor(GlobalObject *global, unsigned argc)
-{
-    PropertyName *ctorName = ctorNames[js::Min(argc, NumCtors - 1)];
-    Value ctorValue;
-    if (!global->maybeGetIntrinsicValue(ctorName, &ctorValue))
-        return nullptr;
-    JS_ASSERT(ctorValue.isObject() && ctorValue.toObject().is<JSFunction>());
-    return &ctorValue.toObject().as<JSFunction>();
-}
-
-/* static */ JSFunction *
-ParallelArrayObject::getConstructor(JSContext *cx, unsigned argc)
-{
-    RootedPropertyName ctorName(cx, ctorNames[js::Min(argc, NumCtors - 1)]);
-    RootedValue ctorValue(cx);
-    if (!cx->global()->getIntrinsicValue(cx, ctorName, &ctorValue))
-        return nullptr;
-    JS_ASSERT(ctorValue.isObject() && ctorValue.toObject().is<JSFunction>());
-    return &ctorValue.toObject().as<JSFunction>();
-}
-
-/*static*/ JSObject *
-ParallelArrayObject::newInstance(JSContext *cx, NewObjectKind newKind /* = GenericObject */)
-{
-    gc::AllocKind kind = gc::GetGCObjectKind(NumFixedSlots);
-    RootedObject result(cx, NewBuiltinClassInstance(cx, &class_, kind, newKind));
-    if (!result)
-        return nullptr;
-
-    // Add in the basic PA properties now with default values:
-    if (!initProps(cx, result))
-        return nullptr;
-
-    return result;
-}
-
-/*static*/ bool
-ParallelArrayObject::constructHelper(JSContext *cx, MutableHandleFunction ctor, CallArgs &args0)
-{
-    RootedObject result(cx, newInstance(cx, TenuredObject));
-    if (!result)
-        return false;
-
-    if (cx->typeInferenceEnabled()) {
-        jsbytecode *pc;
-        RootedScript script(cx, cx->currentScript(&pc));
-        if (script) {
-            if (ctor->nonLazyScript()->shouldCloneAtCallsite()) {
-                ctor.set(CloneFunctionAtCallsite(cx, ctor, script, pc));
-                if (!ctor)
-                    return false;
-            }
-
-            // Create the type object for the PA.  Add in the current
-            // properties as definite properties if this type object is newly
-            // created.  To tell if it is newly created, we check whether it
-            // has any properties yet or not, since any returned type object
-            // must have been created by this same C++ code and hence would
-            // already have properties if it had been returned before.
-            types::TypeObject *paTypeObject =
-                types::TypeScript::InitObject(cx, script, pc, JSProto_ParallelArray);
-            if (!paTypeObject)
-                return false;
-            if (paTypeObject->getPropertyCount() == 0 && !paTypeObject->unknownProperties()) {
-                if (!paTypeObject->addDefiniteProperties(cx, result))
-                    return false;
-
-                // addDefiniteProperties() above should have added one
-                // property for each of the fixed slots:
-                JS_ASSERT(paTypeObject->getPropertyCount() == NumFixedSlots);
-            }
-            result->setType(paTypeObject);
-        }
-    }
-
-    InvokeArgs args(cx);
-    if (!args.init(args0.length()))
-        return false;
-
-    args.setCallee(ObjectValue(*ctor));
-    args.setThis(ObjectValue(*result));
-
-    for (uint32_t i = 0; i < args0.length(); i++)
-        args[i].set(args0[i]);
-
-    if (!Invoke(cx, args))
-        return false;
-
-    args0.rval().setObject(*result);
-    return true;
-}
-
-JSObject *
-ParallelArrayObject::initClass(JSContext *cx, HandleObject obj)
-{
-    JS_ASSERT(obj->isNative());
-
-    // Cache constructor names.
-    {
-        static const char *const ctorStrs[NumCtors] = {
-            "ParallelArrayConstructEmpty",
-            "ParallelArrayConstructFromArray",
-            "ParallelArrayConstructFromFunction",
-            "ParallelArrayConstructFromFunctionMode"
-        };
-        for (uint32_t i = 0; i < NumCtors; i++) {
-            JSAtom *atom = Atomize(cx, ctorStrs[i], strlen(ctorStrs[i]), InternAtom);
-            if (!atom)
-                return nullptr;
-            ctorNames[i].init(atom->asPropertyName());
-        }
-    }
-
-    Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
-
-    RootedObject proto(cx, global->createBlankPrototype(cx, &protoClass));
-    if (!proto)
-        return nullptr;
-
-    JSProtoKey key = JSProto_ParallelArray;
-    RootedFunction ctor(cx, global->createConstructor(cx, construct,
-                                                      cx->names().ParallelArray, 0));
-    if (!ctor ||
-        !LinkConstructorAndPrototype(cx, ctor, proto) ||
-        !DefinePropertiesAndBrand(cx, proto, properties, methods) ||
-        !DefineConstructorAndPrototype(cx, global, key, ctor, proto))
-    {
-        return nullptr;
-    }
-
-    return proto;
-}
-
-bool
-ParallelArrayObject::is(const Value &v)
-{
-    return v.isObject() && v.toObject().hasClass(&class_);
-}
-
-JSObject *
-js_InitParallelArrayClass(JSContext *cx, js::HandleObject obj)
-{
-    return ParallelArrayObject::initClass(cx, obj);
-}
deleted file mode 100644
--- a/js/src/builtin/ParallelArray.h
+++ /dev/null
@@ -1,56 +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:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef builtin_ParallelArray_h
-#define builtin_ParallelArray_h
-
-#include "jsobj.h"
-
-namespace js {
-
-class ParallelArrayObject : public JSObject
-{
-    static const Class protoClass;
-    static const JSFunctionSpec methods[];
-    static const JSPropertySpec properties[];
-    static const uint32_t NumFixedSlots = 4;
-    static const uint32_t NumCtors = 4;
-    static FixedHeapPtr<PropertyName> ctorNames[NumCtors];
-
-    static bool initProps(JSContext *cx, HandleObject obj);
-
-  public:
-    static const Class class_;
-
-    static bool construct(JSContext *cx, unsigned argc, Value *vp);
-    static bool constructHelper(JSContext *cx, MutableHandleFunction ctor, CallArgs &args);
-
-    // Creates a new ParallelArray instance with the correct number of slots
-    // and so forth.
-    //
-    // NOTE: This object will NOT have the correct type object! It is
-    // up to the caller to adjust the type object appropriately
-    // before releasing the object into the wild.  You probably want
-    // to be calling construct() above, which will adjust the type
-    // object for you, since ParallelArray type objects must be setup
-    // in a rather particular way to interact well with the
-    // self-hosted code.  See constructHelper() for details.
-    static JSObject *newInstance(JSContext *cx, NewObjectKind newKind = GenericObject);
-
-    // Get the constructor function for argc number of arguments.
-    static JSFunction *maybeGetConstructor(GlobalObject *global, unsigned argc);
-    static JSFunction *getConstructor(JSContext *cx, unsigned argc);
-
-    static JSObject *initClass(JSContext *cx, HandleObject obj);
-    static bool is(const Value &v);
-};
-
-} // namespace js
-
-extern JSObject *
-js_InitParallelArrayClass(JSContext *cx, js::HandleObject obj);
-
-#endif /* builtin_ParallelArray_h */
deleted file mode 100644
--- a/js/src/builtin/ParallelArray.js
+++ /dev/null
@@ -1,1253 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// FIXME(bug 844882): Parallel array properties should not be exposed.
-
-/**
- * Compute the partial products in reverse order.
- * e.g., if the shape is [A,B,C,D], then the
- * array |products| will be [1,D,CD,BCD].
- */
-function ComputeProducts(shape) {
-  var product = 1;
-  var products = [1];
-  var sdimensionality = shape.length;
-  for (var i = sdimensionality - 1; i > 0; i--) {
-    product *= shape[i];
-    ARRAY_PUSH(products, product);
-  }
-  return products;
-}
-
-/**
- * Given a shape and some index |index1d|, computes and returns an
- * array containing the N-dimensional index that maps to |index1d|.
- */
-function ComputeIndices(shape, index1d) {
-
-  var products = ComputeProducts(shape);
-  var l = shape.length;
-
-  var result = [];
-  for (var i = 0; i < l; i++) {
-    // Obtain product of all higher dimensions.
-    // So if i == 0 and shape is [A,B,C,D], yields BCD.
-    var stride = products[l - i - 1];
-
-    // Compute how many steps of width stride we could take.
-    var index = (index1d / stride) | 0;
-    ARRAY_PUSH(result, index);
-
-    // Adjust remaining indices for smaller dimensions.
-    index1d -= (index * stride);
-  }
-
-  return result;
-}
-
-function StepIndices(shape, indices) {
-  for (var i = shape.length - 1; i >= 0; i--) {
-    var indexi = indices[i] + 1;
-    if (indexi < shape[i]) {
-      indices[i] = indexi;
-      return;
-    }
-    indices[i] = 0;
-  }
-}
-
-// Constructor
-//
-// We split the 3 construction cases so that we don't case on arguments.
-
-/**
- * This is the function invoked for |new ParallelArray()|
- */
-function ParallelArrayConstructEmpty() {
-  this.buffer = [];
-  this.offset = 0;
-  this.shape = [0];
-  this.get = ParallelArrayGet1;
-}
-
-/**
- * This is the function invoked for |new ParallelArray(array)|.
- * It copies the data from its array-like argument |array|.
- */
-function ParallelArrayConstructFromArray(array) {
-  var buffer = ToObject(array);
-  var length = buffer.length >>> 0;
-  if (length !== buffer.length)
-    ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-
-  var buffer1 = [];
-  for (var i = 0; i < length; i++)
-    ARRAY_PUSH(buffer1, buffer[i]);
-
-  this.buffer = buffer1;
-  this.offset = 0;
-  this.shape = [length];
-  this.get = ParallelArrayGet1;
-}
-
-/**
- * Wrapper around |ParallelArrayConstructFromComprehension()| for the
- * case where 2 arguments are supplied. This is typically what users will
- * invoke. We provide an explicit two-argument version rather than
- * relying on JS's semantics for absent arguments because it simplifies
- * the ion code that does inlining of PA constructors.
- */
-function ParallelArrayConstructFromFunction(shape, func) {
-  return ParallelArrayConstructFromComprehension(this, shape, func, undefined);
-}
-
-/**
- * Wrapper around |ParallelArrayConstructFromComprehension()| for the
- * case where 3 arguments are supplied.
- */
-function ParallelArrayConstructFromFunctionMode(shape, func, mode) {
-  return ParallelArrayConstructFromComprehension(this, shape, func, mode);
-}
-
-/**
- * "Comprehension form": This is the function invoked for |new
- * ParallelArray(dim, fn)|. If |dim| is a number, then it creates a
- * new 1-dimensional parallel array with shape |[dim]| where index |i|
- * is equal to |fn(i)|. If |dim| is a vector, then it creates a new
- * N-dimensional parallel array where index |a, b, ... z| is equal to
- * |fn(a, b, ...z)|.
- *
- * The final |mode| argument is an internal argument used only
- * during our unit-testing.
- */
-function ParallelArrayConstructFromComprehension(self, shape, func, mode) {
-  // FIXME(bug 844887): Check |IsCallable(func)|
-
-  if (typeof shape === "number") {
-    var length = shape >>> 0;
-    if (length !== shape)
-      ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-    ParallelArrayBuild(self, [length], func, mode);
-  } else if (!shape || typeof shape.length !== "number") {
-    ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-  } else {
-    var shape1 = [];
-    for (var i = 0, l = shape.length; i < l; i++) {
-      var s0 = shape[i];
-      var s1 = s0 >>> 0;
-      if (s1 !== s0)
-        ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-      ARRAY_PUSH(shape1, s1);
-    }
-    ParallelArrayBuild(self, shape1, func, mode);
-  }
-}
-
-/**
- * Internal function used when constructing new parallel arrays. The
- * NewParallelArray() intrinsic takes a ctor function which it invokes
- * with the given shape, buffer, offset. The |this| parameter will be
- * the newly constructed parallel array.
- */
-function ParallelArrayView(shape, buffer, offset) {
-  this.shape = shape;
-  this.buffer = buffer;
-  this.offset = offset;
-
-  switch (shape.length) {
-    case 1: this.get = ParallelArrayGet1; break;
-    case 2: this.get = ParallelArrayGet2; break;
-    case 3: this.get = ParallelArrayGet3; break;
-    default: this.get = ParallelArrayGetN; break;
-  }
-
-  // Due to inlining of NewParallelArray, the return type of this function
-  // gets recorded as the return type of NewParallelArray at inlined sites, so
-  // we must take care to return the same thing.
-  return this;
-}
-
-/**
- * Helper for the comprehension form. Constructs an N-dimensional
- * array where |N == shape.length|. |shape| must be an array of
- * integers. The data for any given index vector |i| is determined by
- * |func(...i)|.
- */
-function ParallelArrayBuild(self, shape, func, mode) {
-  self.offset = 0;
-  self.shape = shape;
-
-  var length;
-  var xDimension, yDimension, zDimension;
-  var computefunc;
-
-  switch (shape.length) {
-  case 1:
-    length = shape[0];
-    self.get = ParallelArrayGet1;
-    computefunc = fill1;
-    break;
-  case 2:
-    xDimension = shape[0];
-    yDimension = shape[1];
-    length = xDimension * yDimension;
-    self.get = ParallelArrayGet2;
-    computefunc = fill2;
-    break;
-  case 3:
-    xDimension = shape[0];
-    yDimension = shape[1];
-    zDimension = shape[2];
-    length = xDimension * yDimension * zDimension;
-    self.get = ParallelArrayGet3;
-    computefunc = fill3;
-    break;
-  default:
-    length = 1;
-    for (var i = 0; i < shape.length; i++)
-      length *= shape[i];
-    self.get = ParallelArrayGetN;
-    computefunc = fillN;
-    break;
-  }
-
-  var buffer = self.buffer = NewDenseArray(length);
-
-  parallel: for (;;) {
-    // Avoid parallel compilation if we are already nested in another
-    // parallel section or the user told us not to parallelize. The
-    // use of a for (;;) loop is working around some ion limitations:
-    //
-    // - Breaking out of named blocks does not currently work (bug 684384);
-    // - Unreachable Code Elim. can't properly handle if (a && b) (bug 669796)
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-    if (computefunc === fillN)
-      break parallel;
-
-    var chunks = ComputeNumChunks(length);
-    var numSlices = ForkJoinSlices();
-    var info = ComputeAllSliceBounds(chunks, numSlices);
-    ForkJoin(constructSlice, ForkJoinMode(mode));
-    return;
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  computefunc(0, length);
-  return;
-
-  function constructSlice(sliceId, numSlices, warmup) {
-    var chunkPos = info[SLICE_POS(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-
-    if (warmup && chunkEnd > chunkPos)
-      chunkEnd = chunkPos + 1;
-
-    while (chunkPos < chunkEnd) {
-      var indexStart = chunkPos << CHUNK_SHIFT;
-      var indexEnd = std_Math_min(indexStart + CHUNK_SIZE, length);
-      computefunc(indexStart, indexEnd);
-      UnsafePutElements(info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    return chunkEnd == info[SLICE_END(sliceId)];
-  }
-
-  function fill1(indexStart, indexEnd) {
-    for (var i = indexStart; i < indexEnd; i++)
-      UnsafePutElements(buffer, i, func(i));
-  }
-
-  function fill2(indexStart, indexEnd) {
-    var x = (indexStart / yDimension) | 0;
-    var y = indexStart - x * yDimension;
-    for (var i = indexStart; i < indexEnd; i++) {
-      UnsafePutElements(buffer, i, func(x, y));
-      if (++y == yDimension) {
-        y = 0;
-        ++x;
-      }
-    }
-  }
-
-  function fill3(indexStart, indexEnd) {
-    var x = (indexStart / (yDimension * zDimension)) | 0;
-    var r = indexStart - x * yDimension * zDimension;
-    var y = (r / zDimension) | 0;
-    var z = r - y * zDimension;
-    for (var i = indexStart; i < indexEnd; i++) {
-      UnsafePutElements(buffer, i, func(x, y, z));
-      if (++z == zDimension) {
-        z = 0;
-        if (++y == yDimension) {
-          y = 0;
-          ++x;
-        }
-      }
-    }
-  }
-
-  function fillN(indexStart, indexEnd) {
-    var indices = ComputeIndices(shape, indexStart);
-    for (var i = indexStart; i < indexEnd; i++) {
-      var result = callFunction(std_Function_apply, func, null, indices);
-      UnsafePutElements(buffer, i, result);
-      StepIndices(shape, indices);
-    }
-  }
-}
-
-/**
- * Creates a new parallel array by applying |func(e, i, self)| for each
- * element |e| with index |i|. Note that
- * this always operates on the outermost dimension only.
- */
-function ParallelArrayMap(func, mode) {
-  // FIXME(bug 844887): Check |this instanceof ParallelArray|
-  // FIXME(bug 844887): Check |IsCallable(func)|
-
-  var self = this;
-  var length = self.shape[0];
-  var buffer = NewDenseArray(length);
-
-  parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-
-    var chunks = ComputeNumChunks(length);
-    var numSlices = ForkJoinSlices();
-    var info = ComputeAllSliceBounds(chunks, numSlices);
-    ForkJoin(mapSlice, ForkJoinMode(mode));
-    return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  for (var i = 0; i < length; i++) {
-    // Note: Unlike JS arrays, parallel arrays cannot have holes.
-    var v = func(self.get(i), i, self);
-    UnsafePutElements(buffer, i, v);
-  }
-  return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-
-  function mapSlice(sliceId, numSlices, warmup) {
-    var chunkPos = info[SLICE_POS(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-
-    if (warmup && chunkEnd > chunkPos + 1)
-      chunkEnd = chunkPos + 1;
-
-    while (chunkPos < chunkEnd) {
-      var indexStart = chunkPos << CHUNK_SHIFT;
-      var indexEnd = std_Math_min(indexStart + CHUNK_SIZE, length);
-
-      for (var i = indexStart; i < indexEnd; i++)
-        UnsafePutElements(buffer, i, func(self.get(i), i, self));
-
-      UnsafePutElements(info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    return chunkEnd == info[SLICE_END(sliceId)];
-  }
-
-  return undefined;
-}
-
-/**
- * Reduces the elements in a parallel array's outermost dimension
- * using the given reduction function.
- */
-function ParallelArrayReduce(func, mode) {
-  // FIXME(bug 844887): Check |this instanceof ParallelArray|
-  // FIXME(bug 844887): Check |IsCallable(func)|
-
-  var self = this;
-  var length = self.shape[0];
-
-  if (length === 0)
-    ThrowError(JSMSG_PAR_ARRAY_REDUCE_EMPTY);
-
-  parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-
-    var chunks = ComputeNumChunks(length);
-    var numSlices = ForkJoinSlices();
-    if (chunks < numSlices)
-      break parallel;
-
-    var info = ComputeAllSliceBounds(chunks, numSlices);
-    var subreductions = NewDenseArray(numSlices);
-    ForkJoin(reduceSlice, ForkJoinMode(mode));
-    var accumulator = subreductions[0];
-    for (var i = 1; i < numSlices; i++)
-      accumulator = func(accumulator, subreductions[i]);
-    return accumulator;
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  var accumulator = self.get(0);
-  for (var i = 1; i < length; i++)
-    accumulator = func(accumulator, self.get(i));
-  return accumulator;
-
-  function reduceSlice(sliceId, numSlices, warmup) {
-    var chunkStart = info[SLICE_START(sliceId)];
-    var chunkPos = info[SLICE_POS(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-
-    // (*) This function is carefully designed so that the warmup
-    // (which executes with chunkStart === chunkPos) will execute all
-    // potential loads and stores. In particular, the warmup run
-    // processes two chunks rather than one. Moreover, it stores
-    // accumulator into subreductions and then loads it again to
-    // ensure that the load is executed during the warmup, as it will
-    // certainly be executed during subsequent runs.
-
-    if (warmup && chunkEnd > chunkPos + 2)
-      chunkEnd = chunkPos + 2;
-
-    if (chunkStart === chunkPos) {
-      var indexPos = chunkStart << CHUNK_SHIFT;
-      var accumulator = reduceChunk(self.get(indexPos), indexPos + 1, indexPos + CHUNK_SIZE);
-
-      UnsafePutElements(subreductions, sliceId, accumulator, // see (*) above
-                        info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    var accumulator = subreductions[sliceId]; // see (*) above
-
-    while (chunkPos < chunkEnd) {
-      var indexPos = chunkPos << CHUNK_SHIFT;
-      accumulator = reduceChunk(accumulator, indexPos, indexPos + CHUNK_SIZE);
-      UnsafePutElements(subreductions, sliceId, accumulator, info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    return chunkEnd == info[SLICE_END(sliceId)];
-  }
-
-  function reduceChunk(accumulator, from, to) {
-    to = std_Math_min(to, length);
-    for (var i = from; i < to; i++)
-      accumulator = func(accumulator, self.get(i));
-    return accumulator;
-  }
-
-  return undefined;
-}
-
-/**
- * |scan()| returns an array [s_0, ..., s_N] where
- * |s_i| is equal to the reduction (as per |reduce()|)
- * of elements |0..i|. This is the generalization
- * of partial sum.
- */
-function ParallelArrayScan(func, mode) {
-  // FIXME(bug 844887): Check |this instanceof ParallelArray|
-  // FIXME(bug 844887): Check |IsCallable(func)|
-
-  var self = this;
-  var length = self.shape[0];
-
-  if (length === 0)
-    ThrowError(JSMSG_PAR_ARRAY_REDUCE_EMPTY);
-
-  var buffer = NewDenseArray(length);
-
-  parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-
-    var chunks = ComputeNumChunks(length);
-    var numSlices = ForkJoinSlices();
-    if (chunks < numSlices)
-      break parallel;
-    var info = ComputeAllSliceBounds(chunks, numSlices);
-
-    // Scan slices individually (see comment on phase1()).
-    ForkJoin(phase1, ForkJoinMode(mode));
-
-    // Compute intermediates array (see comment on phase2()).
-    var intermediates = [];
-    var accumulator = buffer[finalElement(0)];
-    ARRAY_PUSH(intermediates, accumulator);
-    for (var i = 1; i < numSlices - 1; i++) {
-      accumulator = func(accumulator, buffer[finalElement(i)]);
-      ARRAY_PUSH(intermediates, accumulator);
-    }
-
-    // Reset the current position information for each slice, but
-    // convert from chunks to indices (see comment on phase2()).
-    for (var i = 0; i < numSlices; i++) {
-      info[SLICE_POS(i)] = info[SLICE_START(i)] << CHUNK_SHIFT;
-      info[SLICE_END(i)] = info[SLICE_END(i)] << CHUNK_SHIFT;
-    }
-    info[SLICE_END(numSlices - 1)] = std_Math_min(info[SLICE_END(numSlices - 1)], length);
-
-    // Complete each slice using intermediates array (see comment on phase2()).
-    ForkJoin(phase2, ForkJoinMode(mode));
-    return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  scan(self.get(0), 0, length);
-  return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-
-  function scan(accumulator, start, end) {
-    UnsafePutElements(buffer, start, accumulator);
-    for (var i = start + 1; i < end; i++) {
-      accumulator = func(accumulator, self.get(i));
-      UnsafePutElements(buffer, i, accumulator);
-    }
-    return accumulator;
-  }
-
-  /**
-   * In phase 1, we divide the source array into |numSlices| slices and
-   * compute scan on each slice sequentially as if it were the entire
-   * array. This function is responsible for computing one of those
-   * slices.
-   *
-   * So, if we have an array [A,B,C,D,E,F,G,H,I], |numSlices == 3|,
-   * and our function |func| is sum, then we would wind up computing a
-   * result array like:
-   *
-   *     [A, A+B, A+B+C, D, D+E, D+E+F, G, G+H, G+H+I]
-   *      ^~~~~~~~~~~~^  ^~~~~~~~~~~~^  ^~~~~~~~~~~~~^
-   *      Slice 0        Slice 1        Slice 2
-   *
-   * Read on in phase2 to see what we do next!
-   */
-  function phase1(sliceId, numSlices, warmup) {
-    var chunkStart = info[SLICE_START(sliceId)];
-    var chunkPos = info[SLICE_POS(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-
-    if (warmup && chunkEnd > chunkPos + 2)
-      chunkEnd = chunkPos + 2;
-
-    if (chunkPos == chunkStart) {
-      // For the first chunk, the accumulator begins as the value in
-      // the input at the start of the chunk.
-      var indexStart = chunkPos << CHUNK_SHIFT;
-      var indexEnd = std_Math_min(indexStart + CHUNK_SIZE, length);
-      scan(self.get(indexStart), indexStart, indexEnd);
-      UnsafePutElements(info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    while (chunkPos < chunkEnd) {
-      // For each subsequent chunk, the accumulator begins as the
-      // combination of the final value of prev chunk and the value in
-      // the input at the start of this chunk. Note that this loop is
-      // written as simple as possible, at the cost of an extra read
-      // from the buffer per iteration.
-      var indexStart = chunkPos << CHUNK_SHIFT;
-      var indexEnd = std_Math_min(indexStart + CHUNK_SIZE, length);
-      var accumulator = func(buffer[indexStart - 1], self.get(indexStart));
-      scan(accumulator, indexStart, indexEnd);
-      UnsafePutElements(info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    return chunkEnd == info[SLICE_END(sliceId)];
-  }
-
-  /**
-   * Computes the index of the final element computed by the slice |sliceId|.
-   */
-  function finalElement(sliceId) {
-    var chunkEnd = info[SLICE_END(sliceId)]; // last chunk written by |sliceId| is endChunk - 1
-    var indexStart = std_Math_min(chunkEnd << CHUNK_SHIFT, length);
-    return indexStart - 1;
-  }
-
-  /**
-   * After computing the phase1 results, we compute an
-   * |intermediates| array. |intermediates[i]| contains the result
-   * of reducing the final value from each preceding slice j<i with
-   * the final value of slice i. So, to continue our previous
-   * example, the intermediates array would contain:
-   *
-   *   [A+B+C, (A+B+C)+(D+E+F), ((A+B+C)+(D+E+F))+(G+H+I)]
-   *
-   * Here I have used parenthesization to make clear the order of
-   * evaluation in each case.
-   *
-   *   An aside: currently the intermediates array is computed
-   *   sequentially. In principle, we could compute it in parallel,
-   *   at the cost of doing duplicate work. This did not seem
-   *   particularly advantageous to me, particularly as the number
-   *   of slices is typically quite small (one per core), so I opted
-   *   to just compute it sequentially.
-   *
-   * Phase 2 combines the results of phase1 with the intermediates
-   * array to produce the final scan results. The idea is to
-   * reiterate over each element S[i] in the slice |sliceId|, which
-   * currently contains the result of reducing with S[0]...S[i]
-   * (where S0 is the first thing in the slice), and combine that
-   * with |intermediate[sliceId-1]|, which represents the result of
-   * reducing everything in the input array prior to the slice.
-   *
-   * To continue with our example, in phase 1 we computed slice 1 to
-   * be [D, D+E, D+E+F]. We will combine those results with
-   * |intermediates[1-1]|, which is |A+B+C|, so that the final
-   * result is [(A+B+C)+D, (A+B+C)+(D+E), (A+B+C)+(D+E+F)]. Again I
-   * am using parentheses to clarify how these results were reduced.
-   *
-   * SUBTLE: Because we are mutating |buffer| in place, we have to
-   * be very careful about bailouts!  We cannot checkpoint a chunk
-   * at a time as we do elsewhere because that assumes it is safe to
-   * replay the portion of a chunk which was already processed.
-   * Therefore, in this phase, we track the current position at an
-   * index granularity, although this requires two memory writes per
-   * index.
-   */
-  function phase2(sliceId, numSlices, warmup) {
-    if (sliceId == 0)
-      return true; // No work to do for the 0th slice.
-
-    var indexPos = info[SLICE_POS(sliceId)];
-    var indexEnd = info[SLICE_END(sliceId)];
-
-    if (warmup)
-      indexEnd = std_Math_min(indexEnd, indexPos + CHUNK_SIZE);
-
-    var intermediate = intermediates[sliceId - 1];
-    for (; indexPos < indexEnd; indexPos++) {
-      UnsafePutElements(buffer, indexPos, func(intermediate, buffer[indexPos]),
-                        info, SLICE_POS(sliceId), indexPos + 1);
-    }
-
-    return indexEnd == info[SLICE_END(sliceId)];
-  }
-
-  return undefined;
-}
-
-/**
- * |scatter()| redistributes the elements in the parallel array
- * into a new parallel array.
- *
- * - targets: The index targets[i] indicates where the ith element
- *   should appear in the result.
- *
- * - defaultValue: what value to use for indices in the output array that
- *   are never targeted.
- *
- * - conflictFunc: The conflict function. Used to resolve what
- *   happens if two indices i and j in the source array are targeted
- *   as the same destination (i.e., targets[i] == targets[j]), then
- *   the final result is determined by applying func(targets[i],
- *   targets[j]). If no conflict function is provided, it is an error
- *   if targets[i] == targets[j].
- *
- * - length: length of the output array (if not specified, uses the
- *   length of the input).
- *
- * - mode: internal debugging specification.
- */
-function ParallelArrayScatter(targets, defaultValue, conflictFunc, length, mode) {
-  // FIXME(bug 844887): Check |this instanceof ParallelArray|
-  // FIXME(bug 844887): Check targets is array-like
-  // FIXME(bug 844887): Check |IsCallable(conflictFunc)|
-
-  var self = this;
-
-  if (length === undefined)
-    length = self.shape[0];
-
-  // The Divide-Scatter-Vector strategy:
-  // 1. Slice |targets| array of indices ("scatter-vector") into N
-  //    parts.
-  // 2. Each of the N threads prepares an output buffer and a
-  //    write-log.
-  // 3. Each thread scatters according to one of the N parts into its
-  //    own output buffer, tracking written indices in the write-log
-  //    and resolving any resulting local collisions in parallel.
-  // 4. Merge the parts (either in parallel or sequentially), using
-  //    the write-logs as both the basis for finding merge-inputs and
-  //    for detecting collisions.
-
-  // The Divide-Output-Range strategy:
-  // 1. Slice the range of indices [0..|length|-1] into N parts.
-  //    Allocate a single shared output buffer of length |length|.
-  // 2. Each of the N threads scans (the entirety of) the |targets|
-  //    array, seeking occurrences of indices from that thread's part
-  //    of the range, and writing the results into the shared output
-  //    buffer.
-  // 3. Since each thread has its own portion of the output range,
-  //    every collision that occurs can be handled thread-locally.
-
-  // SO:
-  //
-  // If |targets.length| >> |length|, Divide-Scatter-Vector seems like
-  // a clear win over Divide-Output-Range, since for the latter, the
-  // expense of redundantly scanning the |targets| will diminish the
-  // gain from processing |length| in parallel, while for the former,
-  // the total expense of building separate output buffers and the
-  // merging post-process is small compared to the gain from
-  // processing |targets| in parallel.
-  //
-  // If |targets.length| << |length|, then Divide-Output-Range seems
-  // like it *could* win over Divide-Scatter-Vector. (But when is
-  // |targets.length| << |length| or even |targets.length| < |length|?
-  // Seems like an odd situation and an uncommon case at best.)
-  //
-  // The unanswered question is which strategy performs better when
-  // |targets.length| approximately equals |length|, especially for
-  // special cases like collision-free scatters and permutations.
-
-  var targetsLength = std_Math_min(targets.length, self.shape[0]);
-
-  if (targetsLength >>> 0 !== targetsLength)
-    ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, ".prototype.scatter length");
-
-  if (length >>> 0 !== length)
-    ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, ".prototype.scatter length");
-
-  parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-
-    if (forceDivideScatterVector())
-      return parDivideScatterVector();
-    else if (forceDivideOutputRange())
-      return parDivideOutputRange();
-    else if (conflictFunc === undefined && targetsLength < length)
-      return parDivideOutputRange();
-    return parDivideScatterVector();
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  return seq();
-
-  function forceDivideScatterVector() {
-    return mode && mode.strategy && mode.strategy == "divide-scatter-vector";
-  }
-
-  function forceDivideOutputRange() {
-    return mode && mode.strategy && mode.strategy == "divide-output-range";
-  }
-
-  function collide(elem1, elem2) {
-    if (conflictFunc === undefined)
-      ThrowError(JSMSG_PAR_ARRAY_SCATTER_CONFLICT);
-
-    return conflictFunc(elem1, elem2);
-  }
-
-
-  function parDivideOutputRange() {
-    var chunks = ComputeNumChunks(targetsLength);
-    var numSlices = ForkJoinSlices();
-    var checkpoints = NewDenseArray(numSlices);
-    for (var i = 0; i < numSlices; i++)
-      UnsafePutElements(checkpoints, i, 0);
-
-    var buffer = NewDenseArray(length);
-    var conflicts = NewDenseArray(length);
-
-    for (var i = 0; i < length; i++) {
-      UnsafePutElements(buffer, i, defaultValue);
-      UnsafePutElements(conflicts, i, false);
-    }
-
-    ForkJoin(fill, ForkJoinMode(mode));
-    return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-
-    function fill(sliceId, numSlices, warmup) {
-      var indexPos = checkpoints[sliceId];
-      var indexEnd = targetsLength;
-      if (warmup)
-        indexEnd = std_Math_min(indexEnd, indexPos + CHUNK_SIZE);
-
-      // Range in the output for which we are responsible:
-      var [outputStart, outputEnd] = ComputeSliceBounds(length, sliceId, numSlices);
-
-      for (; indexPos < indexEnd; indexPos++) {
-        var x = self.get(indexPos);
-        var t = checkTarget(indexPos, targets[indexPos]);
-        if (t < outputStart || t >= outputEnd)
-          continue;
-        if (conflicts[t])
-          x = collide(x, buffer[t]);
-        UnsafePutElements(buffer, t, x, conflicts, t, true, checkpoints, sliceId, indexPos + 1);
-      }
-
-      return indexEnd == targetsLength;
-    }
-
-    return undefined;
-  }
-
-  function parDivideScatterVector() {
-    // Subtle: because we will be mutating the localBuffers and
-    // conflict arrays in place, we can never replay an entry in the
-    // target array for fear of inducing a conflict where none existed
-    // before. Therefore, we must proceed not by chunks but rather by
-    // individual indices.
-    var numSlices = ForkJoinSlices();
-    var info = ComputeAllSliceBounds(targetsLength, numSlices);
-
-    // FIXME(bug 844890): Use typed arrays here.
-    var localBuffers = NewDenseArray(numSlices);
-    for (var i = 0; i < numSlices; i++)
-      UnsafePutElements(localBuffers, i, NewDenseArray(length));
-    var localConflicts = NewDenseArray(numSlices);
-    for (var i = 0; i < numSlices; i++) {
-      var conflicts_i = NewDenseArray(length);
-      for (var j = 0; j < length; j++)
-        UnsafePutElements(conflicts_i, j, false);
-      UnsafePutElements(localConflicts, i, conflicts_i);
-    }
-
-    // Initialize the 0th buffer, which will become the output. For
-    // the other buffers, we track which parts have been written to
-    // using the conflict buffer so they do not need to be
-    // initialized.
-    var outputBuffer = localBuffers[0];
-    for (var i = 0; i < length; i++)
-      UnsafePutElements(outputBuffer, i, defaultValue);
-
-    ForkJoin(fill, ForkJoinMode(mode));
-    mergeBuffers();
-    return NewParallelArray(ParallelArrayView, [length], outputBuffer, 0);
-
-    function fill(sliceId, numSlices, warmup) {
-      var indexPos = info[SLICE_POS(sliceId)];
-      var indexEnd = info[SLICE_END(sliceId)];
-      if (warmup)
-        indexEnd = std_Math_min(indexEnd, indexPos + CHUNK_SIZE);
-
-      var localbuffer = localBuffers[sliceId];
-      var conflicts = localConflicts[sliceId];
-      while (indexPos < indexEnd) {
-        var x = self.get(indexPos);
-        var t = checkTarget(indexPos, targets[indexPos]);
-        if (conflicts[t])
-          x = collide(x, localbuffer[t]);
-        UnsafePutElements(localbuffer, t, x, conflicts, t, true, 
-                          info, SLICE_POS(sliceId), ++indexPos);
-      }
-
-      return indexEnd == info[SLICE_END(sliceId)];
-    }
-
-    /**
-     * Merge buffers 1..NUMSLICES into buffer 0. In principle, we could
-     * parallelize the merge work as well. But for this first cut,
-     * just do the merge sequentially.
-     */
-    function mergeBuffers() {
-      var buffer = localBuffers[0];
-      var conflicts = localConflicts[0];
-      for (var i = 1; i < numSlices; i++) {
-        var otherbuffer = localBuffers[i];
-        var otherconflicts = localConflicts[i];
-        for (var j = 0; j < length; j++) {
-          if (otherconflicts[j]) {
-            if (conflicts[j]) {
-              buffer[j] = collide(otherbuffer[j], buffer[j]);
-            } else {
-              buffer[j] = otherbuffer[j];
-              conflicts[j] = true;
-            }
-          }
-        }
-      }
-    }
-
-    return undefined;
-  }
-
-  function seq() {
-    var buffer = NewDenseArray(length);
-    var conflicts = NewDenseArray(length);
-
-    for (var i = 0; i < length; i++) {
-      UnsafePutElements(buffer, i, defaultValue);
-      UnsafePutElements(conflicts, i, false);
-    }
-
-    for (var i = 0; i < targetsLength; i++) {
-      var x = self.get(i);
-      var t = checkTarget(i, targets[i]);
-      if (conflicts[t])
-        x = collide(x, buffer[t]);
-
-      UnsafePutElements(buffer, t, x, conflicts, t, true);
-    }
-
-    return NewParallelArray(ParallelArrayView, [length], buffer, 0);
-  }
-
-  function checkTarget(i, t) {
-    if (TO_INT32(t) !== t)
-      ThrowError(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, i);
-
-    if (t < 0 || t >= length)
-      ThrowError(JSMSG_PAR_ARRAY_SCATTER_BOUNDS);
-
-    // It's not enough to return t, as -0 | 0 === -0.
-    return TO_INT32(t);
-  }
-
-  return undefined;
-}
-
-/**
- * The familiar filter() operation applied across the outermost
- * dimension.
- */
-function ParallelArrayFilter(func, mode) {
-  // FIXME(bug 844887): Check |this instanceof ParallelArray|
-  // FIXME(bug 844887): Check |IsCallable(func)|
-
-  var self = this;
-  var length = self.shape[0];
-
-  parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
-    if (ShouldForceSequential())
-      break parallel;
-    if (!TRY_PARALLEL(mode))
-      break parallel;
-
-    var chunks = ComputeNumChunks(length);
-    var numSlices = ForkJoinSlices();
-    if (chunks < numSlices * 2)
-      break parallel;
-
-    var info = ComputeAllSliceBounds(chunks, numSlices);
-
-    // Step 1. Compute which items from each slice of the result
-    // buffer should be preserved. When we're done, we have an array
-    // |survivors| containing a bitset for each chunk, indicating
-    // which members of the chunk survived. We also keep an array
-    // |counts| containing the total number of items that are being
-    // preserved from within one slice.
-    //
-    // FIXME(bug 844890): Use typed arrays here.
-    var counts = NewDenseArray(numSlices);
-    for (var i = 0; i < numSlices; i++)
-      UnsafePutElements(counts, i, 0);
-    var survivors = NewDenseArray(chunks);
-    ForkJoin(findSurvivorsInSlice, ForkJoinMode(mode));
-
-    // Step 2. Compress the slices into one contiguous set.
-    var count = 0;
-    for (var i = 0; i < numSlices; i++)
-      count += counts[i];
-    var buffer = NewDenseArray(count);
-    if (count > 0)
-      ForkJoin(copySurvivorsInSlice, ForkJoinMode(mode));
-
-    return NewParallelArray(ParallelArrayView, [count], buffer, 0);
-  }
-
-  // Sequential fallback:
-  ASSERT_SEQUENTIAL_IS_OK(mode);
-  var buffer = [];
-  for (var i = 0; i < length; i++) {
-    var elem = self.get(i);
-    if (func(elem, i, self))
-      ARRAY_PUSH(buffer, elem);
-  }
-  return NewParallelArray(ParallelArrayView, [buffer.length], buffer, 0);
-
-  /**
-   * As described above, our goal is to determine which items we
-   * will preserve from a given slice. We do this one chunk at a
-   * time. When we finish a chunk, we record our current count and
-   * the next chunk sliceId, lest we should bail.
-   */
-  function findSurvivorsInSlice(sliceId, numSlices, warmup) {
-    var chunkPos = info[SLICE_POS(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-
-    if (warmup && chunkEnd > chunkPos)
-      chunkEnd = chunkPos + 1;
-
-    var count = counts[sliceId];
-    while (chunkPos < chunkEnd) {
-      var indexStart = chunkPos << CHUNK_SHIFT;
-      var indexEnd = std_Math_min(indexStart + CHUNK_SIZE, length);
-      var chunkBits = 0;
-
-      for (var bit = 0; indexStart + bit < indexEnd; bit++) {
-        var keep = !!func(self.get(indexStart + bit), indexStart + bit, self);
-        chunkBits |= keep << bit;
-        count += keep;
-      }
-
-      UnsafePutElements(survivors, chunkPos, chunkBits,
-                        counts, sliceId, count,
-                        info, SLICE_POS(sliceId), ++chunkPos);
-    }
-
-    return chunkEnd == info[SLICE_END(sliceId)];
-  }
-
-  function copySurvivorsInSlice(sliceId, numSlices, warmup) {
-    // Copies the survivors from this slice into the correct position.
-    // Note that this is an idempotent operation that does not invoke
-    // user code. Therefore, we don't expect bailouts and make an
-    // effort to proceed chunk by chunk or avoid duplicating work.
-
-    // Total up the items preserved by previous slices.
-    var count = 0;
-    if (sliceId > 0) { // FIXME(#819219)---work around a bug in Ion's range checks
-      for (var i = 0; i < sliceId; i++)
-        count += counts[i];
-    }
-
-    // Compute the final index we expect to write.
-    var total = count + counts[sliceId];
-    if (count == total)
-      return true;
-
-    // Iterate over the chunks assigned to us. Read the bitset for
-    // each chunk. Copy values where a 1 appears until we have
-    // written all the values that we expect to. We can just iterate
-    // from 0...CHUNK_SIZE without fear of a truncated final chunk
-    // because we are already checking for when count==total.
-    var chunkStart = info[SLICE_START(sliceId)];
-    var chunkEnd = info[SLICE_END(sliceId)];
-    for (var chunk = chunkStart; chunk < chunkEnd; chunk++) {
-      var chunkBits = survivors[chunk];
-      if (!chunkBits)
-        continue;
-
-      var indexStart = chunk << CHUNK_SHIFT;
-      for (var i = 0; i < CHUNK_SIZE; i++) {
-        if (chunkBits & (1 << i)) {
-          UnsafePutElements(buffer, count++, self.get(indexStart + i));
-          if (count == total)
-            break;
-        }
-      }
-    }
-
-    return true;
-  }
-
-  return undefined;
-}
-
-/**
- * Divides the outermost dimension into two dimensions. Does not copy
- * or affect the underlying data, just how it is divided amongst
- * dimensions. So if we had a vector with shape [N, ...] and you
- * partition with amount=4, you get a [N/4, 4, ...] vector. Note that
- * N must be evenly divisible by 4 in that case.
- */
-function ParallelArrayPartition(amount) {
-  if (amount >>> 0 !== amount)
-    ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-
-  var length = this.shape[0];
-  var partitions = (length / amount) | 0;
-
-  if (partitions * amount !== length)
-    ThrowError(JSMSG_PAR_ARRAY_BAD_PARTITION);
-
-  var shape = [partitions, amount];
-  for (var i = 1; i < this.shape.length; i++)
-    ARRAY_PUSH(shape, this.shape[i]);
-  return NewParallelArray(ParallelArrayView, shape, this.buffer, this.offset);
-}
-
-/**
- * Collapses two outermost dimensions into one. So if you had
- * a [X, Y, ...] vector, you get a [X*Y, ...] vector.
- */
-function ParallelArrayFlatten() {
-  if (this.shape.length < 2)
-    ThrowError(JSMSG_PAR_ARRAY_ALREADY_FLAT);
-
-  var shape = [this.shape[0] * this.shape[1]];
-  for (var i = 2; i < this.shape.length; i++)
-    ARRAY_PUSH(shape, this.shape[i]);
-  return NewParallelArray(ParallelArrayView, shape, this.buffer, this.offset);
-}
-
-//
-// Accessors and utilities.
-//
-
-/**
- * Specialized variant of get() for one-dimensional case
- */
-function ParallelArrayGet1(i) {
-  if (i === undefined)
-    return undefined;
-  return this.buffer[this.offset + i];
-}
-
-/**
- * Specialized variant of get() for two-dimensional case
- */
-function ParallelArrayGet2(x, y) {
-  var xDimension = this.shape[0];
-  var yDimension = this.shape[1];
-  if (x === undefined)
-    return undefined;
-  if (x >= xDimension)
-    return undefined;
-  if (y === undefined)
-    return NewParallelArray(ParallelArrayView, [yDimension], this.buffer, this.offset + x * yDimension);
-  if (y >= yDimension)
-    return undefined;
-  var offset = y + x * yDimension;
-  return this.buffer[this.offset + offset];
-}
-
-/**
- * Specialized variant of get() for three-dimensional case
- */
-function ParallelArrayGet3(x, y, z) {
-  var xDimension = this.shape[0];
-  var yDimension = this.shape[1];
-  var zDimension = this.shape[2];
-  if (x === undefined)
-    return undefined;
-  if (x >= xDimension)
-    return undefined;
-  if (y === undefined)
-    return NewParallelArray(ParallelArrayView, [yDimension, zDimension],
-                            this.buffer, this.offset + x * yDimension * zDimension);
-  if (y >= yDimension)
-    return undefined;
-  if (z === undefined)
-    return NewParallelArray(ParallelArrayView, [zDimension],
-                            this.buffer, this.offset + y * zDimension + x * yDimension * zDimension);
-  if (z >= zDimension)
-    return undefined;
-  var offset = z + y*zDimension + x * yDimension * zDimension;
-  return this.buffer[this.offset + offset];
-}
-
-/**
- * Generalized version of get() for N-dimensional case
- */
-function ParallelArrayGetN(...coords) {
-  if (coords.length == 0)
-    return undefined;
-
-  var products = ComputeProducts(this.shape);
-
-  // Compute the offset of the given coordinates. Each index is
-  // multipled by its corresponding entry in the |products|
-  // array, counting in reverse. So if |coords| is [a,b,c,d],
-  // then you get |a*BCD + b*CD + c*D + d|.
-  var offset = this.offset;
-  var sDimensionality = this.shape.length;
-  var cDimensionality = coords.length;
-  for (var i = 0; i < cDimensionality; i++) {
-    if (coords[i] >= this.shape[i])
-      return undefined;
-    offset += coords[i] * products[sDimensionality - i - 1];
-  }
-
-  if (cDimensionality < sDimensionality) {
-    var shape = callFunction(std_Array_slice, this.shape, cDimensionality);
-    return NewParallelArray(ParallelArrayView, shape, this.buffer, offset);
-  }
-  return this.buffer[offset];
-}
-
-/** The length property yields the outermost dimension */
-function ParallelArrayLength() {
-  return this.shape[0];
-}
-
-function ParallelArrayToString() {
-  var l = this.length;
-  if (l == 0)
-    return "";
-
-  var open, close;
-  if (this.shape.length > 1) {
-    open = "<";
-    close = ">";
-  } else {
-    open = close = "";
-  }
-
-  var result = "";
-  for (var i = 0; i < l - 1; i++) {
-    result += open + String(this.get(i)) + close;
-    result += ",";
-  }
-  result += open + String(this.get(l - 1)) + close;
-  return result;
-}
-
-/**
- * Internal debugging tool: checks that the given `mode` permits
- * sequential execution
- */
-function AssertSequentialIsOK(mode) {
-  if (mode && mode.mode && mode.mode !== "seq" && ParallelTestsShouldPass())
-    ThrowError(JSMSG_WRONG_VALUE, "parallel execution", "sequential was forced");
-}
-
-function ForkJoinMode(mode) {
-  // WARNING: this must match the enum ForkJoinMode in ForkJoin.cpp
-  if (!mode || !mode.mode) {
-    return 0;
-  } else if (mode.mode === "compile") {
-    return 1;
-  } else if (mode.mode === "par") {
-    return 2;
-  } else if (mode.mode === "recover") {
-    return 3;
-  } else if (mode.mode === "bailout") {
-    return 4;
-  }
-  ThrowError(JSMSG_PAR_ARRAY_BAD_ARG, "");
-  return undefined;
-}
-
-/*
- * Mark the main operations as clone-at-callsite for better precision.
- * This is slightly overkill, as all that we really need is to
- * specialize to the receiver and the elemental function, but in
- * practice this is likely not so different, since element functions
- * are often used in exactly one place.
- */
-SetScriptHints(ParallelArrayConstructEmpty, { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayConstructFromArray, { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayConstructFromFunction, { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayConstructFromFunctionMode, { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayConstructFromComprehension, { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayView,       { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayBuild,      { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayMap,        { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayReduce,     { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayScan,       { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayScatter,    { cloneAtCallsite: true });
-SetScriptHints(ParallelArrayFilter,     { cloneAtCallsite: true });
-
-/*
- * Mark the common getters as clone-at-callsite and inline. This is
- * overkill as we should only clone per receiver, but we have no
- * mechanism for that right now. Bug 804767 might permit another
- * alternative by specializing the inlined gets.
- */
-SetScriptHints(ParallelArrayGet1,       { cloneAtCallsite: true, inline: true });
-SetScriptHints(ParallelArrayGet2,       { cloneAtCallsite: true, inline: true });
-SetScriptHints(ParallelArrayGet3,       { cloneAtCallsite: true, inline: true });
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -156,8 +156,38 @@ function IsObject(v) {
     // Watch out for |typeof null === "object"| as the most obvious pitfall.
     // But also be careful of SpiderMonkey's objects that emulate undefined
     // (i.e. |document.all|), which have bogus |typeof| behavior.  Detect
     // these objects using strict equality, which said bogosity doesn't affect.
     return (typeof v === "object" && v !== null) ||
            typeof v === "function" ||
            (typeof v === "undefined" && v !== undefined);
 }
+
+#ifdef ENABLE_PARALLEL_JS
+
+/**
+ * Internal debugging tool: checks that the given `mode` permits
+ * sequential execution
+ */
+function AssertSequentialIsOK(mode) {
+  if (mode && mode.mode && mode.mode !== "seq" && ParallelTestsShouldPass())
+    ThrowError(JSMSG_WRONG_VALUE, "parallel execution", "sequential was forced");
+}
+
+function ForkJoinMode(mode) {
+  // WARNING: this must match the enum ForkJoinMode in ForkJoin.cpp
+  if (!mode || !mode.mode) {
+    return 0;
+  } else if (mode.mode === "compile") {
+    return 1;
+  } else if (mode.mode === "par") {
+    return 2;
+  } else if (mode.mode === "recover") {
+    return 3;
+  } else if (mode.mode === "bailout") {
+    return 4;
+  }
+  ThrowError(JSMSG_PAR_ARRAY_BAD_ARG);
+  return undefined;
+}
+
+#endif
--- a/js/src/jit-test/lib/parallelarray-helpers.js
+++ b/js/src/jit-test/lib/parallelarray-helpers.js
@@ -74,105 +74,55 @@ function assertAlmostEq(v1, v2) {
   var percent = diff / v1 * 100.0;
   print("v1 = " + v1);
   print("v2 = " + v2);
   print("% diff = " + percent);
   assertEq(percent < 1e-10, true); // off by an less than 1e-10%...good enough.
 }
 
 function assertStructuralEq(e1, e2) {
-    if (e1 instanceof ParallelArray && e2 instanceof ParallelArray) {
-      assertEqParallelArray(e1, e2);
-    } else if (e1 instanceof Array && e2 instanceof ParallelArray) {
-      assertEqParallelArrayArray(e2, e1);
-    } else if (e1 instanceof ParallelArray && e2 instanceof Array) {
-      assertEqParallelArrayArray(e1, e2);
-    } else if (e1 instanceof Array && e2 instanceof Array) {
+    if (e1 instanceof Array && e2 instanceof Array) {
       assertEqArray(e1, e2);
     } else if (e1 instanceof Object && e2 instanceof Object) {
       assertEq(e1.__proto__, e2.__proto__);
       for (prop in e1) {
         if (e1.hasOwnProperty(prop)) {
           assertEq(e2.hasOwnProperty(prop), true);
           assertStructuralEq(e1[prop], e2[prop]);
         }
       }
     } else {
       assertEq(e1, e2);
     }
 }
 
-function assertEqParallelArrayArray(a, b) {
-  assertEq(a.shape.length, 1);
-  assertEq(a.length, b.length);
-  for (var i = 0, l = a.length; i < l; i++) {
-    try {
-      assertStructuralEq(a.get(i), b[i]);
-    } catch (e) {
-      print("...in index ", i, " of ", l);
-      throw e;
-    }
-  }
-}
-
 function assertEqArray(a, b) {
     assertEq(a.length, b.length);
     for (var i = 0, l = a.length; i < l; i++) {
       try {
         assertStructuralEq(a[i], b[i]);
       } catch (e) {
         print("...in index ", i, " of ", l);
         throw e;
       }
     }
 }
 
-function assertEqParallelArray(a, b) {
-  assertEq(a instanceof ParallelArray, true);
-  assertEq(b instanceof ParallelArray, true);
-
-  var shape = a.shape;
-  assertEqArray(shape, b.shape);
-
-  function bump(indices) {
-    var d = indices.length - 1;
-    while (d >= 0) {
-      if (++indices[d] < shape[d])
-        break;
-      indices[d] = 0;
-      d--;
-    }
-    return d >= 0;
-  }
-
-  var iv = shape.map(function () { return 0; });
-  do {
-    try {
-      var e1 = a.get.apply(a, iv);
-      var e2 = b.get.apply(b, iv);
-      assertStructuralEq(e1, e2);
-    } catch (e) {
-      print("...in indices ", iv, " of ", shape);
-      throw e;
-    }
-  } while (bump(iv));
-}
-
 // Checks that whenever we execute this in parallel mode,
 // it bails out. `opFunction` should be a closure that takes a
 // mode parameter and performs some parallel array operation.
 // This closure will be invoked repeatedly.
 //
 // Here is an example of the expected usage:
 //
 //    assertParallelExecWillBail(function(m) {
-//        new ParallelArray(..., m)
+//        Array.buildPar(..., m)
 //    });
 //
-// where the `new ParallelArray(...)` is a stand-in
+// where the `Array.buildPar(...)` is a stand-in
 // for some parallel array operation.
 function assertParallelExecWillBail(opFunction) {
   opFunction({mode:"compile"}); // get the script compiled
   opFunction({mode:"bailout"}); // check that it bails when executed
 }
 
 // Checks that when we execute this in parallel mode,
 // some bailouts will occur but we will recover and
@@ -231,40 +181,16 @@ function assertArraySeqParResultsEq(arr,
   if (!cmpFunc)
     cmpFunc = assertStructuralEq;
   var expected = arr[op].apply(arr, [func]);
   assertParallelExecSucceeds(
     function (m) { return arr[op + "Par"].apply(arr, [func, m]); },
     function (r) { cmpFunc(expected, r); });
 }
 
-// Compares a ParallelArray function against its equivalent on the
-// `Array` prototype. `func` should be the closure to provide as
-// argument. For example:
-//
-//    compareAgainstArray([1, 2, 3], "map", i => i + 1)
-//
-// would check that `[1, 2, 3].map(i => i+1)` and `new
-// ParallelArray([1, 2, 3]).map(i => i+1)` yield the same result.
-//
-// Based on `assertParallelExecSucceeds`
-function compareAgainstArray(jsarray, opname, func, cmpFunction) {
-  if (!cmpFunction)
-    cmpFunction = assertStructuralEq;
-  var expected = jsarray[opname].apply(jsarray, [func]);
-  var parray = new ParallelArray(jsarray);
-  assertParallelExecSucceeds(
-    function(m) {
-      return parray[opname].apply(parray, [func, m]);
-    },
-    function(r) {
-      cmpFunction(expected, r);
-    });
-}
-
 // Similar to `compareAgainstArray`, but for the `scan` method which
 // does not appear on array.
 function testArrayScanPar(jsarray, func, cmpFunction) {
   if (!cmpFunction)
     cmpFunction = assertStructuralEq;
   var expected = seq_scan(jsarray, func);
 
   // Unfortunately, it sometimes happens that running 'par' twice in a
@@ -276,34 +202,16 @@ function testArrayScanPar(jsarray, func,
       var p = jsarray.scanPar(func, m);
       return p;
     },
     function(r) {
       cmpFunction(expected, r);
     });
 }
 
-// Similar to `compareAgainstArray`, but for the `scatter` method.
-// In this case, because scatter is so complex, we do not attempt
-// to compute the expected result and instead simply invoke
-// `cmpFunction(r)` with the result `r` of the scatter operation.
-function testScatter(opFunction, cmpFunction) {
-  var strategies = ["divide-scatter-version", "divide-output-range"];
-  for (var i in strategies) {
-    assertParallelExecSucceeds(
-      function(m) {
-        var m1 = {mode: m.mode,
-                  strategy: strategies[i]};
-        print(JSON.stringify(m1));
-        return opFunction(m1);
-      },
-      cmpFunction);
-  }
-}
-
 // Checks that `opFunction`, when run with each of the modes
 // in `modes`, returns the same value each time.
 function assertParallelModesCommute(modes, opFunction) {
   var expected = undefined;
   var acc = opFunction(modes[0]);
   assertParallelExecSucceeds(
     opFunction,
     function(r) {
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug755564.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Binary: cache/js-dbg-64-50177d59c0e1-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS) {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; });
-  assertEq(r.toString( 5 ? r : 0, gc()) ,[4,2,9,4,5].join(","));
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug783923.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// Binary: cache/js-dbg-64-35b8d6ef5d46-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS)
-  print(ParallelArray());
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug784011.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Binary: cache/js-dbg-64-c676b554c7bb-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS) {
-  var p2 = new ParallelArray([2,2], function(i,j) { return i+j; });
-  p2.get({ 0: 1, 1: 0, testGet: 2 })
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug786106.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Binary: cache/js-dbg-64-92b9b2840a79-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS) {
-  var p = new ParallelArray([2, 3,, 4, 5, 6]);
-  var r = p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; });
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug789107.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Binary: cache/js-dbg-64-5d63594c05a9-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS) {
-  ParallelArray().watch("shape", function() {})
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug791445.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Binary: cache/js-dbg-64-9fff2012b66c-linux
-// Flags:
-//
-
-if (getBuildConfiguration().parallelJS) {
-  ParallelArray(0, Proxy.createFunction(function(){}, function(){}))
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/baseline/bug846072.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// |jit-test| error: TypeError
-if (getBuildConfiguration().parallelJS) {
-  toString = undefined;
-  if (!(this in ParallelArray)) {}
-} else {
-  throw new TypeError();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/baseline/bug857579.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// |jit-test| ion-eager; error: TypeError
-
-function testMonitorIntrinsic() {
-  var N = 2;
-  // Make an NxN array of zeros.
-  var p = new ParallelArray([N,N], function () 0);
-  // |i| will go out of bounds!
-  for (var i = 0; i < N+1; i++) {
-    for (var j = 0; j < 2; j++) {
-      // When |i| goes out of bounds, we will bail from Ion to BC on an
-      // 'undefined' result inside parallel array's .get, tripping a type
-      // barrier on GETINTRINSIC.
-      p.get(i).get(j);
-    }
-  }
-}
-
-if (getBuildConfiguration().parallelJS) {
-  testMonitorIntrinsic();
-} else {
-  throw new TypeError();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug815652.js
+++ /dev/null
@@ -1,12 +0,0 @@
-
-gczeal(9, 2)
-function testScatterConflict() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,1,0,3,(0)], 9, function (a,b) { return a+b; });
-  function assertEqParallelArray(a, b)
-    assertEq(a instanceof ParallelArray, true);
-  assertEqParallelArray(r, new ParallelArray([4,2,(false),4,5]));
-}
-if (getBuildConfiguration().parallelJS) {
-  testScatterConflict();
-}
--- a/js/src/jit-test/tests/parallel/binary-arith-numbers.js
+++ b/js/src/jit-test/tests/parallel/binary-arith-numbers.js
@@ -13,19 +13,18 @@ function theTest() {
   }
 
   // run op once where it has to add doubles and strings,
   // just to pullute the typesets:
   var jsarray0 = range(0, 1024);
   jsarray0.map(op);
 
   // this version will never actually touch the strings:
-  var jsarray1 = range(0, 1024).map(i => i % 10);
-  compareAgainstArray(jsarray1, "map", op);
+  assertArraySeqParResultsEq(range(0, 1024), "map", function (i) { return i % 10; });
 
   // but if we try against the original we get bailouts:
   assertParallelExecWillBail(function (mode) {
-    new ParallelArray(jsarray0).map(op, mode);
+    jsarray0.mapPar(op, mode);
   });
 }
 
 if (getBuildConfiguration().parallelJS)
   theTest();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug783924.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function bug783924() {
-  // Shouldn't throw.
-  Function("ParallelArray([])")();
-}
-
-if (getBuildConfiguration().parallelJS)
-  bug783924();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug787282.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// |jit-test| error: TypeError
-
-var protoArr = Proxy.create({}, null);
-void (Array.prototype.__proto__ = protoArr);
-gczeal(2);
-function testCopyBigArray() {
-  var a = new Array(10000);
-  for (var cnt = 0; cnt < a.length; cnt+=2) {
-    var p = new ParallelArray(a);
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  testCopyBigArray();
-else
-  throw new TypeError();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug853555.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function test() {
-  Object.prototype[0] = /a/;
-  function getterFunction(v) { return "getter"; }
-  Object.defineProperty(Array.prototype, 1, { get: getterFunction });
-  gczeal(4);
-  var p = new ParallelArray([1,2,3,4,5]);
-  p.scatter([0,1,0,3,01], 9, function (a,b) { return a+b; });
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug853573.js
+++ /dev/null
@@ -1,17 +0,0 @@
-if (getBuildConfiguration().parallelJS) {
-  var p = Proxy.create({
-    has : function(id) {}
-  });
-  Object.prototype.__proto__ = p;
-    var pa0 = new ParallelArray(range(0, 256));
-    var pa1 = new ParallelArray(256, function (x) {
-      return pa0.map(function(y) {});
-    });
-}
-
-function range(n, m) {
-  var result = [];
-  for (var i = n; i < m; i++)
-    result.push(i);
-  return result;
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug854021.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// Don't crash.
-if (getBuildConfiguration().parallelJS)
-  ParallelArray(7, function ([y]) {})
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug854050.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function bug854050() {
-  // Shouldn't crash. Tests Ion's argumentsRectifier loading the right
-  // IonScript depending on execution mode.
-  for (z = 0; z < 1; z++)
-    function x(b, x) {}
-  ParallelArray(47, x);
-}
-
-if (getBuildConfiguration().parallelJS)
-  bug854050();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug854381.js
+++ /dev/null
@@ -1,20 +0,0 @@
-function bug854381() {
-  // Don't crash.
-  function toString(r) {
-    var l = 2;
-    var result = "";
-    for (var i = 0; i < l; i++)
-      result += r.get(i);
-    return result;
-  }
-
-  var p = new ParallelArray(['x', 'x']);
-  var r = new ParallelArray([toString(p), 42]);
-
-  gc();
-  print(toString(r));
-}
-
-if (getBuildConfiguration().parallelJS) {
-  bug854381();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug857846.js
+++ /dev/null
@@ -1,9 +0,0 @@
-function testNegativeZeroScatter() {
-  // Don't crash.
-  var p = new ParallelArray([0]);
-  var r = p.scatter([-0], 0, undefined, 1);
-}
-
-if (getBuildConfiguration().parallelJS) {
-  testNegativeZeroScatter();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug858077.js
+++ /dev/null
@@ -1,5 +0,0 @@
-if (getBuildConfiguration().parallelJS) {
-  var a = new ParallelArray([1,2,3,4]);
-  for (var i = 0; i < 9 && i > -1000; i-- )
-    a[i] += [0];
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug858582.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// |jit-test| error: TypeError
-// Don't crash.
-if (getBuildConfiguration().parallelJS) {
-gczeal(2);
-evaluate("\
-function assertAlmostEq(v1, v2) {\
-  print(\"v2 = \" + v2);\
-  print(\"% diff = \" + percent);\
-function assertStructuralEq(e1, e2) {}\
-function assertEqParallelArrayArray(a, b) {\
-    try {} catch (e) {\
-      print(\"...in index \", i, \" of \", l);\
-  }\
-}\
-    function assertEqArray(a, b) {\
-      try {} catch (e) {}\
-}\
-function assertEqParallelArray(a, b) {\
-  var shape = a.shape;\
-  function bump(indices) {\
-  var iv = shape.map(function () { return 0; });\
-      print(\"...in indices \", iv, \" of \", shape);\
-    }\
-  } while (bump(iv));\
-}\
-function assertParallelArrayModesEq(modes, acc, opFunction, cmpFunction) {\
-  modes.forEach(function (mode) {\
-    var result = opFunction({ mode: mode, expect: \"success\" });\
-    cmpFunction(acc, result);\
-  });\
-function assertParallelArrayModesCommute(modes, opFunction) {\
-    var acc = opFunction({ mode: modes[0], expect: \"success\" });\
-}\
-function comparePerformance(opts) {\
-        print(\"Option \" + opts[i].name + \" took \" + diff + \"ms\");\
-        print(\"Option \" + opts[i].name + \" relative to option \" +\
-              opts[0].name + \": \" + (rel|0) + \"%\");\
-    }\
-}\
-function compareAgainstArray(jsarray, opname, func, cmpFunction) {\
-  var expected = jsarray[opname].apply(jsarray, [func]);\
-  var parray = new ParallelArray(jsarray);\
-  assertParallelArrayModesEq([\"seq\", \"par\", \"par\"], expected, function(m) {\
-    var result = parray[opname].apply(parray, [func, m]);\
-  }, cmpFunction);\
-}\
-function testFilter(jsarray, func, cmpFunction) {}\
-", { noScriptRval : true });
-  compareAgainstArray([
-	"a", 
-	"b", 
-	('captures: 1,1; RegExp.leftContext: ""; RegExp.rightContext: "123456"'), 
-	"d", "e", 
-	"f", "g", "h",
-        "i", "j", "k", "l", 
-	"m", "n", "o", "p",
-        "q", "r", "s", "t", 
-	(.6  ), "v", "w", "x", "y", "z"
-	], "map", function(e) { 
-		return e != "u" 
-			&& 
-			(function b   (   )  { 
-			} )      
-			!= "x"; 
-	});
-} else {
-  throw new TypeError();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug890465.js
+++ /dev/null
@@ -1,6 +0,0 @@
-if (getBuildConfiguration().parallelJS) {
-  x = Uint8ClampedArray()
-  ParallelArray([320], function() {
-      return x[8]
-  })
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug894782.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// Don't crash
-
-if (getBuildConfiguration().parallelJS) {
-  print(ParallelArray())
-  String(Object.create(ParallelArray(8077, function() {})))
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug895782.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Don't crash
-
-if (getBuildConfiguration().parallelJS) {
-  Object.defineProperty(this, "y", {
-    get: function() {
-      return Object.create(x)
-    }
-  })
-  x = ParallelArray([1142], function() {})
-  x = x.partition(2)
-  y + y
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug908939.js
+++ /dev/null
@@ -1,13 +0,0 @@
-if (getBuildConfiguration().parallelJS) {
-  x = ParallelArray([9937], function() {
-      return /x/
-      })
-  Object.defineProperty(this, "y", {
-    get: function() {
-      return Object.create(x)
-    }
-  })
-  y + x
-  x = x.scatter([]);
-  + y
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/bug909599.js
+++ /dev/null
@@ -1,6 +0,0 @@
-if (getBuildConfiguration().parallelJS) {
-  x = Math.tan(5) + []
-  ParallelArray([764], (function() {})).filter(function(e) {
-      return e << x
-  })
-}
--- a/js/src/jit-test/tests/parallel/compare-values.js
+++ b/js/src/jit-test/tests/parallel/compare-values.js
@@ -10,35 +10,35 @@ function theTest() {
   var doubles = ints.map(v => v + 0.1);
   var bools = ints.map(v => (v % 2) == 0);
   var strings = ints.map(v => String(v));
 
   function looselyCompareToDoubles(e, i) {
     return doubles[i] == e;
   }
   print("doubles");
-  compareAgainstArray(doubles, "map", looselyCompareToDoubles)
+  assertArraySeqParResultsEq(doubles, "map", looselyCompareToDoubles);
   print("bools");
-  compareAgainstArray(bools, "map", looselyCompareToDoubles)
+  assertArraySeqParResultsEq(bools, "map", looselyCompareToDoubles);
   // ion bails out when converting a string to a double right now,
   // so par exec cannot proceed
   print("strings");
   assertParallelExecWillBail(function (mode) {
-    new ParallelArray(strings).map(looselyCompareToDoubles, mode)
+    strings.mapPar(looselyCompareToDoubles, mode)
   });
   print("ints");
-  compareAgainstArray(ints, "map", looselyCompareToDoubles)
+  assertArraySeqParResultsEq(ints, "map", looselyCompareToDoubles);
 
   function strictlyCompareToDoubles(e, i) {
     return doubles[i] === e;
   }
   print("doubles, strict");
-  compareAgainstArray(doubles, "map", strictlyCompareToDoubles)
+  assertArraySeqParResultsEq(doubles, "map", strictlyCompareToDoubles);
   print("bools, strict");
-  compareAgainstArray(bools, "map", strictlyCompareToDoubles)
+  assertArraySeqParResultsEq(bools, "map", strictlyCompareToDoubles);
   print("strings, strict");
-  compareAgainstArray(strings, "map", strictlyCompareToDoubles)
+  assertArraySeqParResultsEq(strings, "map", strictlyCompareToDoubles);
   print("ints, strict");
-  compareAgainstArray(ints, "map", strictlyCompareToDoubles)
+  assertArraySeqParResultsEq(ints, "map", strictlyCompareToDoubles);
 }
 
 if (getBuildConfiguration().parallelJS)
   theTest();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/comprehension-2.js
+++ /dev/null
@@ -1,13 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-load(libdir + "eqArrayHelper.js");
-
-function buildMultidim() {
-  // 2D comprehension
-  var p = new ParallelArray([2,2], function (i,j) { return i + j; });
-  var a = new ParallelArray([0,1,1,2]).partition(2);
-  assertEqArray(p.shape, [2,2]);
-  assertEqParallelArray(p, a);
-}
-
-if (getBuildConfiguration().parallelJS)
-  buildMultidim();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/comprehension-fn-args.js
+++ /dev/null
@@ -1,16 +0,0 @@
-
-function buildComprehension() {
-  // Test kernel function arguments
-  var shape = [];
-  for (var i = 0; i < 8; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function () {
-      assertEq(arguments.length, shape.length);
-      for (var j = 0; j < shape.length; j++)
-        assertEq(arguments[j] >= 0 && arguments[j] < shape[j], true);
-    });
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  buildComprehension();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/comprehension-scale.js
+++ /dev/null
@@ -1,22 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function buildComprehension() {
-  var H = 96;
-  var W = 96;
-  var d = 4;
-  // 3D 96x96x4 texture-like PA
-  var p = new ParallelArray([H,W,d], function (i,j,k) { return i + j + k; });
-  var a = [];
-  for (var i = 0; i < H; i++) {
-    for (var j = 0; j < W; j++) {
-      for (var k = 0; k < d; k++) {
-        a.push(i+j+k);
-      }
-    }
-  }
-  var p2 = new ParallelArray(a).partition(d).partition(W);
-  assertEqParallelArray(p, p2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  buildComprehension();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-1.js
+++ /dev/null
@@ -1,15 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function buildSimple() {
-  // Simple constructor
-  var a = [1,2,3,4,5];
-  var p = new ParallelArray(a);
-  assertEqParallelArrayArray(p, a);
-  var a2 = a.slice();
-  a[0] = 9;
-  // No sharing
-  assertEqParallelArrayArray(p, a2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  buildSimple();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-2.js
+++ /dev/null
@@ -1,15 +0,0 @@
-
-function buildWithHoles() {
-  // Test holes
-  var a = new Array(5);
-  for (var cnt = 0; cnt < a.length; cnt+=2) {
-      a[cnt] = cnt;
-  }
-  var b = [0,1,2,3,4];
-  var p = new ParallelArray(a);
-  assertEq(Object.keys(p).join(","), Object.keys(b).join(","));
-}
-
-// FIXME(bug 844882) self-hosted object not array-like, exposes internal properties
-// if (getBuildConfiguration().parallelJS)
-//   buildWithHoles();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-3.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function bracket(s) {
-  return "<" + s + ">";
-}
-
-function buildArrayLike() {
-  // Construct copying from array-like
-  var a = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 };
-  var p = new ParallelArray(a);
-  var e = Array.prototype.join.call(a, ",");
-  assertEq(p.toString(), e);
-}
-
-if (getBuildConfiguration().parallelJS)
-  buildArrayLike();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-4.js
+++ /dev/null
@@ -1,16 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function buildPA() {
-  // Construct copying from PA
-  var p1 = new ParallelArray([1,2,3,4]);
-  var p2 = new ParallelArray(p1);
-  assertEqParallelArray(p1, p2);
-
-  var p1d = new ParallelArray([2,2], function(i,j) { return i + j; });
-  var p2d = new ParallelArray(p1d);
-  assertEq(p1d.toString(), p2d.toString());
-}
-
-// FIXME(bug 844882) self-hosted object not array-like, exposes internal properties
-// if (getBuildConfiguration().parallelJS)
-//   buildPA();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-5.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// |jit-test| slow;
-// ^^ This test is slow when --no-ion is used, specifically,
-//    as part of TBPL.
-
-function testCopyBigArray() {
-  // Don't crash
-  var a = new Array(1000 * 1000);
-  var p = new ParallelArray(a);
-  // Holes!
-  var a = new Array(10000);
-  for (var cnt = 0; cnt < a.length; cnt+=2) {
-    a[cnt] = cnt;
-    var p = new ParallelArray(a);
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  testCopyBigArray();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/constructor-throws.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "asserts.js");
-
-function testThrows() {
-  assertThrowsInstanceOf(function () {
-    new ParallelArray({ length: 0xffffffff + 1 });
-  }, RangeError);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testThrows();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/element-1.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function testElement() {
-  // Test getting element from 1D
-  var a = [1,{},"a",false]
-  var p = new ParallelArray(a);
-  for (var i = 0; i < a.length; i++) {
-    assertEq(p.get(i), p.get(i));
-    assertEq(p.get(i), a[i]);
-  }
-  // Test out of bounds
-  assertEq(p.get(42), undefined);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testElement();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/element-2.js
+++ /dev/null
@@ -1,26 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testElement() {
-  // Test getting element from higher dimension
-  var p = new ParallelArray([2,2,2], function () { return 0; });
-  var p0 = new ParallelArray([2,2], function () { return 0; });
-  print("0");
-  assertEqParallelArray(p.get(0), p0);
-
-  // Should create new wrapper
-  print("1");
-  assertEq(p.get(0) !== p.get(0), true);
-
-  // Test out of bounds
-  print("2");
-  assertEq(p.get(42), undefined);
-
-  // Test getting element from 0-lengthed higher dimension
-  var pp = new ParallelArray([0,0], function() { return 0; });
-  assertEq(pp.get(2), undefined);
-  var pp2 = new ParallelArray([2,0], function() { return 0; });
-  assertEqParallelArray(pp2.get(0), new ParallelArray());
-}
-
-if (getBuildConfiguration().parallelJS)
-  testElement();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/element-3.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function testElement() {
-  var p = new ParallelArray([9]);
-  var desc = Object.getOwnPropertyDescriptor(p, "0");
-  assertEq(desc.enumerable, true);
-  assertEq(desc.configurable, false);
-  assertEq(desc.writable, false);
-  assertEq(desc.value, 9);
-}
-
-// FIXME(bug 844882) self-hosted object not array-like, exposes internal properties
-// if (getBuildConfiguration().parallelJS)
-//   testElement();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/flatten-1.js
+++ /dev/null
@@ -1,14 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testFlatten() {
-  var shape = [5];
-  for (var i = 0; i < 7; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function(i,j) { return i+j; });
-    var flatShape = ([shape[0] * shape[1]]).concat(shape.slice(2));
-    assertEqArray(p.flatten().shape, flatShape);
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  testFlatten();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/flatten-2.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testFlatten() {
-  var p = new ParallelArray([2,2], function(i,j) { return i+j; });
-  var p2 = new ParallelArray([0,1,1,2]);
-  assertEqParallelArray(p.flatten(), p2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testFlatten();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/flatten-3.js
+++ /dev/null
@@ -1,25 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testFlatten() {
-  var p0 = new ParallelArray([0,1]);
-  var p1 = new ParallelArray([2,3]);
-  var p = new ParallelArray([p0, p1]);
-  var p2 = new ParallelArray([0,1,2,3]);
-  assertEqParallelArray(p.flatten(), p2);
-
-  // Test flatten crossing packed boundary with non-shape uniform elements
-  var blah = new ParallelArray([2,2], function() { return 0; });
-  var pp = new ParallelArray([p0, p1, blah]);
-  var p2 = new ParallelArray([0,1,2,3,blah[0],blah[1]]);
-  assertEqParallelArray(pp.flatten(), p2);
-
-  var p0 = new ParallelArray([2,2], function() { return 1; });
-  var p1 = new ParallelArray([2,2], function() { return 2; });
-  var p = new ParallelArray([p0, p1]);
-  var p2 = new ParallelArray([p0[0],p0[1],p1[0],p1[1]]);
-  assertEqParallelArray(p.flatten(), p2);
-}
-
-// FIXME(bug 844991) logical shape not implemented
-// if (getBuildConfiguration().parallelJS)
-//   testFlatten();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/flatten-throws.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// |jit-test| error: Error;
-
-function testFlattenFlat() {
-  // Throw on flattening flat array
-  var p = new ParallelArray([1]);
-  var f = p.flatten();
-}
-
-if (getBuildConfiguration().parallelJS)
-  testFlattenFlat();
-else
-  throw new Error();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/get-1.js
+++ /dev/null
@@ -1,9 +0,0 @@
-function testGet() {
-  var a = [1,2,3,4,5];
-  var p = new ParallelArray(a);
-  for (var i = 0; i < a.length; i++)
-    assertEq(p.get(i), a[i]);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testGet();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/get-2.js
+++ /dev/null
@@ -1,14 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testGet() {
-  var p = new ParallelArray([2,2,2], function(i,j,k) { return i+j+k; });
-  assertEq(p.get(1,1,1), 1+1+1);
-  var p2 = new ParallelArray([2], function(i) { return 1+1+i; });
-  assertEqParallelArray(p.get(1,1), p2);
-  var p3 = new ParallelArray([2,2], function(i,j) { return 1+i+j; });
-  assertEqParallelArray(p.get(1), p3);
-  assertEq(p.get(5,5), undefined);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testGet();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/get-3.js
+++ /dev/null
@@ -1,9 +0,0 @@
-function testGetNoCraziness() {
-  // .get shouldn't do prototype walks
-  ParallelArray.prototype[42] = "foo";
-  var p = new ParallelArray([1,2,3,4]);
-  assertEq(p.get(42), undefined);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testGetNoCraziness();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/get-4.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function testGetBounds() {
-  var p = new ParallelArray([1,2,3,4]);
-  assertEq(p.get(42), undefined);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testGetBounds();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/get-6.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function testGet() {
-  // Test getting higher dimension inferred shape
-  var p0 = new ParallelArray([0,1]);
-  var p1 = new ParallelArray([2,3]);
-  var p = new ParallelArray([p0, p1]);
-  assertEq(p.get(0,0), 0);
-  assertEq(p.get(0,1), 1);
-  assertEq(p.get(1,0), 2);
-  assertEq(p.get(1,1), 3);
-}
-
-// FIXME(bug 844991) logical shape not implemented
-// if (getBuildConfiguration().parallelJS)
-//   testGet();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/holes-1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function testHoles() {
-  function f1(a) { return a * 42; }
-  function f2(a,b) { return a * b; }
-  // Don't crash when getting holes out.
-  //
-  // We do the multiplications below instead of asserting against undefined to
-  // force the VM to call a conversion function, which will crash if the value
-  // we got out is a JS_ARRAY_HOLE.
-  var p = new ParallelArray([,1]);
-  assertEq(p.get(0) * 42, NaN);
-  var m = p.map(f1);
-  assertEq(m.get(0), NaN);
-  assertEq(m.get(1), 42);
-  var r = p.reduce(f2);
-  assertEq(r, NaN);
-  var s = p.scan(f2);
-  assertEq(s.get(0) * 42, NaN);
-  assertEq(s.get(1), NaN);
-  var k = p.scatter([1,0]);
-  assertEq(k.get(0), 1);
-  assertEq(k[1] * 42, NaN);
-  var l = p.filter(function (e, i) { return i == 0; });
-  assertEq(l.get(0) * 42, NaN);
-  var p2 = p.partition(1);
-  assertEq(p2.get(0).get(0) * 42, NaN);
-  var g = p.get(0);
-  assertEq(g * 42, NaN);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testHoles();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/holes-2.js
+++ /dev/null
@@ -1,25 +0,0 @@
-function testElement() {
-  // No crazy prototype walking for indexed properties
-  ParallelArray.prototype[42] = "foo";
-  ParallelArray.prototype.bar = "bar";
-  var p = new ParallelArray([1,2,3,4]);
-  assertEq(p[42], undefined);
-  assertEq(42 in p, false);
-  assertEq("bar" in p, true);
-  // Don't inherit any indexed properties
-  for (var i in p)
-    assertEq(i !== 42, true);
-  for (var i in p) {
-    if (i % 1 !== 0)
-      assertEq(i, "bar");
-  }
-  ParallelArray.prototype[0] = "foo";
-  var p2 = new ParallelArray([,2]);
-  // ParallelArrays have no holes, so 0 must be 'in' p2
-  assertEq(0 in p2, true);
-  assertEq(p2[0], undefined);
-}
-
-// FIXME(bug 844882) self-hosted object not array-like, exposes internal properties
-// if (getBuildConfiguration().parallelJS)
-//   testElement();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/index-1.js
+++ /dev/null
@@ -1,9 +0,0 @@
-function test() {
-  var N = 22;
-  var p = new ParallelArray([N], function(i) { return i; });
-  for (var i = 0; i < N; i++)
-    assertEq(p.get(i), i);
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/index-2.js
+++ /dev/null
@@ -1,18 +0,0 @@
-function test() {
-  function mk(i, j) { return i*100+j; }
-
-  var N = 22;
-  var M = 44;
-
-  var p = new ParallelArray([N,M], mk);
-  for (var i = 0; i < N; i++) {
-    for (var j = 0; j < M; j++) {
-      print([i, j]);
-      assertEq(p.get(i, j), mk(i, j));
-      assertEq(p.get(i).get(j), mk(i, j));
-    }
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/index-3.js
+++ /dev/null
@@ -1,25 +0,0 @@
-function test() {
-  function mk(i, j, k) { return i*10000+j*100+k; }
-
-  var N = 10;
-  var M = 20;
-  var O = 30;
-
-  print("Computing");
-  var p = new ParallelArray([N,M,O], mk);
-
-  print("Checking");
-  for (var i = 0; i < N; i++) {
-    for (var j = 0; j < M; j++) {
-      for (var k = 0; k < O; k++) {
-        assertEq(p.get(i, j, k), mk(i, j, k));
-        assertEq(p.get(i, j).get(k), mk(i, j, k));
-        assertEq(p.get(i).get(j).get(k), mk(i, j, k));
-        assertEq(p.get(i).get(j, k), mk(i, j, k));
-      }
-    }
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/index-4.js
+++ /dev/null
@@ -1,27 +0,0 @@
-function test() {
-  function mk(i, j, k, l) { return i*1000000+j*10000+k*100+l; }
-
-  var N = 2;
-  var M = 4;
-  var O = 6;
-  var P = 8;
-
-  print("Computing");
-  var p = new ParallelArray([N,M,O,P], mk);
-
-  print("Checking");
-  for (var i = 0; i < N; i++) {
-    for (var j = 0; j < M; j++) {
-      for (var k = 0; k < O; k++) {
-        for (var l = 0; l < P; l++) {
-          assertEq(p.get(i, j, k, l), mk(i, j, k, l));
-          assertEq(p.get(i, j).get(k, l), mk(i, j, k, l));
-          assertEq(p.get(i).get(j).get(k).get(l), mk(i, j, k, l));
-        }
-      }
-    }
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/inline-new-bad-type.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// |jit-test| error: RangeError
-//
-// Run with --ion-eager.
-if (getBuildConfiguration().parallelJS) {
-  function TestCase(n, d, e, a) {};
-  function reportCompare() {
-    var testcase = new TestCase("x", 0);
-  }
-  reportCompare();
-  TestCase = ParallelArray;
-  gczeal(6);
-  try {
-    reportCompare();
-  } catch(exc1) {}
-  reportCompare();
-} else {
-  throw new RangeError();
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/length-1.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function testLength() {
-  var a = [1,2,3];
-  var p = new ParallelArray(a);
-  assertEq(p.length, a.length);
-  // Test holes
-  var a = [1,,3];
-  var p = new ParallelArray(a);
-  assertEq(p.length, a.length);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testLength();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/length-2.js
+++ /dev/null
@@ -1,13 +0,0 @@
-function testLength() {
-  // Test higher dimension shape up to 8D
-  var shape = [];
-  for (var i = 0; i < 8; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function () { return 0; });
-    // Length should be outermost dimension
-    assertEq(p.length, shape[0]);
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  testLength();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/length-3.js
+++ /dev/null
@@ -1,11 +0,0 @@
-function testLength() {
-  // Test length immutability.
-  var p = new ParallelArray([1,2,3,4]);
-  p.length = 0;
-  assertEq(p[0], 1);
-  assertEq(p.length, 4);
-}
-
-// FIXME(bug 844988) immutability not enforced
-// if (getBuildConfiguration().parallelJS)
-//   testLength();
--- a/js/src/jit-test/tests/parallel/mandelbrot.js
+++ b/js/src/jit-test/tests/parallel/mandelbrot.js
@@ -41,11 +41,13 @@ function computeSequentially() {
 var scale = 10000*300;
 var rows = 4;
 var cols = 4;
 
 // check that we get correct result
 if (getBuildConfiguration().parallelJS) {
   var expected = computeSequentially();
   assertParallelExecSucceeds(
-    function (m) new ParallelArray([rows, cols], computeSetByRow, m).flatten(),
+    function (m) Array.buildPar(rows * cols, function (xy) {
+      return computeSetByRow((xy/cols)|0,(xy%cols))
+    }, m),
     function (r) assertStructuralEq(expected, r));
 }
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/map-3.js
+++ /dev/null
@@ -1,12 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testMap() {
-  // Test mapping higher dimensional
-  var p = new ParallelArray([2,2], function (i,j) { return i+j; });
-  var m = p.map(function(x) { return x; });
-  var p2 = new ParallelArray(p.shape[0], function (i) { return p.get(i); });
-  assertEqParallelArray(m, p2);
-}
-
-if (getBuildConfiguration().parallelJS) testMap();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/overflow-throws.js
+++ /dev/null
@@ -1,12 +0,0 @@
-load(libdir + "asserts.js");
-
-function testOverflow() {
-  assertThrowsInstanceOf(function () {
-    new ParallelArray([0xffffffff + 1], function() { return 0; });
-  }, RangeError);
-  assertThrowsInstanceOf(function () {
-    new ParallelArray({ length: 0xffffffff + 1 });
-  }, RangeError);
-}
-
-if (getBuildConfiguration().parallelJS) testOverflow();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/partition-1.js
+++ /dev/null
@@ -1,15 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testPartition() {
-  var p = new ParallelArray([1,2,3,4,5,6,7,8]);
-  var pp = p.partition(2);
-  var ppp = pp.partition(2);
-  var ppShape = [p.shape[0] / 2, 2].concat(p.shape.slice(1));
-  var pppShape = [pp.shape[0] / 2, 2].concat(pp.shape.slice(1));
-  assertEqArray(pp.shape, ppShape);
-  assertEq(pp.toString(), "<1,2>,<3,4>,<5,6>,<7,8>");
-  assertEqArray(ppp.shape, pppShape);
-  assertEq(ppp.toString(), "<<1,2>,<3,4>>,<<5,6>,<7,8>>");
-}
-
-if (getBuildConfiguration().parallelJS) testPartition();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/partition-throws.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "asserts.js");
-
-function testPartitionDivisible() {
-  var p = new ParallelArray([1,2,3,4]);
-  var pp;
-  assertThrowsInstanceOf(function () { pp = p.partition(3); }, Error);
-  assertThrowsInstanceOf(function () { pp = p.partition(.34); }, Error);
-}
-
-if (getBuildConfiguration().parallelJS) testPartitionDivisible();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/reduce-higher-dim.js
+++ /dev/null
@@ -1,14 +0,0 @@
-
-function testReduce() {
-  // Test reduce on higher dimensional
-  // XXX Can we test this better?
-  var shape = [2];
-  for (var i = 0; i < 7; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function () { return i+1; });
-    var r = p.reduce(function (a, b) { return a; });
-    assertEq(r.shape.length, i + 1);
-  }
-}
-
-if (getBuildConfiguration().parallelJS) testReduce();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/reduce-throws.js
+++ /dev/null
@@ -1,17 +0,0 @@
-load(libdir + "asserts.js");
-
-function testReduceThrows() {
-  // Throw on empty
-  assertThrowsInstanceOf(function () {
-    var p = new ParallelArray([]);
-    p.reduce(function (v, p) { return v*p; });
-  }, Error);
-  // Throw on not function
-  assertThrowsInstanceOf(function () {
-    var p = new ParallelArray([1]);
-    p.reduce(42);
-  }, TypeError);
-}
-
-// FIXME(bug 844886) sanity check argument types
-// if (getBuildConfiguration().parallelJS) testReduceThrows();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scan-3.js
+++ /dev/null
@@ -1,17 +0,0 @@
-function testScan() {
-  // Test reduce on higher dimensional
-  // XXX Can we test this better?
-  function f(a, b) { return a; }
-  var shape = [2];
-  for (var i = 0; i < 7; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function () { return i+1; });
-    var r = p.reduce(f);
-    var s = p.scan(f)
-    for (var j = 0; j < s.length; j++)
-      assertEq(s.get(j).shape.length, i + 1);
-    assertEq(r.shape.length, i + 1);
-  }
-}
-
-if (getBuildConfiguration().parallelJS) testScan();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scan-throws.js
+++ /dev/null
@@ -1,18 +0,0 @@
-load(libdir + "asserts.js");
-
-function testScanThrows() {
-  // Throw on empty
-  assertThrowsInstanceOf(function () {
-    var p = new ParallelArray([]);
-    p.scan(function (v, p) { return v*p; });
-  }, Error);
-
-  // Throw on not function
-  assertThrowsInstanceOf(function () {
-    var p = new ParallelArray([1]);
-    p.scan(42);
-  }, TypeError);
-}
-
-// FIXME(bug 844886) sanity check argument types
-// if (getBuildConfiguration().parallelJS) testScanThrows();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-1.js
+++ /dev/null
@@ -1,8 +0,0 @@
-
-function testScatter() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; }, 10);
-  assertEq(r.length, 10);
-}
-
-if (getBuildConfiguration().parallelJS) testScatter();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-10.js
+++ /dev/null
@@ -1,21 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-// Test specific scatter implementation strategies, and compare them
-// each against the sequential version.
-//
-// This is just a simple reverse permutation of the input:
-// [A, B, ..., Y, Z] ==> [Z, Y, ..., B, A]
-
-function testDivideScatterVector() {
-  var len = 1024;
-  function add1(x) { return x+1; }
-  function id(x) { return x; }
-  var p = new ParallelArray(len, add1);
-  var revidx = build(len, id).reverse();
-  var p2 = new ParallelArray(revidx.map(add1));
-  testScatter(
-    m => p.scatter(revidx, 0, undefined, len, m),
-    r => assertEqParallelArray(r, p2));
-}
-
-if (getBuildConfiguration().parallelJS) testDivideScatterVector();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-11.js
+++ /dev/null
@@ -1,21 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-// Test specific scatter implementation strategies, and compare them
-// each against the sequential version.
-//
-// This is a reverse permutation that has a gap at the end.
-// [A, B, ..., Y, Z] ==> [Z, Y, ..., B, A, 0]
-
-function testDivideScatterVector() {
-  var len = 1024;
-  function add1(x) { return x+1; }
-  function id(x) { return x; }
-  var p = new ParallelArray(len, add1);
-  var revidx = build(len, id).reverse();
-  var p2 = new ParallelArray(revidx.map(add1).concat([0]));
-  testScatter(
-    m => p.scatter(revidx, 0, undefined, len+1, m),
-    r => assertEqParallelArray(r, p2));
-}
-
-if (getBuildConfiguration().parallelJS) testDivideScatterVector();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-12.js
+++ /dev/null
@@ -1,22 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-// Test specific scatter implementation strategies, and compare them
-// each against the sequential version.
-//
-// This is a reverse permutation that has a gap at the start and at the end.
-// [A, B, ..., Y, Z] ==> [0, Z, Y, ..., B, A, 0]
-
-function testDivideScatterVector() {
-  var len = 1024;
-  function add1(x) { return x+1; }
-  function id(x) { return x; }
-  var p = new ParallelArray(len, add1);
-  var revidx = build(len, add1).reverse();
-  var p2 = new ParallelArray([0].concat(revidx).concat([0]));
-
-  testScatter(
-    m => p.scatter(revidx, 0, undefined, len+2, m),
-    r => assertEqParallelArray(r, p2));
-}
-
-if (getBuildConfiguration().parallelJS) testDivideScatterVector();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-13.js
+++ /dev/null
@@ -1,24 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-// Test specific scatter implementation strategies, and compare them
-// each against the sequential version.
-//
-// This is a reverse permutation of the input with collisions at front and end
-// [A, B, C, D, ..., W, X, Y, Z] ==> [Z+Y, X, W, ..., D, C, B+A]
-
-function testDivideScatterVector() {
-  var len = 1024;
-  function add1(x) { return x+1; }
-  function add3(x) { return x+3; }
-  function id(x) { return x; }
-  var p = new ParallelArray(len, add1);
-  var idx = [0,0].concat(build(len-4, add1)).concat([len-3,len-3]);
-  var revidx = idx.reverse();
-  var p2 = [3].concat(build(len-4, add3)).concat([2*len-1]);
-  var expect = new ParallelArray(p2.reverse());
-  testScatter(
-    m => p.scatter(revidx, 0, function (x,y) { return x+y; }, len-2, m),
-    r => assertEqParallelArray(r, expect));
-}
-
-if (getBuildConfiguration().parallelJS) testDivideScatterVector();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-2.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatterIdentity() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,1,2,3,4]);
-  assertEqParallelArray(p, r);
-}
-
-if (getBuildConfiguration().parallelJS) testScatterIdentity();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-3.js
+++ /dev/null
@@ -1,12 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatter3() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([1,0,3,2,4]);
-  var p2 = new ParallelArray([2,1,4,3,5]);
-  assertStructuralEq(r, p2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testScatter3();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-4.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatterDefault() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,2,4], 9);
-  assertEqParallelArray(r, new ParallelArray([1,9,2,9,3]));
-}
-
-if (getBuildConfiguration().parallelJS) testScatterDefault();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-5.js
+++ /dev/null
@@ -1,9 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatterConflict() {
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; });
-  assertEqParallelArray(r, new ParallelArray([4,2,9,4,5]));
-}
-
-if (getBuildConfiguration().parallelJS) testScatterConflict();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-6.js
+++ /dev/null
@@ -1,13 +0,0 @@
-
-function testScatter() {
-  // Test scatter on higher dimension
-  var shape = [5];
-  for (var i = 0; i < 7; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function(k) { return k; });
-    var r = p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; }, 10);
-    assertEq(r.length, 10);
-  }
-}
-
-if (getBuildConfiguration().parallelJS) testScatter();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-7.js
+++ /dev/null
@@ -1,15 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatterIdentity() {
-  var shape = [5];
-  for (var i = 0; i < 7; i++) {
-    shape.push(2);
-    var p = new ParallelArray(shape, function(k) { return k; });
-    var r = p.scatter([0,1,2,3,4]);
-    var p2 = new ParallelArray([p.get(0), p.get(1), p.get(2), p.get(3), p.get(4)]);
-    assertEqParallelArray(p2, r);
-  }
-}
-
-if (getBuildConfiguration().parallelJS) testScatterIdentity();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-8.js
+++ /dev/null
@@ -1,16 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatter8() {
-  var shape = [5];
-  for (var i = 0; i < 7; i++) {
-    shape.push(2);
-    var p = new ParallelArray(shape, function(k) { return k; });
-    var r = p.scatter([1,0,3,2,4]);
-    var p2 = new ParallelArray([p.get(1), p.get(0), p.get(3), p.get(2), p.get(4)]);
-    assertEqParallelArray(p2, r);
-  }
-}
-
-if (getBuildConfiguration().parallelJS)
-  testScatter8();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-9.js
+++ /dev/null
@@ -1,12 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-function testScatter9() {
-  // Ignore the rest of the scatter vector if longer than source
-  var p = new ParallelArray([1,2,3,4,5]);
-  var r = p.scatter([1,0,3,2,4,1,2,3]);
-  var p2 = new ParallelArray([2,1,4,3,5]);
-  assertEqParallelArray(r, p2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  testScatter9();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-regression-1.js
+++ /dev/null
@@ -1,18 +0,0 @@
-load(libdir + "parallelarray-helpers.js");
-
-// The bug this is testing for:
-// the input p and the scatter vector have length 4
-// and the output p2 has length 3.  Even though p2
-// is shorter than the input lengths, we still need
-// to scan the entirety of the scatter vector, because
-// it may hold valid targets at distant indices.
-function test() {
-  var p = new ParallelArray([2,3,5,17]);
-  var r = p.scatter([0,0,2,1], 9, function (x,y) { return x * y; }, 3);
-  var p2 = new ParallelArray([6,17,5]);
-  assertEqParallelArray(r, p2);
-}
-
-if (getBuildConfiguration().parallelJS)
-  test();
-
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/scatter-throws.js
+++ /dev/null
@@ -1,31 +0,0 @@
-load(libdir + "asserts.js");
-
-function testScatterThrows() {
-  var p = new ParallelArray([1,2,3,4,5]);
-
-  // Throw on conflict with no resolution function
-  assertThrowsInstanceOf(function () {
-    var r = p.scatter([0,1,0,3,4]);
-  }, Error);
-  // Throw on out of bounds
-  assertThrowsInstanceOf(function () {
-    var r = p.scatter([0,1,0,3,11]);
-  }, Error);
-
-  assertThrowsInstanceOf(function () {
-    p.scatter([-1,1,0,3,4], 9, function (a,b) { return a+b; }, 10);
-  }, TypeError);
-  assertThrowsInstanceOf(function () {
-    p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; }, -1);
-  }, RangeError);
-  assertThrowsInstanceOf(function () {
-    p.scatter([0,1,0,3,4], 9, function (a,b) { return a+b; }, 0xffffffff + 1);
-  }, RangeError);
-  assertThrowsInstanceOf(function () {
-    p.scatter({ length: 0xffffffff + 1 }, 9, function (a,b) { return a+b; }, 10);
-  }, RangeError);
-
-}
-
-// FIXME(bug 844886) sanity check argument types
-// if (getBuildConfiguration().parallelJS) testScatterThrows();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/shape-1.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function testShape() {
-  var a = [1,2,3];
-  var p = new ParallelArray(a);
-  assertEq(p.shape.length, 1);
-  assertEq(p.shape[0], a.length);
-}
-
-if (getBuildConfiguration().parallelJS) testShape();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/shape-2.js
+++ /dev/null
@@ -1,15 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testShape() {
-  // Test higher dimension shape up to 8D
-  var shape = [];
-  for (var i = 0; i < 8; i++) {
-    shape.push(i+1);
-    var p = new ParallelArray(shape, function () { return 0; });
-    // Test shape identity and shape
-    assertEqArray(p.shape, shape);
-    assertEq(p.shape !== shape, true);
-  }
-}
-
-if (getBuildConfiguration().parallelJS) testShape();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/shape-3.js
+++ /dev/null
@@ -1,16 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testInfer() {
-  // Test that shapes are inferred
-  var p0 = new ParallelArray([0,1]);
-  var p1 = new ParallelArray([2,3]);
-  var p = new ParallelArray([p0, p1]);
-  assertEqArray(p.shape, [2,2]);
-  var p0 = new ParallelArray([0,1]);
-  var p1 = new ParallelArray([2]);
-  var p = new ParallelArray([p0, p1]);
-  assertEqArray(p.shape, [2]);
-}
-
-// FIXME(bug 844991) logical shape not implemented
-// if (parallelEnabled) testInfer();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/shape-4.js
+++ /dev/null
@@ -1,13 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testShape() {
-  // Test shape immutability.
-  var p = new ParallelArray([1,2,3,4]);
-  p.shape[0] = 0;
-  p.shape[1] = 42;
-  assertEq(p[0], 1);
-  assertEqArray(p.shape, [4]);
-}
-
-// FIXME(bug 844988) immutability not enforced
-// if (getBuildConfiguration().parallelJS) testShape();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/shape-5.js
+++ /dev/null
@@ -1,13 +0,0 @@
-load(libdir + "eqArrayHelper.js");
-
-function testShape() {
-  // Test shape immutability.
-  var p = new ParallelArray([1,2,3,4]);
-  p.shape[0] = 0;
-  p.shape[1] = 42;
-  assertEq(p[0], 1);
-  assertEqArray(p.shape, [4]);
-}
-
-// FIXME(bug 844988) immutability not enforced
-// if (getBuildConfiguration().parallelJS) testShape();
--- a/js/src/jit-test/tests/parallel/stack-overflow.js
+++ b/js/src/jit-test/tests/parallel/stack-overflow.js
@@ -4,15 +4,15 @@ function kernel(n) {
   // in parallel mode just recurse infinitely.
   if (n > 10 && inParallelSection())
     return kernel(n);
 
   return n+1;
 }
 
 function testMap() {
-  var p = new ParallelArray(range(0, 2048));
+  var p = range(0, 2048);
   assertParallelExecWillBail(
-    m => p.map(kernel, m));
+    m => p.mapPar(kernel, m));
 }
 
 if (getBuildConfiguration().parallelJS)
   testMap();
deleted file mode 100644
--- a/js/src/jit-test/tests/parallel/toString-1.js
+++ /dev/null
@@ -1,6 +0,0 @@
-function testToString() {
-  var p = new ParallelArray();
-  assertEq(p.toString(), "");
-}
-
-if (getBuildConfiguration().parallelJS) testToString();
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -7863,29 +7863,16 @@ GetTemplateObjectForNative(JSContext *cx
     if (native == js_String) {
         RootedString emptyString(cx, cx->runtime()->emptyString);
         res.set(StringObject::create(cx, emptyString, TenuredObject));
         if (!res)
             return false;
         return true;
     }
 
-    if (native == intrinsic_NewParallelArray || native == ParallelArrayObject::construct) {
-        res.set(ParallelArrayObject::newInstance(cx, TenuredObject));
-        if (!res)
-            return false;
-
-        types::TypeObject *type =
-            types::TypeScript::InitObject(cx, script, pc, JSProto_ParallelArray);
-        if (!type)
-            return false;
-        res->setType(type);
-        return true;
-    }
-
     return true;
 }
 
 static bool
 TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsbytecode *pc,
                   JSOp op, uint32_t argc, Value *vp, bool constructing, bool useNewType)
 {
     if (useNewType || op == JSOP_EVAL)
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -2932,60 +2932,16 @@ CodeGenerator::generateBody()
         perfSpewer->endBasicBlock(masm);
 #endif
     }
 
     JS_ASSERT(pushedArgumentSlots_.empty());
     return true;
 }
 
-// Out-of-line object allocation for LNewParallelArray.
-class OutOfLineNewParallelArray : public OutOfLineCodeBase<CodeGenerator>
-{
-    LNewParallelArray *lir_;
-
-  public:
-    OutOfLineNewParallelArray(LNewParallelArray *lir)
-      : lir_(lir)
-    { }
-
-    bool accept(CodeGenerator *codegen) {
-        return codegen->visitOutOfLineNewParallelArray(this);
-    }
-
-    LNewParallelArray *lir() const {
-        return lir_;
-    }
-};
-
-typedef JSObject *(*NewInitParallelArrayFn)(JSContext *, HandleObject);
-static const VMFunction NewInitParallelArrayInfo =
-    FunctionInfo<NewInitParallelArrayFn>(NewInitParallelArray);
-
-bool
-CodeGenerator::visitNewParallelArrayVMCall(LNewParallelArray *lir)
-{
-    JS_ASSERT(gen->info().executionMode() == SequentialExecution);
-
-    Register objReg = ToRegister(lir->output());
-
-    JS_ASSERT(!lir->isCall());
-    saveLive(lir);
-
-    pushArg(ImmGCPtr(lir->mir()->templateObject()));
-    if (!callVM(NewInitParallelArrayInfo, lir))
-        return false;
-
-    if (ReturnReg != objReg)
-        masm.movePtr(ReturnReg, objReg);
-
-    restoreLive(lir);
-    return true;
-}
-
 // Out-of-line object allocation for LNewArray.
 class OutOfLineNewArray : public OutOfLineCodeBase<CodeGenerator>
 {
     LNewArray *lir_;
 
   public:
     OutOfLineNewArray(LNewArray *lir)
       : lir_(lir)
@@ -3100,42 +3056,16 @@ bool CodeGenerator::visitHypot(LHypot *l
     masm.passABIArg(y);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MacroAssembler::DOUBLE);
 
     JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg);
     return true;
 }
 
 bool
-CodeGenerator::visitNewParallelArray(LNewParallelArray *lir)
-{
-    Register objReg = ToRegister(lir->output());
-    JSObject *templateObject = lir->mir()->templateObject();
-
-    OutOfLineNewParallelArray *ool = new(alloc()) OutOfLineNewParallelArray(lir);
-    if (!addOutOfLineCode(ool))
-        return false;
-
-    masm.newGCThing(objReg, templateObject, ool->entry(), gc::DefaultHeap);
-    masm.initGCThing(objReg, templateObject);
-
-    masm.bind(ool->rejoin());
-    return true;
-}
-
-bool
-CodeGenerator::visitOutOfLineNewParallelArray(OutOfLineNewParallelArray *ool)
-{
-    if (!visitNewParallelArrayVMCall(ool->lir()))
-        return false;
-    masm.jump(ool->rejoin());
-    return true;
-}
-
-bool
 CodeGenerator::visitNewArray(LNewArray *lir)
 {
     JS_ASSERT(gen->info().executionMode() == SequentialExecution);
     Register objReg = ToRegister(lir->output());
     JSObject *templateObject = lir->mir()->templateObject();
     DebugOnly<uint32_t> count = lir->mir()->count();
 
     JS_ASSERT(count < JSObject::NELEMENTS_LIMIT);
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -20,17 +20,16 @@
 # include "jit/arm/CodeGenerator-arm.h"
 #else
 #error "CPU Not Supported"
 #endif
 
 namespace js {
 namespace jit {
 
-class OutOfLineNewParallelArray;
 class OutOfLineTestObject;
 class OutOfLineNewArray;
 class OutOfLineNewObject;
 class CheckOverRecursedFailure;
 class CheckOverRecursedFailurePar;
 class OutOfLineCheckInterruptPar;
 class OutOfLineInterruptCheckImplicit;
 class OutOfLineUnboxFloatingPoint;
@@ -122,19 +121,16 @@ class CodeGenerator : public CodeGenerat
     bool visitGetDynamicName(LGetDynamicName *lir);
     bool visitFilterArgumentsOrEvalS(LFilterArgumentsOrEvalS *lir);
     bool visitFilterArgumentsOrEvalV(LFilterArgumentsOrEvalV *lir);
     bool visitCallDirectEvalS(LCallDirectEvalS *lir);
     bool visitCallDirectEvalV(LCallDirectEvalV *lir);
     bool visitDoubleToInt32(LDoubleToInt32 *lir);
     bool visitFloat32ToInt32(LFloat32ToInt32 *lir);
     bool visitNewSlots(LNewSlots *lir);
-    bool visitNewParallelArrayVMCall(LNewParallelArray *lir);
-    bool visitNewParallelArray(LNewParallelArray *lir);
-    bool visitOutOfLineNewParallelArray(OutOfLineNewParallelArray *ool);
     bool visitNewArrayCallVM(LNewArray *lir);
     bool visitNewArray(LNewArray *lir);
     bool visitOutOfLineNewArray(OutOfLineNewArray *ool);
     bool visitNewObjectVMCall(LNewObject *lir);
     bool visitNewObject(LNewObject *lir);
     bool visitOutOfLineNewObject(OutOfLineNewObject *ool);
     bool visitNewDeclEnvObject(LNewDeclEnvObject *lir);
     bool visitNewCallObject(LNewCallObject *lir);
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -640,26 +640,16 @@ class IonBuilder : public MIRGenerator
     InliningStatus inlineNewDenseArray(CallInfo &callInfo);
     InliningStatus inlineNewDenseArrayForSequentialExecution(CallInfo &callInfo);
     InliningStatus inlineNewDenseArrayForParallelExecution(CallInfo &callInfo);
 
     // Slot intrinsics.
     InliningStatus inlineUnsafeSetReservedSlot(CallInfo &callInfo);
     InliningStatus inlineUnsafeGetReservedSlot(CallInfo &callInfo);
 
-    // Parallel intrinsics.
-    InliningStatus inlineNewParallelArray(CallInfo &callInfo);
-    InliningStatus inlineParallelArray(CallInfo &callInfo);
-    InliningStatus inlineParallelArrayTail(CallInfo &callInfo,
-                                           JSFunction *target,
-                                           MDefinition *ctor,
-                                           types::TemporaryTypeSet *ctorTypes,
-                                           uint32_t discards,
-                                           Native native);
-
     // Utility intrinsics.
     InliningStatus inlineIsCallable(CallInfo &callInfo);
     InliningStatus inlineHaveSameClass(CallInfo &callInfo);
     InliningStatus inlineToObject(CallInfo &callInfo);
     InliningStatus inlineDump(CallInfo &callInfo);
 
     // Testing functions.
     InliningStatus inlineForceSequentialOrInParallelSection(CallInfo &callInfo);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -297,26 +297,16 @@ class LNewSlots : public LCallInstructio
         return getTemp(2);
     }
 
     MNewSlots *mir() const {
         return mir_->toNewSlots();
     }
 };
 
-class LNewParallelArray : public LInstructionHelper<1, 0, 0>
-{
-  public:
-    LIR_HEADER(NewParallelArray);
-
-    MNewParallelArray *mir() const {
-        return mir_->toNewParallelArray();
-    }
-};
-
 class LNewArray : public LInstructionHelper<1, 0, 0>
 {
   public:
     LIR_HEADER(NewArray)
 
     const char *extraName() const {
         return mir()->shouldUseVM() ? "VMCall" : nullptr;
     }
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -17,17 +17,16 @@
     _(Double)                       \
     _(Float32)                      \
     _(Value)                        \
     _(Parameter)                    \
     _(Callee)                       \
     _(TableSwitch)                  \
     _(TableSwitchV)                 \
     _(Goto)                         \
-    _(NewParallelArray)             \
     _(NewArray)                     \
     _(NewObject)                    \
     _(NewSlots)                     \
     _(NewDeclEnvObject)             \
     _(NewCallObject)                \
     _(NewStringObject)              \
     _(NewPar)                       \
     _(NewDenseArrayPar)             \
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -156,23 +156,16 @@ LIRGenerator::visitNewSlots(MNewSlots *i
     LNewSlots *lir = new(alloc()) LNewSlots(tempFixed(CallTempReg0), tempFixed(CallTempReg1),
                                             tempFixed(CallTempReg2));
     if (!assignSnapshot(lir))
         return false;
     return defineReturn(lir, ins);
 }
 
 bool
-LIRGenerator::visitNewParallelArray(MNewParallelArray *ins)
-{
-    LNewParallelArray *lir = new(alloc()) LNewParallelArray();
-    return define(lir, ins) && assignSafepoint(lir, ins);
-}
-
-bool
 LIRGenerator::visitNewArray(MNewArray *ins)
 {
     LNewArray *lir = new(alloc()) LNewArray();
     return define(lir, ins) && assignSafepoint(lir, ins);
 }
 
 bool
 LIRGenerator::visitNewObject(MNewObject *ins)
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -76,17 +76,16 @@ class LIRGenerator : public LIRGenerator
 
     // Visitor hooks are explicit, to give CPU-specific versions a chance to
     // intercept without a bunch of explicit gunk in the .cpp.
     bool visitParameter(MParameter *param);
     bool visitCallee(MCallee *callee);
     bool visitGoto(MGoto *ins);
     bool visitTableSwitch(MTableSwitch *tableswitch);
     bool visitNewSlots(MNewSlots *ins);
-    bool visitNewParallelArray(MNewParallelArray *ins);
     bool visitNewArray(MNewArray *ins);
     bool visitNewObject(MNewObject *ins);
     bool visitNewDeclEnvObject(MNewDeclEnvObject *ins);
     bool visitNewCallObject(MNewCallObject *ins);
     bool visitNewStringObject(MNewStringObject *ins);
     bool visitNewDerivedTypedObject(MNewDerivedTypedObject *ins);
     bool visitNewPar(MNewPar *ins);
     bool visitNewCallObjectPar(MNewCallObjectPar *ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsmath.h"
 
-#include "builtin/ParallelArray.h"
 #include "builtin/TestingFunctions.h"
 #include "jit/BaselineInspector.h"
 #include "jit/IonBuilder.h"
 #include "jit/Lowering.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 #include "jsscriptinlines.h"
@@ -132,20 +131,16 @@ IonBuilder::inlineNativeCall(CallInfo &c
     if (native == intrinsic_UnsafeSetReservedSlot)
         return inlineUnsafeSetReservedSlot(callInfo);
     if (native == intrinsic_UnsafeGetReservedSlot)
         return inlineUnsafeGetReservedSlot(callInfo);
 
     // Parallel intrinsics.
     if (native == intrinsic_ShouldForceSequential)
         return inlineForceSequentialOrInParallelSection(callInfo);
-    if (native == intrinsic_NewParallelArray)
-        return inlineNewParallelArray(callInfo);
-    if (native == ParallelArrayObject::construct)
-        return inlineParallelArray(callInfo);
 
     // Utility intrinsics.
     if (native == intrinsic_IsCallable)
         return inlineIsCallable(callInfo);
     if (native == intrinsic_HaveSameClass)
         return inlineHaveSameClass(callInfo);
     if (native == intrinsic_ToObject)
         return inlineToObject(callInfo);
@@ -1240,163 +1235,16 @@ IonBuilder::inlineForceSequentialOrInPar
         return InliningStatus_Inlined;
       }
     }
 
     MOZ_ASSUME_UNREACHABLE("Invalid execution mode");
 }
 
 IonBuilder::InliningStatus
-IonBuilder::inlineNewParallelArray(CallInfo &callInfo)
-{
-    // Rewrites a call like
-    //
-    //    NewParallelArray(ParallelArrayView, arg0, ..., argN)
-    //
-    // to
-    //
-    //    x = MNewParallelArray()
-    //    ParallelArrayView(x, arg0, ..., argN)
-
-    uint32_t argc = callInfo.argc();
-    if (argc < 1 || callInfo.constructing())
-        return InliningStatus_NotInlined;
-
-    types::TemporaryTypeSet *ctorTypes = callInfo.getArg(0)->resultTypeSet();
-    JSObject *targetObj = ctorTypes ? ctorTypes->getSingleton() : nullptr;
-    JSFunction *target = nullptr;
-    if (targetObj && targetObj->is<JSFunction>())
-        target = &targetObj->as<JSFunction>();
-    if (target && target->isInterpreted() && target->nonLazyScript()->shouldCloneAtCallsite()) {
-        if (JSFunction *clone = ExistingCloneFunctionAtCallsite(compartment->callsiteClones(), target, script(), pc))
-            target = clone;
-    }
-    MDefinition *ctor = makeCallsiteClone(
-        target,
-        callInfo.getArg(0)->toPassArg()->getArgument());
-
-    // Discard the function.
-    return inlineParallelArrayTail(callInfo, target, ctor,
-                                   target ? nullptr : ctorTypes, 1,
-                                   intrinsic_NewParallelArray);
-}
-
-IonBuilder::InliningStatus
-IonBuilder::inlineParallelArray(CallInfo &callInfo)
-{
-    if (!callInfo.constructing())
-        return InliningStatus_NotInlined;
-
-    uint32_t argc = callInfo.argc();
-    JSFunction *target = ParallelArrayObject::maybeGetConstructor(&script()->global(), argc);
-    if (!target)
-        return InliningStatus_NotInlined;
-
-    JS_ASSERT(target->nonLazyScript()->shouldCloneAtCallsite());
-    if (JSFunction *clone = ExistingCloneFunctionAtCallsite(compartment->callsiteClones(), target, script(), pc))
-        target = clone;
-
-    MConstant *ctor = MConstant::New(alloc(), ObjectValue(*target));
-    current->add(ctor);
-
-    return inlineParallelArrayTail(callInfo, target, ctor, nullptr, 0,
-                                   ParallelArrayObject::construct);
-}
-
-IonBuilder::InliningStatus
-IonBuilder::inlineParallelArrayTail(CallInfo &callInfo,
-                                    JSFunction *target,
-                                    MDefinition *ctor,
-                                    types::TemporaryTypeSet *ctorTypes,
-                                    uint32_t discards,
-                                    Native native)
-{
-    // Rewrites either NewParallelArray(...) or new ParallelArray(...) from a
-    // call to a native ctor into a call to the relevant function in the
-    // self-hosted code.
-
-    uint32_t argc = callInfo.argc() - discards;
-
-    // Create the new parallel array object.  Parallel arrays have specially
-    // constructed type objects, so we can only perform the inlining if we
-    // already have one of these type objects.
-    types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
-    if (returnTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT)
-        return InliningStatus_NotInlined;
-    if (returnTypes->unknownObject() || returnTypes->getObjectCount() != 1)
-        return InliningStatus_NotInlined;
-    types::TypeObject *typeObject = returnTypes->getTypeObject(0);
-    if (!typeObject || typeObject->clasp != &ParallelArrayObject::class_)
-        return InliningStatus_NotInlined;
-
-    JSObject *templateObject = inspector->getTemplateObjectForNative(pc, native);
-    if (!templateObject || templateObject->type() != typeObject)
-        return InliningStatus_NotInlined;
-
-    // Create the call and add in the non-this arguments.
-    uint32_t targetArgs = argc;
-    if (target && !target->isNative())
-        targetArgs = Max<uint32_t>(target->nargs, argc);
-
-    MCall *call = MCall::New(alloc(), target, targetArgs + 1, argc, false);
-    if (!call)
-        return InliningStatus_Error;
-
-    callInfo.unwrapArgs();
-
-    // Explicitly pad any missing arguments with |undefined|.
-    // This permits skipping the argumentsRectifier.
-    for (uint32_t i = targetArgs; i > argc; i--) {
-        JS_ASSERT_IF(target, !target->isNative());
-        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
-        current->add(undef);
-        MPassArg *pass = MPassArg::New(alloc(), undef);
-        current->add(pass);
-        call->addArg(i, pass);
-    }
-
-    MPassArg *oldThis = MPassArg::New(alloc(), callInfo.thisArg());
-    current->add(oldThis);
-
-    // Add explicit arguments.
-    // Skip addArg(0) because it is reserved for this
-    for (uint32_t i = 0; i < argc; i++) {
-        MDefinition *arg = callInfo.getArg(i + discards);
-        MPassArg *passArg = MPassArg::New(alloc(), arg);
-        current->add(passArg);
-        call->addArg(i + 1, passArg);
-    }
-
-    // Place an MPrepareCall before the first passed argument, before we
-    // potentially perform rearrangement.
-    MPrepareCall *start = MPrepareCall::New(alloc());
-    oldThis->block()->insertBefore(oldThis, start);
-    call->initPrepareCall(start);
-
-    // Create the MIR to allocate the new parallel array.  Take the type
-    // object is taken from the prediction set.
-    MNewParallelArray *newObject = MNewParallelArray::New(alloc(), templateObject);
-    current->add(newObject);
-    MPassArg *newThis = MPassArg::New(alloc(), newObject);
-    current->add(newThis);
-    call->addArg(0, newThis);
-
-    // Set the new callee.
-    call->initFunction(ctor);
-
-    current->add(call);
-    current->push(newObject);
-
-    if (!resumeAfter(call))
-        return InliningStatus_Error;
-
-    return InliningStatus_Inlined;
-}
-
-IonBuilder::InliningStatus
 IonBuilder::inlineNewDenseArray(CallInfo &callInfo)
 {
     if (callInfo.constructing() || callInfo.argc() != 1)
         return InliningStatus_NotInlined;
 
     // For now, in seq. mode we just call the C function.  In
     // par. mode we use inlined MIR.
     ExecutionMode executionMode = info().executionMode();
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1358,42 +1358,16 @@ class MThrow
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     bool possiblyCalls() const {
         return true;
     }
 };
 
-class MNewParallelArray : public MNullaryInstruction
-{
-    CompilerRootObject templateObject_;
-
-    MNewParallelArray(JSObject *templateObject)
-      : templateObject_(templateObject)
-    {
-        setResultType(MIRType_Object);
-    }
-
-  public:
-    INSTRUCTION_HEADER(NewParallelArray);
-
-    static MNewParallelArray *New(TempAllocator &alloc, JSObject *templateObject) {
-        return new(alloc) MNewParallelArray(templateObject);
-    }
-
-    AliasSet getAliasSet() const {
-        return AliasSet::None();
-    }
-
-    JSObject *templateObject() const {
-        return templateObject_;
-    }
-};
-
 // Fabricate a type set containing only the type of the specified object.
 types::TemporaryTypeSet *
 MakeSingletonTypeSet(JSObject *obj);
 
 void
 MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
            MIRType newType, types::TemporaryTypeSet *newTypeSet);
 
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -82,17 +82,16 @@ namespace jit {
     _(GuardString)                                                          \
     _(AssertRange)                                                          \
     _(ToDouble)                                                             \
     _(ToFloat32)                                                            \
     _(ToInt32)                                                              \
     _(TruncateToInt32)                                                      \
     _(ToString)                                                             \
     _(NewSlots)                                                             \
-    _(NewParallelArray)                                                     \
     _(NewArray)                                                             \
     _(NewObject)                                                            \
     _(NewDeclEnvObject)                                                     \
     _(NewCallObject)                                                        \
     _(NewStringObject)                                                      \
     _(InitElem)                                                             \
     _(InitElemGetterSetter)                                                 \
     _(InitProp)                                                             \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -179,17 +179,16 @@ class ParallelSafetyVisitor : public MIn
     SAFE_OP(ToInt32)
     SAFE_OP(TruncateToInt32)
     SAFE_OP(MaybeToDoubleElement)
     CUSTOM_OP(ToString)
     SAFE_OP(NewSlots)
     CUSTOM_OP(NewArray)
     CUSTOM_OP(NewObject)
     CUSTOM_OP(NewCallObject)
-    CUSTOM_OP(NewParallelArray)
     UNSAFE_OP(NewDerivedTypedObject)
     UNSAFE_OP(InitElem)
     UNSAFE_OP(InitElemGetterSetter)
     UNSAFE_OP(InitProp)
     UNSAFE_OP(InitPropGetterSetter)
     SAFE_OP(Start)
     UNSAFE_OP(OsrEntry)
     SAFE_OP(Nop)
@@ -513,22 +512,16 @@ ParallelSafetyVisitor::convertToBailout(
 
 bool
 ParallelSafetyVisitor::visitCreateThisWithTemplate(MCreateThisWithTemplate *ins)
 {
     return replaceWithNewPar(ins, ins->templateObject());
 }
 
 bool
-ParallelSafetyVisitor::visitNewParallelArray(MNewParallelArray *ins)
-{
-    return replaceWithNewPar(ins, ins->templateObject());
-}
-
-bool
 ParallelSafetyVisitor::visitNewCallObject(MNewCallObject *ins)
 {
     replace(ins, MNewCallObjectPar::New(alloc(), forkJoinSlice(), ins));
     return true;
 }
 
 bool
 ParallelSafetyVisitor::visitLambda(MLambda *ins)
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/VMFunctions.h"
 
-#include "builtin/ParallelArray.h"
 #include "builtin/TypedObject.h"
 #include "frontend/BytecodeCompiler.h"
 #include "jit/BaselineIC.h"
 #include "jit/IonFrames.h"
 #include "jit/JitCompartment.h"
 #include "vm/ArrayObject.h"
 #include "vm/Debugger.h"
 #include "vm/Interpreter.h"
@@ -272,31 +271,16 @@ IteratorMore(JSContext *cx, HandleObject
     RootedValue tmp(cx);
     if (!js_IteratorMore(cx, obj, &tmp))
         return false;
 
     *res = tmp.toBoolean();
     return true;
 }
 
-JSObject *
-NewInitParallelArray(JSContext *cx, HandleObject templateObject)
-{
-    JS_ASSERT(templateObject->getClass() == &ParallelArrayObject::class_);
-    JS_ASSERT(!templateObject->hasSingletonType());
-
-    RootedObject obj(cx, ParallelArrayObject::newInstance(cx, TenuredObject));
-    if (!obj)
-        return nullptr;
-
-    obj->setType(templateObject->type());
-
-    return obj;
-}
-
 JSObject*
 NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *typeArg)
 {
     RootedTypeObject type(cx, typeArg);
     NewObjectKind newKind = !type ? SingletonObject : GenericObject;
     if (type && type->shouldPreTenure())
         newKind = TenuredObject;
     RootedObject obj(cx, NewDenseAllocatedArray(cx, count, nullptr, newKind));
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -349,20 +349,20 @@ MSG_DEF(JSMSG_PARAMETER_AFTER_REST,   29
 MSG_DEF(JSMSG_NO_REST_NAME,           296, 0, JSEXN_SYNTAXERR, "no parameter name after ...")
 MSG_DEF(JSMSG_ARGUMENTS_AND_REST,     297, 0, JSEXN_SYNTAXERR, "'arguments' object may not be used in conjunction with a rest parameter")
 MSG_DEF(JSMSG_FUNCTION_ARGUMENTS_AND_REST, 298, 0, JSEXN_ERR, "the 'arguments' property of a function with a rest parameter may not be used")
 MSG_DEF(JSMSG_REST_WITH_DEFAULT,      299, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default")
 MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 300, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default")
 MSG_DEF(JSMSG_YIELD_IN_DEFAULT,       301, 0, JSEXN_SYNTAXERR, "yield in default expression")
 MSG_DEF(JSMSG_INTRINSIC_NOT_DEFINED,  302, 1, JSEXN_REFERENCEERR, "no intrinsic function {0}")
 MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 303, 2, JSEXN_ERR,      "{0} is being assigned a {1}, but already has one")
-MSG_DEF(JSMSG_PAR_ARRAY_BAD_ARG,      304, 1, JSEXN_RANGEERR, "invalid ParallelArray{0} argument")
-MSG_DEF(JSMSG_PAR_ARRAY_BAD_PARTITION, 305, 0, JSEXN_ERR, "argument must be divisible by outermost dimension")
-MSG_DEF(JSMSG_PAR_ARRAY_REDUCE_EMPTY, 306, 0, JSEXN_ERR, "cannot reduce ParallelArray object whose outermost dimension is empty")
-MSG_DEF(JSMSG_PAR_ARRAY_ALREADY_FLAT, 307, 0, JSEXN_ERR, "cannot flatten 1-dimensional ParallelArray object")
+MSG_DEF(JSMSG_PAR_ARRAY_BAD_ARG,      304, 0, JSEXN_RANGEERR, "invalid parallel method argument")
+MSG_DEF(JSMSG_UNUSED305,              305, 0, JSEXN_NONE, "")
+MSG_DEF(JSMSG_UNUSED306,              306, 0, JSEXN_NONE, "")
+MSG_DEF(JSMSG_UNUSED307,              307, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_CONFLICT, 308, 0, JSEXN_ERR, "no conflict resolution function provided")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BOUNDS, 309, 0, JSEXN_ERR, "index in scatter vector out of bounds")
 MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE,   310, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent")
 MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE,    311, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
 MSG_DEF(JSMSG_CANT_REPORT_NEW,        312, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object")
 MSG_DEF(JSMSG_CANT_REPORT_INVALID,    313, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor")
 MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC,   314, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable")
 MSG_DEF(JSMSG_CANT_DEFINE_NEW,        315, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -47,17 +47,16 @@
 #include "prmjtime.h"
 
 #if ENABLE_YARR_JIT
 #include "assembler/jit/ExecutableAllocator.h"
 #endif
 #include "builtin/Eval.h"
 #include "builtin/Intl.h"
 #include "builtin/MapObject.h"
-#include "builtin/ParallelArray.h"
 #include "builtin/RegExp.h"
 #include "builtin/TypedObject.h"
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/FullParseHandler.h"  // for JS_BufferIsCompileableUnit
 #include "frontend/Parser.h" // for JS_BufferIsCompileableUnit
 #include "gc/Marking.h"
 #include "jit/AsmJSLink.h"
 #include "js/CharacterEncoding.h"
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -10,17 +10,16 @@
 #define jsinferinlines_h
 
 #include "jsinfer.h"
 
 #include "mozilla/PodOperations.h"
 
 #include "jsanalyze.h"
 
-#include "builtin/ParallelArray.h"
 #include "jit/ExecutionModeInlines.h"
 #include "vm/ArrayObject.h"
 #include "vm/BooleanObject.h"
 #include "vm/NumberObject.h"
 #include "vm/StringObject.h"
 #include "vm/TypedArrayObject.h"
 
 #include "jsanalyzeinlines.h"
@@ -349,19 +348,16 @@ GetClassForProtoKey(JSProtoKey key)
         return &TypedArrayObject::classes[key - JSProto_Int8Array];
 
       case JSProto_ArrayBuffer:
         return &ArrayBufferObject::class_;
 
       case JSProto_DataView:
         return &DataViewObject::class_;
 
-      case JSProto_ParallelArray:
-        return &ParallelArrayObject::class_;
-
       default:
         MOZ_ASSUME_UNREACHABLE("Bad proto key");
     }
 }
 
 /*
  * Get the default 'new' object for a given standard class, per the currently
  * active global.
--- a/js/src/jsprototypes.h
+++ b/js/src/jsprototypes.h
@@ -86,16 +86,15 @@
     real(Float32Array,          28,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_FLOAT32)) \
     real(Float64Array,          29,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_FLOAT64)) \
     real(Uint8ClampedArray,     30,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)) \
     real(Proxy,                 31,     js_InitProxyClass,         &ProxyObject::uncallableClass_) \
     real(WeakMap,               32,     js_InitWeakMapClass,       OCLASP(WeakMap)) \
     real(Map,                   33,     js_InitMapClass,           OCLASP(Map)) \
     real(Set,                   34,     js_InitSetClass,           OCLASP(Set)) \
     real(DataView,              35,     js_InitTypedArrayClasses,  OCLASP(DataView)) \
-IF_PJS(real,imaginary)  (ParallelArray,         36,     js_InitParallelArrayClass, OCLASP(ParallelArray)) \
-IF_INTL(real,imaginary) (Intl,                  37,     js_InitIntlClass,          CLASP(Intl)) \
-IF_BDATA(real,imaginary)(TypedObject,           38,     js_InitTypedObjectModuleObject,   OCLASP(TypedObjectModule)) \
-    imaginary(GeneratorFunction,     39,     js_InitIteratorClasses, dummy) \
+IF_INTL(real,imaginary) (Intl,                  36,     js_InitIntlClass,          CLASP(Intl)) \
+IF_BDATA(real,imaginary)(TypedObject,           37,     js_InitTypedObjectModuleObject,   OCLASP(TypedObjectModule)) \
+    imaginary(GeneratorFunction,     38,     js_InitIteratorClasses, dummy) \
 
 #define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
 
 #endif /* jsprototypes_h */
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -91,17 +91,16 @@ EXPORTS.js += [
 ]
 
 UNIFIED_SOURCES += [
     'assembler/jit/ExecutableAllocator.cpp',
     'builtin/Eval.cpp',
     'builtin/Intl.cpp',
     'builtin/MapObject.cpp',
     'builtin/Object.cpp',
-    'builtin/ParallelArray.cpp',
     'builtin/Profilers.cpp',
     'builtin/TestingFunctions.cpp',
     'builtin/TypedObject.cpp',
     'builtin/TypeRepresentation.cpp',
     'devtools/sharkctl.cpp',
     'ds/LifoAlloc.cpp',
     'frontend/BytecodeCompiler.cpp',
     'frontend/BytecodeEmitter.cpp',
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -186,17 +186,17 @@ ExecuteSequentially(JSContext *cx, Handl
 // Class Declarations and Function Prototypes
 
 namespace js {
 
 // When writing tests, it is often useful to specify different modes
 // of operation.
 enum ForkJoinMode {
     // WARNING: If you change this enum, you MUST update
-    // ForkJoinMode() in ParallelArray.js
+    // ForkJoinMode() in Utilities.js
 
     // The "normal" behavior: attempt parallel, fallback to
     // sequential.  If compilation is ongoing in a helper thread, then
     // run sequential warmup iterations in the meantime. If those
     // iterations wind up completing all the work, just abort.
     ForkJoinModeNormal,
 
     // Like normal, except that we will keep running warmup iterations
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -512,19 +512,16 @@ GlobalObject::initStandardClasses(JSCont
            js_InitProxyClass(cx, global) &&
            js_InitMapClass(cx, global) &&
            GlobalObject::initMapIteratorProto(cx, global) &&
            js_InitSetClass(cx, global) &&
            GlobalObject::initSetIteratorProto(cx, global) &&
 #if EXPOSE_INTL_API
            js_InitIntlClass(cx, global) &&
 #endif
-#if ENABLE_PARALLEL_JS
-           js_InitParallelArrayClass(cx, global) &&
-#endif
            true;
 }
 
 /* static */ bool
 GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global)
 {
     HeapSlot &v = global->getSlotRef(RUNTIME_CODEGEN_ENABLED);
     if (v.isUndefined()) {
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -7,17 +7,16 @@
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsfriendapi.h"
 #include "jshashutil.h"
 #include "jsobj.h"
 #include "selfhosted.out.h"
 
 #include "builtin/Intl.h"
-#include "builtin/ParallelArray.h"
 #include "builtin/TypedObject.h"
 #include "gc/Marking.h"
 #include "vm/ForkJoin.h"
 #include "vm/Interpreter.h"
 
 #include "jsfuninlines.h"
 #include "jsscriptinlines.h"
 
@@ -307,37 +306,16 @@ static bool
 intrinsic_ForkJoinSlices(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     args.rval().setInt32(ForkJoinSlices(cx));
     return true;
 }
 
 /*
- * NewParallelArray(init, ...args): Creates a new parallel array using
- * an initialization function |init|. All subsequent arguments are
- * passed to |init|. The new instance will be passed as the |this|
- * argument.
- */
-bool
-js::intrinsic_NewParallelArray(JSContext *cx, unsigned argc, Value *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    JS_ASSERT(args[0].isObject() && args[0].toObject().is<JSFunction>());
-
-    RootedFunction init(cx, &args[0].toObject().as<JSFunction>());
-    CallArgs args0 = CallArgsFromVp(argc - 1, vp + 1);
-    if (!js::ParallelArrayObject::constructHelper(cx, &init, args0))
-        return false;
-    args.rval().set(args0.rval());
-    return true;
-}
-
-/*
  * NewDenseArray(length): Allocates and returns a new dense array with
  * the given length where all values are initialized to holes.
  */
 bool
 js::intrinsic_NewDenseArray(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
@@ -635,17 +613,16 @@ static const JSFunctionSpec intrinsic_fu
     JS_FN("NewArrayIterator",        intrinsic_NewArrayIterator,        0,0),
     JS_FN("IsArrayIterator",         intrinsic_IsArrayIterator,         1,0),
 
     JS_FN("NewStringIterator",       intrinsic_NewStringIterator,       0,0),
     JS_FN("IsStringIterator",        intrinsic_IsStringIterator,        1,0),
 
     JS_FN("ForkJoin",                intrinsic_ForkJoin,                2,0),
     JS_FN("ForkJoinSlices",          intrinsic_ForkJoinSlices,          0,0),
-    JS_FN("NewParallelArray",        intrinsic_NewParallelArray,        3,0),
     JS_FN("NewDenseArray",           intrinsic_NewDenseArray,           1,0),
     JS_FN("ShouldForceSequential",   intrinsic_ShouldForceSequential,   0,0),
     JS_FN("ParallelTestsShouldPass", intrinsic_ParallelTestsShouldPass, 0,0),
 
     // See builtin/TypedObject.h for descriptors of the typedobj functions.
     JS_FN("NewTypedHandle",
           js::NewTypedHandle,
           1, 0),