Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/js/array.js b/src/js/array.js
index 1406df3..0a77b23 100644
--- a/src/js/array.js
+++ b/src/js/array.js
@@ -11,7 +11,6 @@
 // -------------------------------------------------------------------
 // Imports
 
-var AddIndexedProperty;
 var FLAG_harmony_species;
 var GetIterator;
 var GetMethod;
@@ -21,27 +20,18 @@
 var MakeTypeError;
 var MaxSimple;
 var MinSimple;
-var ObjectDefineProperty;
 var ObjectHasOwnProperty;
 var ObjectToString = utils.ImportNow("object_to_string");
-var ObserveBeginPerformSplice;
-var ObserveEndPerformSplice;
-var ObserveEnqueueSpliceRecord;
 var iteratorSymbol = utils.ImportNow("iterator_symbol");
 var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
 
 utils.Import(function(from) {
-  AddIndexedProperty = from.AddIndexedProperty;
   GetIterator = from.GetIterator;
   GetMethod = from.GetMethod;
   MakeTypeError = from.MakeTypeError;
   MaxSimple = from.MaxSimple;
   MinSimple = from.MinSimple;
-  ObjectDefineProperty = from.ObjectDefineProperty;
   ObjectHasOwnProperty = from.ObjectHasOwnProperty;
-  ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
-  ObserveEndPerformSplice = from.ObserveEndPerformSplice;
-  ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
 });
 
 utils.ImportFromExperimental(function(from) {
@@ -53,6 +43,9 @@
 
 function ArraySpeciesCreate(array, length) {
   var constructor;
+
+  length = INVERT_NEG_ZERO(length);
+
   if (FLAG_harmony_species) {
     constructor = %ArraySpeciesConstructor(array);
   } else {
@@ -62,17 +55,6 @@
 }
 
 
-function DefineIndexedProperty(array, i, value) {
-  if (FLAG_harmony_species) {
-    var result = ObjectDefineProperty(array, i, {
-      value: value, writable: true, configurable: true, enumerable: true
-    });
-    if (!result) throw MakeTypeError(kStrictCannotAssign, i);
-  } else {
-    AddIndexedProperty(array, i, value);
-  }
-}
-
 function KeySortCompare(a, b) {
   return a - b;
 }
@@ -123,8 +105,7 @@
   // Only use the sparse variant on arrays that are likely to be sparse and the
   // number of elements touched in the operation is relatively small compared to
   // the overall size of the array.
-  if (!is_array || length < 1000 || %IsObserved(array) ||
-      %HasComplexElements(array)) {
+  if (!is_array || length < 1000 || %HasComplexElements(array)) {
     return false;
   }
   if (!%_IsSmi(length)) {
@@ -265,7 +246,7 @@
     for (var i = start_i; i < limit; ++i) {
       var current = array[i];
       if (!IS_UNDEFINED(current) || i in array) {
-        DefineIndexedProperty(deleted_elements, i - start_i, current);
+        %CreateDataProperty(deleted_elements, i - start_i, current);
       }
     }
   } else {
@@ -275,7 +256,7 @@
       if (key >= start_i) {
         var current = array[key];
         if (!IS_UNDEFINED(current) || key in array) {
-          DefineIndexedProperty(deleted_elements, key - start_i, current);
+          %CreateDataProperty(deleted_elements, key - start_i, current);
         }
       }
     }
@@ -352,7 +333,7 @@
     var index = start_i + i;
     if (HAS_INDEX(array, index, is_array)) {
       var current = array[index];
-      DefineIndexedProperty(deleted_elements, i, current);
+      %CreateDataProperty(deleted_elements, i, current);
     }
   }
 }
@@ -456,23 +437,6 @@
 }
 
 
-function ObservedArrayPop(n) {
-  n--;
-  var value = this[n];
-
-  try {
-    ObserveBeginPerformSplice(this);
-    delete this[n];
-    this.length = n;
-  } finally {
-    ObserveEndPerformSplice(this);
-    ObserveEnqueueSpliceRecord(this, n, [value], 0);
-  }
-
-  return value;
-}
-
-
 // Removes the last element from the array and returns it. See
 // ECMA-262, section 15.4.4.6.
 function ArrayPop() {
@@ -485,9 +449,6 @@
     return;
   }
 
-  if (%IsObserved(array))
-    return ObservedArrayPop.call(array, n);
-
   n--;
   var value = array[n];
   %DeleteProperty_Strict(array, n);
@@ -496,46 +457,19 @@
 }
 
 
-function ObservedArrayPush() {
-  var n = TO_LENGTH(this.length);
-  var m = arguments.length;
-
-  try {
-    ObserveBeginPerformSplice(this);
-    for (var i = 0; i < m; i++) {
-      this[i+n] = arguments[i];
-    }
-    var new_length = n + m;
-    this.length = new_length;
-  } finally {
-    ObserveEndPerformSplice(this);
-    ObserveEnqueueSpliceRecord(this, n, [], m);
-  }
-
-  return new_length;
-}
-
-
 // Appends the arguments to the end of the array and returns the new
 // length of the array. See ECMA-262, section 15.4.4.7.
 function ArrayPush() {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
 
-  if (%IsObserved(this))
-    return ObservedArrayPush.apply(this, arguments);
-
   var array = TO_OBJECT(this);
   var n = TO_LENGTH(array.length);
   var m = arguments.length;
 
-  // It appears that there is no enforced, absolute limit on the number of
-  // arguments, but it would surely blow the stack to use 2**30 or more.
-  // To avoid integer overflow, do the comparison to the max safe integer
-  // after subtracting 2**30 from both sides. (2**31 would seem like a
-  // natural value, but it is negative in JS, and 2**32 is 1.)
-  if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) {
-    throw MakeTypeError(kPushPastSafeLength, m, n);
-  }
+  // Subtract n from kMaxSafeInteger rather than testing m + n >
+  // kMaxSafeInteger. n may already be kMaxSafeInteger. In that case adding
+  // e.g., 1 would not be safe.
+  if (m > kMaxSafeInteger - n) throw MakeTypeError(kPushPastSafeLength, m, n);
 
   for (var i = 0; i < m; i++) {
     array[i+n] = arguments[i];
@@ -646,22 +580,6 @@
 }
 
 
-function ObservedArrayShift(len) {
-  var first = this[0];
-
-  try {
-    ObserveBeginPerformSplice(this);
-    SimpleMove(this, 0, 1, len, 0);
-    this.length = len - 1;
-  } finally {
-    ObserveEndPerformSplice(this);
-    ObserveEnqueueSpliceRecord(this, 0, [first], 0);
-  }
-
-  return first;
-}
-
-
 function ArrayShift() {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
 
@@ -675,9 +593,6 @@
 
   if (%object_is_sealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed);
 
-  if (%IsObserved(array))
-    return ObservedArrayShift.call(array, len);
-
   var first = array[0];
 
   if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
@@ -692,33 +607,9 @@
 }
 
 
-function ObservedArrayUnshift() {
-  var len = TO_LENGTH(this.length);
-  var num_arguments = arguments.length;
-
-  try {
-    ObserveBeginPerformSplice(this);
-    SimpleMove(this, 0, 0, len, num_arguments);
-    for (var i = 0; i < num_arguments; i++) {
-      this[i] = arguments[i];
-    }
-    var new_length = len + num_arguments;
-    this.length = new_length;
-  } finally {
-    ObserveEndPerformSplice(this);
-    ObserveEnqueueSpliceRecord(this, 0, [], num_arguments);
-  }
-
-  return new_length;
-}
-
-
 function ArrayUnshift(arg1) {  // length == 1
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
 
-  if (%IsObserved(this))
-    return ObservedArrayUnshift.apply(this, arguments);
-
   var array = TO_OBJECT(this);
   var len = TO_LENGTH(array.length);
   var num_arguments = arguments.length;
@@ -813,53 +704,9 @@
 }
 
 
-function ObservedArraySplice(start, delete_count) {
-  var num_arguments = arguments.length;
-  var len = TO_LENGTH(this.length);
-  var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
-  var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
-                                           start_i);
-  var deleted_elements = [];
-  deleted_elements.length = del_count;
-  var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
-
-  try {
-    ObserveBeginPerformSplice(this);
-
-    SimpleSlice(this, start_i, del_count, len, deleted_elements);
-    SimpleMove(this, start_i, del_count, len, num_elements_to_add);
-
-    // Insert the arguments into the resulting array in
-    // place of the deleted elements.
-    var i = start_i;
-    var arguments_index = 2;
-    var arguments_length = arguments.length;
-    while (arguments_index < arguments_length) {
-      this[i++] = arguments[arguments_index++];
-    }
-    this.length = len - del_count + num_elements_to_add;
-
-  } finally {
-    ObserveEndPerformSplice(this);
-    if (deleted_elements.length || num_elements_to_add) {
-      ObserveEnqueueSpliceRecord(this,
-                                 start_i,
-                                 deleted_elements.slice(),
-                                 num_elements_to_add);
-    }
-  }
-
-  // Return the deleted elements.
-  return deleted_elements;
-}
-
-
 function ArraySplice(start, delete_count) {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
 
-  if (%IsObserved(this))
-    return ObservedArraySplice.apply(this, arguments);
-
   var num_arguments = arguments.length;
   var array = TO_OBJECT(this);
   var len = TO_LENGTH(array.length);
@@ -1048,7 +895,8 @@
   // of a prototype property.
   var CopyFromPrototype = function CopyFromPrototype(obj, length) {
     var max = 0;
-    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+    for (var proto = %object_get_prototype_of(obj); proto;
+         proto = %object_get_prototype_of(proto)) {
       var indices = IS_PROXY(proto) ? length : %GetArrayKeys(proto, length);
       if (IS_NUMBER(indices)) {
         // It's an interval.
@@ -1076,7 +924,8 @@
   // where a prototype of obj has an element. I.e., shadow all prototype
   // elements in that range.
   var ShadowPrototypeElements = function(obj, from, to) {
-    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+    for (var proto = %object_get_prototype_of(obj); proto;
+         proto = %object_get_prototype_of(proto)) {
       var indices = IS_PROXY(proto) ? to : %GetArrayKeys(proto, to);
       if (IS_NUMBER(indices)) {
         // It's an interval.
@@ -1143,7 +992,7 @@
     }
     for (i = length - num_holes; i < length; i++) {
       // For compatability with Webkit, do not expose elements in the prototype.
-      if (i in %_GetPrototype(obj)) {
+      if (i in %object_get_prototype_of(obj)) {
         obj[i] = UNDEFINED;
       } else {
         delete obj[i];
@@ -1174,9 +1023,9 @@
   var num_non_undefined = %RemoveArrayHoles(array, length);
 
   if (num_non_undefined == -1) {
-    // The array is observed, or there were indexed accessors in the array.
+    // There were indexed accessors in the array.
     // Move array holes and undefineds to the end using a Javascript function
-    // that is safe in the presence of accessors and is observable.
+    // that is safe in the presence of accessors.
     num_non_undefined = SafeRemoveArrayHoles(array);
   }
 
@@ -1211,7 +1060,7 @@
     if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       if (%_Call(f, receiver, element, i, array)) {
-        DefineIndexedProperty(result, result_length, element);
+        %CreateDataProperty(result, result_length, element);
         result_length++;
       }
     }
@@ -1331,7 +1180,7 @@
   for (var i = 0; i < length; i++) {
     if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
-      DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array));
+      %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
     }
   }
   return result;
@@ -1347,7 +1196,7 @@
   if (IS_UNDEFINED(index)) {
     index = 0;
   } else {
-    index = TO_INTEGER(index) + 0;  // Add 0 to convert -0 to 0
+    index = INVERT_NEG_ZERO(TO_INTEGER(index));
     // If index is negative, index from the end of the array.
     if (index < 0) {
       index = length + index;
@@ -1409,7 +1258,7 @@
   if (argumentsLength < 2) {
     index = length - 1;
   } else {
-    index = TO_INTEGER(index) + 0;  // Add 0 to convert -0 to 0
+    index = INVERT_NEG_ZERO(TO_INTEGER(index));
     // If index is negative, index from end of the array.
     if (index < 0) index += length;
     // If index is still negative, do not search the array.
@@ -1736,17 +1585,6 @@
 }
 
 
-function AddArrayElement(constructor, array, i, value) {
-  if (constructor === GlobalArray) {
-    AddIndexedProperty(array, i, value);
-  } else {
-    ObjectDefineProperty(array, i, {
-      value: value, writable: true, configurable: true, enumerable: true
-    });
-  }
-}
-
-
 // ES6, draft 10-14-14, section 22.1.2.1
 function ArrayFrom(arrayLike, mapfn, receiver) {
   var items = TO_OBJECT(arrayLike);
@@ -1775,7 +1613,7 @@
       } else {
         mappedValue = nextValue;
       }
-      AddArrayElement(this, result, k, mappedValue);
+      %CreateDataProperty(result, k, mappedValue);
       k++;
     }
     result.length = k;
@@ -1791,7 +1629,7 @@
       } else {
         mappedValue = nextValue;
       }
-      AddArrayElement(this, result, k, mappedValue);
+      %CreateDataProperty(result, k, mappedValue);
     }
 
     result.length = k;
@@ -1807,7 +1645,7 @@
   // TODO: Implement IsConstructor (ES6 section 7.2.5)
   var array = %IsConstructor(constructor) ? new constructor(length) : [];
   for (var i = 0; i < length; i++) {
-    AddArrayElement(constructor, array, i, args[i]);
+    %CreateDataProperty(array, i, args[i]);
   }
   array.length = length;
   return array;
diff --git a/src/js/arraybuffer.js b/src/js/arraybuffer.js
index f0273c7..e739960 100644
--- a/src/js/arraybuffer.js
+++ b/src/js/arraybuffer.js
@@ -70,7 +70,9 @@
     throw MakeTypeError(kIncompatibleMethodReceiver,
                         'ArrayBuffer.prototype.slice', result);
   }
-  // TODO(littledan): Check for a detached ArrayBuffer
+  // Checks for detached source/target ArrayBuffers are done inside of
+  // %ArrayBufferSliceImpl; the reordering of checks does not violate
+  // the spec because all exceptions thrown are TypeErrors.
   if (result === this) {
     throw MakeTypeError(kArrayBufferSpeciesThis);
   }
diff --git a/src/js/generator.js b/src/js/generator.js
deleted file mode 100644
index 3dcdcc0..0000000
--- a/src/js/generator.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-// -------------------------------------------------------------------
-// Imports
-
-var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype");
-var GeneratorFunction = utils.ImportNow("GeneratorFunction");
-var GlobalFunction = global.Function;
-var MakeTypeError;
-var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
-
-utils.Import(function(from) {
-  MakeTypeError = from.MakeTypeError;
-});
-
-// ----------------------------------------------------------------------------
-
-// Generator functions and objects are specified by ES6, sections 15.19.3 and
-// 15.19.4.
-
-function GeneratorObjectNext(value) {
-  if (!IS_GENERATOR(this)) {
-    throw MakeTypeError(kIncompatibleMethodReceiver,
-                        '[Generator].prototype.next', this);
-  }
-
-  var continuation = %GeneratorGetContinuation(this);
-  if (continuation > 0) {
-    // Generator is suspended.
-    DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
-    return %_GeneratorNext(this, value);
-  } else if (continuation == 0) {
-    // Generator is already closed.
-    return %_CreateIterResultObject(UNDEFINED, true);
-  } else {
-    // Generator is running.
-    throw MakeTypeError(kGeneratorRunning);
-  }
-}
-
-
-function GeneratorObjectReturn(value) {
-  if (!IS_GENERATOR(this)) {
-    throw MakeTypeError(kIncompatibleMethodReceiver,
-                        '[Generator].prototype.return', this);
-  }
-
-  var continuation = %GeneratorGetContinuation(this);
-  if (continuation > 0) {
-    // Generator is suspended.
-    DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
-    return %_GeneratorReturn(this, value);
-  } else if (continuation == 0) {
-    // Generator is already closed.
-    return %_CreateIterResultObject(value, true);
-  } else {
-    // Generator is running.
-    throw MakeTypeError(kGeneratorRunning);
-  }
-}
-
-
-function GeneratorObjectThrow(exn) {
-  if (!IS_GENERATOR(this)) {
-    throw MakeTypeError(kIncompatibleMethodReceiver,
-                        '[Generator].prototype.throw', this);
-  }
-
-  var continuation = %GeneratorGetContinuation(this);
-  if (continuation > 0) {
-    // Generator is suspended.
-    DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
-    return %_GeneratorThrow(this, exn);
-  } else if (continuation == 0) {
-    // Generator is already closed.
-    throw exn;
-  } else {
-    // Generator is running.
-    throw MakeTypeError(kGeneratorRunning);
-  }
-}
-
-// ----------------------------------------------------------------------------
-
-// None of the three resume operations (Runtime_GeneratorNext,
-// Runtime_GeneratorReturn, Runtime_GeneratorThrow) is supported by
-// Crankshaft or TurboFan.  Disable optimization of wrappers here.
-%NeverOptimizeFunction(GeneratorObjectNext);
-%NeverOptimizeFunction(GeneratorObjectReturn);
-%NeverOptimizeFunction(GeneratorObjectThrow);
-
-// Set up non-enumerable functions on the generator prototype object.
-var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
-utils.InstallFunctions(GeneratorObjectPrototype,
-                       DONT_ENUM,
-                      ["next", GeneratorObjectNext,
-                       "return", GeneratorObjectReturn,
-                       "throw", GeneratorObjectThrow]);
-
-%AddNamedProperty(GeneratorObjectPrototype, "constructor",
-    GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
-%AddNamedProperty(GeneratorObjectPrototype,
-    toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY);
-%InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype);
-%AddNamedProperty(GeneratorFunctionPrototype,
-    toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY);
-%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
-    GeneratorFunction, DONT_ENUM | READ_ONLY);
-%InternalSetPrototype(GeneratorFunction, GlobalFunction);
-
-})
diff --git a/src/js/harmony-async-await.js b/src/js/harmony-async-await.js
new file mode 100644
index 0000000..c6705ef
--- /dev/null
+++ b/src/js/harmony-async-await.js
@@ -0,0 +1,43 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var AsyncFunctionNext;
+var AsyncFunctionThrow;
+var PromiseReject;
+var PromiseResolve;
+var PromiseThen;
+
+utils.Import(function(from) {
+  AsyncFunctionNext = from.AsyncFunctionNext;
+  AsyncFunctionThrow = from.AsyncFunctionThrow;
+  PromiseReject = from.PromiseCreateRejected;
+  PromiseResolve = from.PromiseCreateResolved;
+  PromiseThen = from.PromiseThen;
+});
+
+// -------------------------------------------------------------------
+
+function AsyncFunctionAwait(generator, value) {
+  return %_Call(
+      PromiseThen, PromiseResolve(value),
+      function(sentValue) {
+        return %_Call(AsyncFunctionNext, generator, sentValue);
+      },
+      function(sentError) {
+        return %_Call(AsyncFunctionThrow, generator, sentError);
+      });
+}
+
+%InstallToContext([ "async_function_await", AsyncFunctionAwait ]);
+
+})
diff --git a/src/js/harmony-atomics.js b/src/js/harmony-atomics.js
index 9f80227..8372903 100644
--- a/src/js/harmony-atomics.js
+++ b/src/js/harmony-atomics.js
@@ -62,19 +62,6 @@
   return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
 }
 
-function AtomicsLoadJS(sta, index) {
-  CheckSharedIntegerTypedArray(sta);
-  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
-  return %_AtomicsLoad(sta, index);
-}
-
-function AtomicsStoreJS(sta, index, value) {
-  CheckSharedIntegerTypedArray(sta);
-  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
-  value = TO_NUMBER(value);
-  return %_AtomicsStore(sta, index, value);
-}
-
 function AtomicsAddJS(ia, index, value) {
   CheckSharedIntegerTypedArray(ia);
   index = ValidateIndex(index, %_TypedArrayGetLength(ia));
@@ -161,13 +148,9 @@
 
 // -------------------------------------------------------------------
 
-function AtomicsConstructor() {}
+var Atomics = global.Atomics;
 
-var Atomics = new AtomicsConstructor();
-
-%InternalSetPrototype(Atomics, GlobalObject.prototype);
-%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
-%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');
+// The Atomics global is defined by the bootstrapper.
 
 %AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
 
@@ -179,9 +162,9 @@
 ]);
 
 utils.InstallFunctions(Atomics, DONT_ENUM, [
+  // TODO(binji): remove the rest of the (non futex) Atomics functions as they
+  // become builtins.
   "compareExchange", AtomicsCompareExchangeJS,
-  "load", AtomicsLoadJS,
-  "store", AtomicsStoreJS,
   "add", AtomicsAddJS,
   "sub", AtomicsSubJS,
   "and", AtomicsAndJS,
diff --git a/src/js/harmony-object-observe.js b/src/js/harmony-object-observe.js
deleted file mode 100644
index 95dd298..0000000
--- a/src/js/harmony-object-observe.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-var ObserveArrayMethods = utils.ImportNow("ObserveArrayMethods");
-var ObserveObjectMethods = utils.ImportNow("ObserveObjectMethods");;
-
-utils.InstallFunctions(global.Object, DONT_ENUM, ObserveObjectMethods);
-utils.InstallFunctions(global.Array, DONT_ENUM, ObserveArrayMethods);
-
-})
diff --git a/src/js/harmony-string-padding.js b/src/js/harmony-string-padding.js
index a6c6c47..dc59823 100644
--- a/src/js/harmony-string-padding.js
+++ b/src/js/harmony-string-padding.js
@@ -30,7 +30,8 @@
   } else {
     fillString = TO_STRING(fillString);
     if (fillString === "") {
-      fillString = " ";
+      // If filler is the empty String, return S.
+      return "";
     }
   }
 
diff --git a/src/js/i18n.js b/src/js/i18n.js
index 845289a..7c9535b 100644
--- a/src/js/i18n.js
+++ b/src/js/i18n.js
@@ -20,6 +20,7 @@
 var ArrayIndexOf;
 var ArrayJoin;
 var ArrayPush;
+var FLAG_intl_extra;
 var GlobalBoolean = global.Boolean;
 var GlobalDate = global.Date;
 var GlobalNumber = global.Number;
@@ -27,7 +28,7 @@
 var GlobalString = global.String;
 var InstallFunctions = utils.InstallFunctions;
 var InstallGetter = utils.InstallGetter;
-var InternalPackedArray = utils.InternalPackedArray;
+var InternalArray = utils.InternalArray;
 var InternalRegExpMatch;
 var InternalRegExpReplace
 var IsFinite;
@@ -35,8 +36,6 @@
 var MakeError;
 var MakeRangeError;
 var MakeTypeError;
-var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties");
-var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty");
 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
 var OverrideFunction = utils.OverrideFunction;
 var patternSymbol = utils.ImportNow("intl_pattern_symbol");
@@ -66,6 +65,10 @@
   StringSubstring = from.StringSubstring;
 });
 
+utils.ImportFromExperimental(function(from) {
+  FLAG_intl_extra = from.FLAG_intl_extra;
+});
+
 // Utilities for definitions
 
 function InstallFunction(object, name, func) {
@@ -84,11 +87,11 @@
 /**
  * Adds bound method to the prototype of the given object.
  */
-function AddBoundMethod(obj, methodName, implementation, length) {
+function AddBoundMethod(obj, methodName, implementation, length, type) {
   %CheckIsBootstrapping();
   var internalName = %CreatePrivateSymbol(methodName);
   var getter = function() {
-    if (!%IsInitializedIntlObject(this)) {
+    if (!%IsInitializedIntlObjectOfType(this, type)) {
       throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
     }
     if (IS_UNDEFINED(this[internalName])) {
@@ -144,6 +147,13 @@
  */
 var DEFAULT_ICU_LOCALE = UNDEFINED;
 
+function GetDefaultICULocaleJS() {
+  if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
+    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+  }
+  return DEFAULT_ICU_LOCALE;
+}
+
 /**
  * Unicode extension regular expression.
  */
@@ -307,7 +317,7 @@
  * Locales appear in the same order in the returned list as in the input list.
  */
 function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
-  var matchedLocales = [];
+  var matchedLocales = new InternalArray();
   for (var i = 0; i < requestedLocales.length; ++i) {
     // Remove -u- extension.
     var locale = InternalRegExpReplace(
@@ -448,11 +458,7 @@
   }
 
   // Didn't find a match, return default.
-  if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
-    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
-  }
-
-  return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+  return {'locale': GetDefaultICULocaleJS(), 'extension': '', 'position': -1};
 }
 
 
@@ -567,21 +573,23 @@
 
 
 /**
- * Converts all OwnProperties into
+ * Given an array-like, outputs an Array with the numbered
+ * properties copied over and defined
  * configurable: false, writable: false, enumerable: true.
  */
-function freezeArray(array) {
-  var l = array.length;
+function freezeArray(input) {
+  var array = [];
+  var l = input.length;
   for (var i = 0; i < l; i++) {
-    if (i in array) {
-      ObjectDefineProperty(array, i, {value: array[i],
-                                      configurable: false,
-                                      writable: false,
-                                      enumerable: true});
+    if (i in input) {
+      %object_define_property(array, i, {value: input[i],
+                                         configurable: false,
+                                         writable: false,
+                                         enumerable: true});
     }
   }
 
-  ObjectDefineProperty(array, 'length', {value: l, writable: false});
+  %object_define_property(array, 'length', {value: l, writable: false});
   return array;
 }
 
@@ -643,8 +651,8 @@
  * Configurable is false by default.
  */
 function defineWEProperty(object, property, value) {
-  ObjectDefineProperty(object, property,
-                       {value: value, writable: true, enumerable: true});
+  %object_define_property(object, property,
+                          {value: value, writable: true, enumerable: true});
 }
 
 
@@ -663,10 +671,10 @@
  * Defines a property and sets writable, enumerable and configurable to true.
  */
 function defineWECProperty(object, property, value) {
-  ObjectDefineProperty(object, property, {value: value,
-                                          writable: true,
-                                          enumerable: true,
-                                          configurable: true});
+  %object_define_property(object, property, {value: value,
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
 }
 
 
@@ -722,21 +730,24 @@
  */
 function canonicalizeLanguageTag(localeID) {
   // null is typeof 'object' so we have to do extra check.
-  if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+  if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) ||
       IS_NULL(localeID)) {
     throw MakeTypeError(kLanguageID);
   }
 
+  // Optimize for the most common case; a language code alone in
+  // the canonical form/lowercase (e.g. "en", "fil").
+  if (IS_STRING(localeID) &&
+      !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) {
+    return localeID;
+  }
+
   var localeString = GlobalString(localeID);
 
   if (isValidLanguageTag(localeString) === false) {
     throw MakeRangeError(kInvalidLanguageTag, localeString);
   }
 
-  // This call will strip -kn but not -kn-true extensions.
-  // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
-  // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
-  // upgrade to ICU 4.9.
   var tag = %CanonicalizeLanguageTag(localeString);
   if (tag === 'invalid-tag') {
     throw MakeRangeError(kInvalidLanguageTag, localeString);
@@ -751,11 +762,8 @@
  * Throws on locales that are not well formed BCP47 tags.
  */
 function initializeLocaleList(locales) {
-  var seen = [];
-  if (IS_UNDEFINED(locales)) {
-    // Constructor is called without arguments.
-    seen = [];
-  } else {
+  var seen = new InternalArray();
+  if (!IS_UNDEFINED(locales)) {
     // We allow single string localeID.
     if (typeof locales === 'string') {
       %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales));
@@ -810,8 +818,8 @@
   // Skip language since it can match variant regex, so we start from 1.
   // We are matching i-klingon here, but that's ok, since i-klingon-klingon
   // is not valid and would fail LANGUAGE_TAG_RE test.
-  var variants = [];
-  var extensions = [];
+  var variants = new InternalArray();
+  var extensions = new InternalArray();
   var parts = %_Call(StringSplit, locale, '-');
   for (var i = 1; i < parts.length; i++) {
     var value = parts[i];
@@ -965,8 +973,8 @@
   // We define all properties C++ code may produce, to prevent security
   // problems. If malicious user decides to redefine Object.prototype.locale
   // we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
-  // ObjectDefineProperties will either succeed defining or throw an error.
-  var resolved = ObjectDefineProperties({}, {
+  // %object_define_properties will either succeed defining or throw an error.
+  var resolved = %object_define_properties({}, {
     caseFirst: {writable: true},
     collation: {value: internalOptions.collation, writable: true},
     ignorePunctuation: {writable: true},
@@ -985,7 +993,9 @@
   // Writable, configurable and enumerable are set to false by default.
   %MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
   collator[resolvedSymbol] = resolved;
-  ObjectDefineProperty(collator, 'resolved', resolvedAccessor);
+  if (FLAG_intl_extra) {
+    %object_define_property(collator, 'resolved', resolvedAccessor);
+  }
 
   return collator;
 }
@@ -1072,7 +1082,7 @@
 };
 
 
-AddBoundMethod(Intl.Collator, 'compare', compare, 2);
+AddBoundMethod(Intl.Collator, 'compare', compare, 2, 'collator');
 
 /**
  * Verifies that the input is a well-formed ISO 4217 currency code.
@@ -1198,7 +1208,7 @@
                              getOption, internalOptions);
 
   var requestedLocale = locale.locale + extension;
-  var resolved = ObjectDefineProperties({}, {
+  var resolved = %object_define_properties({}, {
     currency: {writable: true},
     currencyDisplay: {writable: true},
     locale: {writable: true},
@@ -1206,7 +1216,6 @@
     minimumFractionDigits: {writable: true},
     minimumIntegerDigits: {writable: true},
     numberingSystem: {writable: true},
-    pattern: patternAccessor,
     requestedLocale: {value: requestedLocale, writable: true},
     style: {value: internalOptions.style, writable: true},
     useGrouping: {writable: true}
@@ -1222,13 +1231,16 @@
                                       resolved);
 
   if (internalOptions.style === 'currency') {
-    ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
-                                                       writable: true});
+    %object_define_property(resolved, 'currencyDisplay',
+        {value: currencyDisplay, writable: true});
   }
 
   %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
   numberFormat[resolvedSymbol] = resolved;
-  ObjectDefineProperty(numberFormat, 'resolved', resolvedAccessor);
+  if (FLAG_intl_extra) {
+    %object_define_property(resolved, 'pattern', patternAccessor);
+    %object_define_property(numberFormat, 'resolved', resolvedAccessor);
+  }
 
   return numberFormat;
 }
@@ -1334,14 +1346,12 @@
 /**
  * Returns a Number that represents string value that was passed in.
  */
-function parseNumber(formatter, value) {
+function IntlParseNumber(formatter, value) {
   return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
                               GlobalString(value));
 }
 
-
-AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
-AddBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
+AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1, 'numberformat');
 
 /**
  * Returns a string that matches LDML representation of the options object.
@@ -1508,33 +1518,33 @@
   }
 
   if (needsDefault && (defaults === 'date' || defaults === 'all')) {
-    ObjectDefineProperty(options, 'year', {value: 'numeric',
-                                           writable: true,
-                                           enumerable: true,
-                                           configurable: true});
-    ObjectDefineProperty(options, 'month', {value: 'numeric',
-                                            writable: true,
-                                            enumerable: true,
-                                            configurable: true});
-    ObjectDefineProperty(options, 'day', {value: 'numeric',
-                                          writable: true,
-                                          enumerable: true,
-                                          configurable: true});
+    %object_define_property(options, 'year', {value: 'numeric',
+                                              writable: true,
+                                              enumerable: true,
+                                              configurable: true});
+    %object_define_property(options, 'month', {value: 'numeric',
+                                               writable: true,
+                                               enumerable: true,
+                                               configurable: true});
+    %object_define_property(options, 'day', {value: 'numeric',
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
   }
 
   if (needsDefault && (defaults === 'time' || defaults === 'all')) {
-    ObjectDefineProperty(options, 'hour', {value: 'numeric',
-                                           writable: true,
-                                           enumerable: true,
-                                           configurable: true});
-    ObjectDefineProperty(options, 'minute', {value: 'numeric',
-                                             writable: true,
-                                             enumerable: true,
-                                             configurable: true});
-    ObjectDefineProperty(options, 'second', {value: 'numeric',
-                                             writable: true,
-                                             enumerable: true,
-                                             configurable: true});
+    %object_define_property(options, 'hour', {value: 'numeric',
+                                              writable: true,
+                                              enumerable: true,
+                                              configurable: true});
+    %object_define_property(options, 'minute', {value: 'numeric',
+                                                writable: true,
+                                                enumerable: true,
+                                                configurable: true});
+    %object_define_property(options, 'second', {value: 'numeric',
+                                                writable: true,
+                                                enumerable: true,
+                                                configurable: true});
   }
 
   return options;
@@ -1592,7 +1602,7 @@
                              getOption, internalOptions);
 
   var requestedLocale = locale.locale + extension;
-  var resolved = ObjectDefineProperties({}, {
+  var resolved = %object_define_properties({}, {
     calendar: {writable: true},
     day: {writable: true},
     era: {writable: true},
@@ -1603,7 +1613,6 @@
     month: {writable: true},
     numberingSystem: {writable: true},
     [patternSymbol]: {writable: true},
-    pattern: patternAccessor,
     requestedLocale: {value: requestedLocale, writable: true},
     second: {writable: true},
     timeZone: {writable: true},
@@ -1622,7 +1631,10 @@
 
   %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
   dateFormat[resolvedSymbol] = resolved;
-  ObjectDefineProperty(dateFormat, 'resolved', resolvedAccessor);
+  if (FLAG_intl_extra) {
+    %object_define_property(resolved, 'pattern', patternAccessor);
+    %object_define_property(dateFormat, 'resolved', resolvedAccessor);
+  }
 
   return dateFormat;
 }
@@ -1756,15 +1768,14 @@
  * DateTimeFormat.
  * Returns undefined if date string cannot be parsed.
  */
-function parseDate(formatter, value) {
+function IntlParseDate(formatter, value) {
   return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
                             GlobalString(value));
 }
 
 
 // 0 because date is optional argument.
-AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
-AddBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
+AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0, 'dateformat');
 
 
 /**
@@ -1826,7 +1837,7 @@
     'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
 
   var locale = resolveLocale('breakiterator', locales, options);
-  var resolved = ObjectDefineProperties({}, {
+  var resolved = %object_define_properties({}, {
     requestedLocale: {value: locale.locale, writable: true},
     type: {value: internalOptions.type, writable: true},
     locale: {writable: true}
@@ -1839,7 +1850,9 @@
   %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
                                      internalIterator);
   iterator[resolvedSymbol] = resolved;
-  ObjectDefineProperty(iterator, 'resolved', resolvedAccessor);
+  if (FLAG_intl_extra) {
+    %object_define_property(iterator, 'resolved', resolvedAccessor);
+  }
 
   return iterator;
 }
@@ -1950,11 +1963,13 @@
 }
 
 
-AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
-AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
+AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1,
+               'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0,
+               'breakiterator');
 
 // Save references to Intl objects and methods we use, for added security.
 var savedObjects = {
@@ -1992,6 +2007,37 @@
   return new savedObjects[service](locales, useOptions);
 }
 
+function LocaleConvertCase(s, locales, isToUpper) {
+  // ECMA 402 section 13.1.2 steps 1 through 12.
+  var language;
+  // Optimize for the most common two cases. initializeLocaleList() can handle
+  // them as well, but it's rather slow accounting for over 60% of
+  // toLocale{U,L}Case() and about 40% of toLocale{U,L}Case("<locale>").
+  if (IS_UNDEFINED(locales)) {
+    language = GetDefaultICULocaleJS();
+  } else if (IS_STRING(locales)) {
+    language = canonicalizeLanguageTag(locales);
+  } else {
+    var locales = initializeLocaleList(locales);
+    language = locales.length > 0 ? locales[0] : GetDefaultICULocaleJS();
+  }
+
+  // StringSplit is slower than this.
+  var pos = %_Call(StringIndexOf, language, '-');
+  if (pos != -1) {
+    language = %_Call(StringSubstring, language, 0, pos);
+  }
+
+  var CUSTOM_CASE_LANGUAGES = ['az', 'el', 'lt', 'tr'];
+  var langIndex = %_Call(ArrayIndexOf, CUSTOM_CASE_LANGUAGES, language);
+  if (langIndex == -1) {
+    // language-independent case conversion.
+    return isToUpper ? %StringToUpperCaseI18N(s) : %StringToLowerCaseI18N(s);
+  }
+  return %StringLocaleConvertCase(s, isToUpper,
+                                  CUSTOM_CASE_LANGUAGES[langIndex]);
+}
+
 /**
  * Compares this and that, and returns less than 0, 0 or greater than 0 value.
  * Overrides the built-in method.
@@ -2044,6 +2090,56 @@
   }
 );
 
+function ToLowerCaseI18N() {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+  }
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
+  var s = TO_STRING(this);
+  return %StringToLowerCaseI18N(s);
+}
+
+function ToUpperCaseI18N() {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+  }
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toUpperCase");
+  var s = TO_STRING(this);
+  return %StringToUpperCaseI18N(s);
+}
+
+function ToLocaleLowerCaseI18N(locales) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+  }
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleLowerCase");
+  return LocaleConvertCase(TO_STRING(this), locales, false);
+}
+
+%FunctionSetLength(ToLocaleLowerCaseI18N, 0);
+
+function ToLocaleUpperCaseI18N(locales) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+  }
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleUpperCase");
+  return LocaleConvertCase(TO_STRING(this), locales, true);
+}
+
+%FunctionSetLength(ToLocaleUpperCaseI18N, 0);
+
+%FunctionRemovePrototype(ToLowerCaseI18N);
+%FunctionRemovePrototype(ToUpperCaseI18N);
+%FunctionRemovePrototype(ToLocaleLowerCaseI18N);
+%FunctionRemovePrototype(ToLocaleUpperCaseI18N);
+
+utils.Export(function(to) {
+  to.ToLowerCaseI18N = ToLowerCaseI18N;
+  to.ToUpperCaseI18N = ToUpperCaseI18N;
+  to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
+  to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
+});
+
 
 /**
  * Formats a Number object (this) using locale and options values.
@@ -2138,4 +2234,10 @@
   }
 );
 
+utils.Export(function(to) {
+  to.AddBoundMethod = AddBoundMethod;
+  to.IntlParseDate = IntlParseDate;
+  to.IntlParseNumber = IntlParseNumber;
+});
+
 })
diff --git a/src/js/icu-case-mapping.js b/src/js/icu-case-mapping.js
new file mode 100644
index 0000000..9806249
--- /dev/null
+++ b/src/js/icu-case-mapping.js
@@ -0,0 +1,24 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalString = global.String;
+var OverrideFunction = utils.OverrideFunction;
+var ToLowerCaseI18N = utils.ImportNow("ToLowerCaseI18N");
+var ToUpperCaseI18N = utils.ImportNow("ToUpperCaseI18N");
+var ToLocaleLowerCaseI18N = utils.ImportNow("ToLocaleLowerCaseI18N");
+var ToLocaleUpperCaseI18N = utils.ImportNow("ToLocaleUpperCaseI18N");
+
+OverrideFunction(GlobalString.prototype, 'toLowerCase', ToLowerCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toUpperCase', ToUpperCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toLocaleLowerCase',
+                 ToLocaleLowerCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toLocaleUpperCase',
+                 ToLocaleUpperCaseI18N, true);
+
+})
diff --git a/src/js/intl-extra.js b/src/js/intl-extra.js
new file mode 100644
index 0000000..a4d2256
--- /dev/null
+++ b/src/js/intl-extra.js
@@ -0,0 +1,22 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalIntl = global.Intl;
+
+var AddBoundMethod = utils.ImportNow("AddBoundMethod");
+var IntlParseDate = utils.ImportNow("IntlParseDate");
+var IntlParseNumber = utils.ImportNow("IntlParseNumber");
+
+AddBoundMethod(GlobalIntl.DateTimeFormat, 'v8Parse', IntlParseDate, 1,
+               'dateformat');
+AddBoundMethod(GlobalIntl.NumberFormat, 'v8Parse', IntlParseNumber, 1,
+               'numberformat');
+
+})
diff --git a/src/js/macros.py b/src/js/macros.py
index a4c7f53..3cc2d6c 100644
--- a/src/js/macros.py
+++ b/src/js/macros.py
@@ -113,6 +113,7 @@
 macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(arg));
 macro TO_INT32(arg) = ((arg) | 0);
 macro TO_UINT32(arg) = ((arg) >>> 0);
+macro INVERT_NEG_ZERO(arg) = ((arg) + 0);
 macro TO_LENGTH(arg) = (%_ToLength(arg));
 macro TO_STRING(arg) = (%_ToString(arg));
 macro TO_NUMBER(arg) = (%_ToNumber(arg));
@@ -174,16 +175,6 @@
 # 1-based so index of 1 returns the first capture
 macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]);
 
-# PropertyDescriptor return value indices - must match
-# PropertyDescriptorIndices in runtime-object.cc.
-define IS_ACCESSOR_INDEX = 0;
-define VALUE_INDEX = 1;
-define GETTER_INDEX = 2;
-define SETTER_INDEX = 3;
-define WRITABLE_INDEX = 4;
-define ENUMERABLE_INDEX = 5;
-define CONFIGURABLE_INDEX = 6;
-
 # For messages.js
 # Matches Script::Type from objects.h
 define TYPE_NATIVE = 0;
@@ -238,7 +229,6 @@
 
 # Check whether debug is active.
 define DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
-macro DEBUG_PREPARE_STEP_IN_IF_STEPPING(function) = if (%_DebugIsActive() != 0) %DebugPrepareStepInIfStepping(function);
 
 # SharedFlag equivalents
 define kNotShared = false;
@@ -251,7 +241,6 @@
 define kMarkDequeOverflow = 3;
 define kStoreBufferOverflow = 4;
 define kSlotsBufferOverflow = 5;
-define kObjectObserve = 6;
 define kForcedGC = 7;
 define kSloppyMode = 8;
 define kStrictMode = 9;
diff --git a/src/js/messages.js b/src/js/messages.js
index f8cb967..b5c4b56 100644
--- a/src/js/messages.js
+++ b/src/js/messages.js
@@ -23,6 +23,10 @@
     utils.ImportNow("call_site_position_symbol");
 var callSiteStrictSymbol =
     utils.ImportNow("call_site_strict_symbol");
+var callSiteWasmObjectSymbol =
+    utils.ImportNow("call_site_wasm_obj_symbol");
+var callSiteWasmFunctionIndexSymbol =
+    utils.ImportNow("call_site_wasm_func_index_symbol");
 var Float32x4ToString;
 var formattedStackTraceSymbol =
     utils.ImportNow("formatted_stack_trace_symbol");
@@ -32,12 +36,10 @@
 var Int8x16ToString;
 var InternalArray = utils.InternalArray;
 var internalErrorSymbol = utils.ImportNow("internal_error_symbol");
-var ObjectDefineProperty;
 var ObjectHasOwnProperty;
 var ObjectToString = utils.ImportNow("object_to_string");
 var Script = utils.ImportNow("Script");
 var stackTraceSymbol = utils.ImportNow("stack_trace_symbol");
-var StringCharAt;
 var StringIndexOf;
 var StringSubstring;
 var SymbolToString;
@@ -55,9 +57,7 @@
   Int16x8ToString = from.Int16x8ToString;
   Int32x4ToString = from.Int32x4ToString;
   Int8x16ToString = from.Int8x16ToString;
-  ObjectDefineProperty = from.ObjectDefineProperty;
   ObjectHasOwnProperty = from.ObjectHasOwnProperty;
-  StringCharAt = from.StringCharAt;
   StringIndexOf = from.StringIndexOf;
   StringSubstring = from.StringSubstring;
   SymbolToString = from.SymbolToString;
@@ -255,6 +255,7 @@
   return -1;
 }
 
+
 /**
  * Get information on a specific source position.
  * @param {number} position The source position
@@ -272,7 +273,7 @@
   var line_ends = this.line_ends;
   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
   var end = line_ends[line];
-  if (end > 0 && %_Call(StringCharAt, this.source, end - 1) == '\r') {
+  if (end > 0 && %_StringCharAt(this.source, end - 1) === '\r') {
     end--;
   }
   var column = position - start;
@@ -556,7 +557,9 @@
 // Error implementation
 
 function CallSite(receiver, fun, pos, strict_mode) {
-  if (!IS_FUNCTION(fun)) {
+  // For wasm frames, receiver is the wasm object and fun is the function index
+  // instead of an actual function.
+  if (!IS_FUNCTION(fun) && !IS_NUMBER(fun)) {
     throw MakeTypeError(kCallSiteExpectsFunction, typeof fun);
   }
 
@@ -564,14 +567,19 @@
     return new CallSite(receiver, fun, pos, strict_mode);
   }
 
-  SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
-  SET_PRIVATE(this, callSiteFunctionSymbol, fun);
+  if (IS_FUNCTION(fun)) {
+    SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
+    SET_PRIVATE(this, callSiteFunctionSymbol, fun);
+  } else {
+    SET_PRIVATE(this, callSiteWasmObjectSymbol, receiver);
+    SET_PRIVATE(this, callSiteWasmFunctionIndexSymbol, TO_UINT32(fun));
+  }
   SET_PRIVATE(this, callSitePositionSymbol, TO_INT32(pos));
   SET_PRIVATE(this, callSiteStrictSymbol, TO_BOOLEAN(strict_mode));
 }
 
 function CheckCallSite(obj, name) {
-  if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSiteFunctionSymbol)) {
+  if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSitePositionSymbol)) {
     throw MakeTypeError(kCallSiteMethod, name);
   }
 }
@@ -622,6 +630,12 @@
 function CallSiteGetFunctionName() {
   // See if the function knows its own name
   CheckCallSite(this, "getFunctionName");
+  if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+    var wasm = GET_PRIVATE(this, callSiteWasmObjectSymbol);
+    var func_index = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+    if (IS_UNDEFINED(wasm)) return "<WASM>";
+    return %WasmGetFunctionName(wasm, func_index);
+  }
   return %CallSiteGetFunctionNameRT(this);
 }
 
@@ -638,6 +652,9 @@
 }
 
 function CallSiteGetLineNumber() {
+  if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+    return GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+  }
   CheckCallSite(this, "getLineNumber");
   return %CallSiteGetLineNumberRT(this);
 }
@@ -658,6 +675,13 @@
 }
 
 function CallSiteToString() {
+  if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+    var funName = this.getFunctionName();
+    var funcIndex = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+    var pos = this.getPosition();
+    return funName + " (<WASM>:" + funcIndex + ":" + pos + ")";
+  }
+
   var fileName;
   var fileLocation = "";
   if (this.isNative()) {
@@ -795,14 +819,19 @@
 
 
 function GetStackFrames(raw_stack) {
+  var internal_raw_stack = new InternalArray();
+  %MoveArrayContents(raw_stack, internal_raw_stack);
   var frames = new InternalArray();
-  var sloppy_frames = raw_stack[0];
-  for (var i = 1; i < raw_stack.length; i += 4) {
-    var recv = raw_stack[i];
-    var fun = raw_stack[i + 1];
-    var code = raw_stack[i + 2];
-    var pc = raw_stack[i + 3];
-    var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
+  var sloppy_frames = internal_raw_stack[0];
+  for (var i = 1; i < internal_raw_stack.length; i += 4) {
+    var recv = internal_raw_stack[i];
+    var fun = internal_raw_stack[i + 1];
+    var code = internal_raw_stack[i + 2];
+    var pc = internal_raw_stack[i + 3];
+    // For traps in wasm, the bytecode offset is passed as (-1 - offset).
+    // Otherwise, lookup the position from the pc.
+    var pos = IS_NUMBER(fun) && pc < 0 ? (-1 - pc) :
+      %FunctionGetPositionForOffset(code, pc);
     sloppy_frames--;
     frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
   }
@@ -879,7 +908,7 @@
       if (IS_UNDEFINED(stack_trace)) {
         // Neither formatted nor structured stack trace available.
         // Look further up the prototype chain.
-        holder = %_GetPrototype(holder);
+        holder = %object_get_prototype_of(holder);
         continue;
       }
       formatted_stack_trace = FormatStackTrace(holder, stack_trace);
@@ -995,9 +1024,9 @@
 // Define actual captureStackTrace function after everything has been set up.
 captureStackTrace = function captureStackTrace(obj, cons_opt) {
   // Define accessors first, as this may fail and throw.
-  ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
-                                       set: StackTraceSetter,
-                                       configurable: true });
+  %object_define_property(obj, 'stack', { get: StackTraceGetter,
+                                          set: StackTraceSetter,
+                                          configurable: true });
   %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
 };
 
diff --git a/src/js/object-observe.js b/src/js/object-observe.js
deleted file mode 100644
index 5e256bf..0000000
--- a/src/js/object-observe.js
+++ /dev/null
@@ -1,717 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-// -------------------------------------------------------------------
-// Imports
-
-var GetHash;
-var GlobalArray = global.Array;
-var GlobalObject = global.Object;
-var InternalArray = utils.InternalArray;
-var MakeTypeError;
-
-utils.Import(function(from) {
-  GetHash = from.GetHash;
-  MakeTypeError = from.MakeTypeError;
-});
-
-// -------------------------------------------------------------------
-
-// Overview:
-//
-// This file contains all of the routing and accounting for Object.observe.
-// User code will interact with these mechanisms via the Object.observe APIs
-// and, as a side effect of mutation objects which are observed. The V8 runtime
-// (both C++ and JS) will interact with these mechanisms primarily by enqueuing
-// proper change records for objects which were mutated. The Object.observe
-// routing and accounting consists primarily of three participants
-//
-// 1) ObjectInfo. This represents the observed state of a given object. It
-//    records what callbacks are observing the object, with what options, and
-//    what "change types" are in progress on the object (i.e. via
-//    notifier.performChange).
-//
-// 2) CallbackInfo. This represents a callback used for observation. It holds
-//    the records which must be delivered to the callback, as well as the global
-//    priority of the callback (which determines delivery order between
-//    callbacks).
-//
-// 3) observationState.pendingObservers. This is the set of observers which
-//    have change records which must be delivered. During "normal" delivery
-//    (i.e. not Object.deliverChangeRecords), this is the mechanism by which
-//    callbacks are invoked in the proper order until there are no more
-//    change records pending to a callback.
-//
-// Note that in order to reduce allocation and processing costs, the
-// implementation of (1) and (2) have "optimized" states which represent
-// common cases which can be handled more efficiently.
-
-var observationState;
-
-var notifierPrototype = {};
-
-// We have to wait until after bootstrapping to grab a reference to the
-// observationState object, since it's not possible to serialize that
-// reference into the snapshot.
-function GetObservationStateJS() {
-  if (IS_UNDEFINED(observationState)) {
-    observationState = %GetObservationState();
-  }
-
-  // TODO(adamk): Consider moving this code into heap.cc
-  if (IS_UNDEFINED(observationState.callbackInfoMap)) {
-    observationState.callbackInfoMap = %ObservationWeakMapCreate();
-    observationState.objectInfoMap = %ObservationWeakMapCreate();
-    observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
-    observationState.pendingObservers = null;
-    observationState.nextCallbackPriority = 0;
-    observationState.lastMicrotaskId = 0;
-  }
-
-  return observationState;
-}
-
-
-function GetPendingObservers() {
-  return GetObservationStateJS().pendingObservers;
-}
-
-
-function SetPendingObservers(pendingObservers) {
-  GetObservationStateJS().pendingObservers = pendingObservers;
-}
-
-
-function GetNextCallbackPriority() {
-  return GetObservationStateJS().nextCallbackPriority++;
-}
-
-
-function nullProtoObject() {
-  return { __proto__: null };
-}
-
-
-function TypeMapCreate() {
-  return nullProtoObject();
-}
-
-
-function TypeMapAddType(typeMap, type, ignoreDuplicate) {
-  typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1;
-}
-
-
-function TypeMapRemoveType(typeMap, type) {
-  typeMap[type]--;
-}
-
-
-function TypeMapCreateFromList(typeList, length) {
-  var typeMap = TypeMapCreate();
-  for (var i = 0; i < length; i++) {
-    TypeMapAddType(typeMap, typeList[i], true);
-  }
-  return typeMap;
-}
-
-
-function TypeMapHasType(typeMap, type) {
-  return !!typeMap[type];
-}
-
-
-function TypeMapIsDisjointFrom(typeMap1, typeMap2) {
-  if (!typeMap1 || !typeMap2)
-    return true;
-
-  for (var type in typeMap1) {
-    if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type))
-      return false;
-  }
-
-  return true;
-}
-
-
-var defaultAcceptTypes = (function() {
-  var defaultTypes = [
-    'add',
-    'update',
-    'delete',
-    'setPrototype',
-    'reconfigure',
-    'preventExtensions'
-  ];
-  return TypeMapCreateFromList(defaultTypes, defaultTypes.length);
-})();
-
-
-// An Observer is a registration to observe an object by a callback with
-// a given set of accept types. If the set of accept types is the default
-// set for Object.observe, the observer is represented as a direct reference
-// to the callback. An observer never changes its accept types and thus never
-// needs to "normalize".
-function ObserverCreate(callback, acceptList) {
-  if (IS_UNDEFINED(acceptList))
-    return callback;
-  var observer = nullProtoObject();
-  observer.callback = callback;
-  observer.accept = acceptList;
-  return observer;
-}
-
-
-function ObserverGetCallback(observer) {
-  return IS_CALLABLE(observer) ? observer : observer.callback;
-}
-
-
-function ObserverGetAcceptTypes(observer) {
-  return IS_CALLABLE(observer) ? defaultAcceptTypes : observer.accept;
-}
-
-
-function ObserverIsActive(observer, objectInfo) {
-  return TypeMapIsDisjointFrom(ObjectInfoGetPerformingTypes(objectInfo),
-                               ObserverGetAcceptTypes(observer));
-}
-
-
-function ObjectInfoGetOrCreate(object) {
-  var objectInfo = ObjectInfoGet(object);
-  if (IS_UNDEFINED(objectInfo)) {
-    if (!IS_PROXY(object)) {
-      %SetIsObserved(object);
-    }
-    objectInfo = {
-      object: object,
-      changeObservers: null,
-      notifier: null,
-      performing: null,
-      performingCount: 0,
-    };
-    %WeakCollectionSet(GetObservationStateJS().objectInfoMap,
-                       object, objectInfo, GetHash(object));
-  }
-  return objectInfo;
-}
-
-
-function ObjectInfoGet(object) {
-  return %WeakCollectionGet(GetObservationStateJS().objectInfoMap, object,
-                            GetHash(object));
-}
-
-
-function ObjectInfoGetFromNotifier(notifier) {
-  return %WeakCollectionGet(GetObservationStateJS().notifierObjectInfoMap,
-                            notifier, GetHash(notifier));
-}
-
-
-function ObjectInfoGetNotifier(objectInfo) {
-  if (IS_NULL(objectInfo.notifier)) {
-    var notifier = { __proto__: notifierPrototype };
-    objectInfo.notifier = notifier;
-    %WeakCollectionSet(GetObservationStateJS().notifierObjectInfoMap,
-                       notifier, objectInfo, GetHash(notifier));
-  }
-
-  return objectInfo.notifier;
-}
-
-
-function ChangeObserversIsOptimized(changeObservers) {
-  return IS_CALLABLE(changeObservers) ||
-         IS_CALLABLE(changeObservers.callback);
-}
-
-
-// The set of observers on an object is called 'changeObservers'. The first
-// observer is referenced directly via objectInfo.changeObservers. When a second
-// is added, changeObservers "normalizes" to become a mapping of callback
-// priority -> observer and is then stored on objectInfo.changeObservers.
-function ObjectInfoNormalizeChangeObservers(objectInfo) {
-  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
-    var observer = objectInfo.changeObservers;
-    var callback = ObserverGetCallback(observer);
-    var callbackInfo = CallbackInfoGet(callback);
-    var priority = CallbackInfoGetPriority(callbackInfo);
-    objectInfo.changeObservers = nullProtoObject();
-    objectInfo.changeObservers[priority] = observer;
-  }
-}
-
-
-function ObjectInfoAddObserver(objectInfo, callback, acceptList) {
-  var callbackInfo = CallbackInfoGetOrCreate(callback);
-  var observer = ObserverCreate(callback, acceptList);
-
-  if (!objectInfo.changeObservers) {
-    objectInfo.changeObservers = observer;
-    return;
-  }
-
-  ObjectInfoNormalizeChangeObservers(objectInfo);
-  var priority = CallbackInfoGetPriority(callbackInfo);
-  objectInfo.changeObservers[priority] = observer;
-}
-
-function ObjectInfoRemoveObserver(objectInfo, callback) {
-  if (!objectInfo.changeObservers)
-    return;
-
-  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
-    if (callback === ObserverGetCallback(objectInfo.changeObservers))
-      objectInfo.changeObservers = null;
-    return;
-  }
-
-  var callbackInfo = CallbackInfoGet(callback);
-  var priority = CallbackInfoGetPriority(callbackInfo);
-  objectInfo.changeObservers[priority] = null;
-}
-
-function ObjectInfoHasActiveObservers(objectInfo) {
-  if (IS_UNDEFINED(objectInfo) || !objectInfo.changeObservers)
-    return false;
-
-  if (ChangeObserversIsOptimized(objectInfo.changeObservers))
-    return ObserverIsActive(objectInfo.changeObservers, objectInfo);
-
-  for (var priority in objectInfo.changeObservers) {
-    var observer = objectInfo.changeObservers[priority];
-    if (!IS_NULL(observer) && ObserverIsActive(observer, objectInfo))
-      return true;
-  }
-
-  return false;
-}
-
-
-function ObjectInfoAddPerformingType(objectInfo, type) {
-  objectInfo.performing = objectInfo.performing || TypeMapCreate();
-  TypeMapAddType(objectInfo.performing, type);
-  objectInfo.performingCount++;
-}
-
-
-function ObjectInfoRemovePerformingType(objectInfo, type) {
-  objectInfo.performingCount--;
-  TypeMapRemoveType(objectInfo.performing, type);
-}
-
-
-function ObjectInfoGetPerformingTypes(objectInfo) {
-  return objectInfo.performingCount > 0 ? objectInfo.performing : null;
-}
-
-
-function ConvertAcceptListToTypeMap(arg) {
-  // We use undefined as a sentinel for the default accept list.
-  if (IS_UNDEFINED(arg))
-    return arg;
-
-  if (!IS_RECEIVER(arg)) throw MakeTypeError(kObserveInvalidAccept);
-
-  var len = TO_INTEGER(arg.length);
-  if (len < 0) len = 0;
-
-  return TypeMapCreateFromList(arg, len);
-}
-
-
-// CallbackInfo's optimized state is just a number which represents its global
-// priority. When a change record must be enqueued for the callback, it
-// normalizes. When delivery clears any pending change records, it re-optimizes.
-function CallbackInfoGet(callback) {
-  return %WeakCollectionGet(GetObservationStateJS().callbackInfoMap, callback,
-                            GetHash(callback));
-}
-
-
-function CallbackInfoSet(callback, callbackInfo) {
-  %WeakCollectionSet(GetObservationStateJS().callbackInfoMap,
-                     callback, callbackInfo, GetHash(callback));
-}
-
-
-function CallbackInfoGetOrCreate(callback) {
-  var callbackInfo = CallbackInfoGet(callback);
-  if (!IS_UNDEFINED(callbackInfo))
-    return callbackInfo;
-
-  var priority = GetNextCallbackPriority();
-  CallbackInfoSet(callback, priority);
-  return priority;
-}
-
-
-function CallbackInfoGetPriority(callbackInfo) {
-  if (IS_NUMBER(callbackInfo))
-    return callbackInfo;
-  else
-    return callbackInfo.priority;
-}
-
-
-function CallbackInfoNormalize(callback) {
-  var callbackInfo = CallbackInfoGet(callback);
-  if (IS_NUMBER(callbackInfo)) {
-    var priority = callbackInfo;
-    callbackInfo = new InternalArray;
-    callbackInfo.priority = priority;
-    CallbackInfoSet(callback, callbackInfo);
-  }
-  return callbackInfo;
-}
-
-
-function ObjectObserve(object, callback, acceptList) {
-  if (!IS_RECEIVER(object))
-    throw MakeTypeError(kObserveNonObject, "observe", "observe");
-  if (%IsJSGlobalProxy(object))
-    throw MakeTypeError(kObserveGlobalProxy, "observe");
-  if (%IsAccessCheckNeeded(object))
-    throw MakeTypeError(kObserveAccessChecked, "observe");
-  if (!IS_CALLABLE(callback))
-    throw MakeTypeError(kObserveNonFunction, "observe");
-  if (%object_is_frozen(callback))
-    throw MakeTypeError(kObserveCallbackFrozen);
-
-  var objectObserveFn = %GetObjectContextObjectObserve(object);
-  return objectObserveFn(object, callback, acceptList);
-}
-
-
-function NativeObjectObserve(object, callback, acceptList) {
-  var objectInfo = ObjectInfoGetOrCreate(object);
-  var typeList = ConvertAcceptListToTypeMap(acceptList);
-  ObjectInfoAddObserver(objectInfo, callback, typeList);
-  return object;
-}
-
-
-function ObjectUnobserve(object, callback) {
-  if (!IS_RECEIVER(object))
-    throw MakeTypeError(kObserveNonObject, "unobserve", "unobserve");
-  if (%IsJSGlobalProxy(object))
-    throw MakeTypeError(kObserveGlobalProxy, "unobserve");
-  if (!IS_CALLABLE(callback))
-    throw MakeTypeError(kObserveNonFunction, "unobserve");
-
-  var objectInfo = ObjectInfoGet(object);
-  if (IS_UNDEFINED(objectInfo))
-    return object;
-
-  ObjectInfoRemoveObserver(objectInfo, callback);
-  return object;
-}
-
-
-function ArrayObserve(object, callback) {
-  return ObjectObserve(object, callback, ['add',
-                                          'update',
-                                          'delete',
-                                          'splice']);
-}
-
-
-function ArrayUnobserve(object, callback) {
-  return ObjectUnobserve(object, callback);
-}
-
-
-function ObserverEnqueueIfActive(observer, objectInfo, changeRecord) {
-  if (!ObserverIsActive(observer, objectInfo) ||
-      !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) {
-    return;
-  }
-
-  var callback = ObserverGetCallback(observer);
-  if (!%ObserverObjectAndRecordHaveSameOrigin(callback, changeRecord.object,
-                                              changeRecord)) {
-    return;
-  }
-
-  var callbackInfo = CallbackInfoNormalize(callback);
-  if (IS_NULL(GetPendingObservers())) {
-    SetPendingObservers(nullProtoObject());
-    if (DEBUG_IS_ACTIVE) {
-      var id = ++GetObservationStateJS().lastMicrotaskId;
-      var name = "Object.observe";
-      %EnqueueMicrotask(function() {
-        %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
-        ObserveMicrotaskRunner();
-        %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
-      });
-      %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
-    } else {
-      %EnqueueMicrotask(ObserveMicrotaskRunner);
-    }
-  }
-  GetPendingObservers()[callbackInfo.priority] = callback;
-  callbackInfo.push(changeRecord);
-}
-
-
-function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
-  if (!ObjectInfoHasActiveObservers(objectInfo))
-    return;
-
-  var hasType = !IS_UNDEFINED(type);
-  var newRecord = hasType ?
-      { object: objectInfo.object, type: type } :
-      { object: objectInfo.object };
-
-  for (var prop in changeRecord) {
-    if (prop === 'object' || (hasType && prop === 'type')) continue;
-    %DefineDataPropertyUnchecked(
-        newRecord, prop, changeRecord[prop], READ_ONLY + DONT_DELETE);
-  }
-  %object_freeze(newRecord);
-
-  ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord);
-}
-
-
-function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) {
-  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
-  if (IS_SYMBOL(changeRecord.name)) return;
-
-  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
-    var observer = objectInfo.changeObservers;
-    ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
-    return;
-  }
-
-  for (var priority in objectInfo.changeObservers) {
-    var observer = objectInfo.changeObservers[priority];
-    if (IS_NULL(observer))
-      continue;
-    ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
-  }
-}
-
-
-function BeginPerformSplice(array) {
-  var objectInfo = ObjectInfoGet(array);
-  if (!IS_UNDEFINED(objectInfo))
-    ObjectInfoAddPerformingType(objectInfo, 'splice');
-}
-
-
-function EndPerformSplice(array) {
-  var objectInfo = ObjectInfoGet(array);
-  if (!IS_UNDEFINED(objectInfo))
-    ObjectInfoRemovePerformingType(objectInfo, 'splice');
-}
-
-
-function EnqueueSpliceRecord(array, index, removed, addedCount) {
-  var objectInfo = ObjectInfoGet(array);
-  if (!ObjectInfoHasActiveObservers(objectInfo))
-    return;
-
-  var changeRecord = {
-    type: 'splice',
-    object: array,
-    index: index,
-    removed: removed,
-    addedCount: addedCount
-  };
-
-  %object_freeze(changeRecord);
-  %object_freeze(changeRecord.removed);
-  ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function NotifyChange(type, object, name, oldValue) {
-  var objectInfo = ObjectInfoGet(object);
-  if (!ObjectInfoHasActiveObservers(objectInfo))
-    return;
-
-  var changeRecord;
-  if (arguments.length == 2) {
-    changeRecord = { type: type, object: object };
-  } else if (arguments.length == 3) {
-    changeRecord = { type: type, object: object, name: name };
-  } else {
-    changeRecord = {
-      type: type,
-      object: object,
-      name: name,
-      oldValue: oldValue
-    };
-  }
-
-  %object_freeze(changeRecord);
-  ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function ObjectNotifierNotify(changeRecord) {
-  if (!IS_RECEIVER(this))
-    throw MakeTypeError(kCalledOnNonObject, "notify");
-
-  var objectInfo = ObjectInfoGetFromNotifier(this);
-  if (IS_UNDEFINED(objectInfo))
-    throw MakeTypeError(kObserveNotifyNonNotifier);
-  if (!IS_STRING(changeRecord.type))
-    throw MakeTypeError(kObserveTypeNonString);
-
-  ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function ObjectNotifierPerformChange(changeType, changeFn) {
-  if (!IS_RECEIVER(this))
-    throw MakeTypeError(kCalledOnNonObject, "performChange");
-
-  var objectInfo = ObjectInfoGetFromNotifier(this);
-  if (IS_UNDEFINED(objectInfo))
-    throw MakeTypeError(kObserveNotifyNonNotifier);
-  if (!IS_STRING(changeType))
-    throw MakeTypeError(kObservePerformNonString);
-  if (!IS_CALLABLE(changeFn))
-    throw MakeTypeError(kObservePerformNonFunction);
-
-  var performChangeFn = %GetObjectContextNotifierPerformChange(objectInfo);
-  performChangeFn(objectInfo, changeType, changeFn);
-}
-
-
-function NativeObjectNotifierPerformChange(objectInfo, changeType, changeFn) {
-  ObjectInfoAddPerformingType(objectInfo, changeType);
-
-  var changeRecord;
-  try {
-    changeRecord = changeFn();
-  } finally {
-    ObjectInfoRemovePerformingType(objectInfo, changeType);
-  }
-
-  if (IS_RECEIVER(changeRecord))
-    ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
-}
-
-
-function ObjectGetNotifier(object) {
-  if (!IS_RECEIVER(object))
-    throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier");
-  if (%IsJSGlobalProxy(object))
-    throw MakeTypeError(kObserveGlobalProxy, "getNotifier");
-  if (%IsAccessCheckNeeded(object))
-    throw MakeTypeError(kObserveAccessChecked, "getNotifier");
-
-  if (%object_is_frozen(object)) return null;
-
-  if (!%ObjectWasCreatedInCurrentOrigin(object)) return null;
-
-  var getNotifierFn = %GetObjectContextObjectGetNotifier(object);
-  return getNotifierFn(object);
-}
-
-
-function NativeObjectGetNotifier(object) {
-  var objectInfo = ObjectInfoGetOrCreate(object);
-  return ObjectInfoGetNotifier(objectInfo);
-}
-
-
-function CallbackDeliverPending(callback) {
-  var callbackInfo = CallbackInfoGet(callback);
-  if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
-    return false;
-
-  // Clear the pending change records from callback and return it to its
-  // "optimized" state.
-  var priority = callbackInfo.priority;
-  CallbackInfoSet(callback, priority);
-
-  var pendingObservers = GetPendingObservers();
-  if (!IS_NULL(pendingObservers))
-    delete pendingObservers[priority];
-
-  // TODO: combine the following runtime calls for perf optimization.
-  var delivered = [];
-  %MoveArrayContents(callbackInfo, delivered);
-  %DeliverObservationChangeRecords(callback, delivered);
-
-  return true;
-}
-
-
-function ObjectDeliverChangeRecords(callback) {
-  if (!IS_CALLABLE(callback))
-    throw MakeTypeError(kObserveNonFunction, "deliverChangeRecords");
-
-  while (CallbackDeliverPending(callback)) {}
-}
-
-
-function ObserveMicrotaskRunner() {
-  var pendingObservers = GetPendingObservers();
-  if (!IS_NULL(pendingObservers)) {
-    SetPendingObservers(null);
-    for (var i in pendingObservers) {
-      CallbackDeliverPending(pendingObservers[i]);
-    }
-  }
-}
-
-// -------------------------------------------------------------------
-
-utils.InstallFunctions(notifierPrototype, DONT_ENUM, [
-  "notify", ObjectNotifierNotify,
-  "performChange", ObjectNotifierPerformChange
-]);
-
-var ObserveObjectMethods = [
-  "deliverChangeRecords", ObjectDeliverChangeRecords,
-  "getNotifier", ObjectGetNotifier,
-  "observe", ObjectObserve,
-  "unobserve", ObjectUnobserve
-];
-
-var ObserveArrayMethods = [
-  "observe", ArrayObserve,
-  "unobserve", ArrayUnobserve
-];
-
-// TODO(adamk): Figure out why this prototype removal has to
-// happen as part of initial snapshotting.
-var removePrototypeFn = function(f, i) {
-  if (i % 2 === 1) %FunctionRemovePrototype(f);
-};
-ObserveObjectMethods.forEach(removePrototypeFn);
-ObserveArrayMethods.forEach(removePrototypeFn);
-
-%InstallToContext([
-  "native_object_get_notifier", NativeObjectGetNotifier,
-  "native_object_notifier_perform_change", NativeObjectNotifierPerformChange,
-  "native_object_observe", NativeObjectObserve,
-  "observers_begin_perform_splice", BeginPerformSplice,
-  "observers_end_perform_splice", EndPerformSplice,
-  "observers_enqueue_splice", EnqueueSpliceRecord,
-  "observers_notify_change", NotifyChange,
-]);
-
-utils.Export(function(to) {
-  to.ObserveArrayMethods = ObserveArrayMethods;
-  to.ObserveBeginPerformSplice = BeginPerformSplice;
-  to.ObserveEndPerformSplice = EndPerformSplice;
-  to.ObserveEnqueueSpliceRecord = EnqueueSpliceRecord;
-  to.ObserveObjectMethods = ObserveObjectMethods;
-});
-
-})
diff --git a/src/js/prologue.js b/src/js/prologue.js
index f9589a5..b352eb1 100644
--- a/src/js/prologue.js
+++ b/src/js/prologue.js
@@ -128,10 +128,10 @@
 
 function OverrideFunction(object, name, f, afterInitialBootstrap) {
   %CheckIsBootstrapping();
-  %ObjectDefineProperty(object, name, { value: f,
-                                        writeable: true,
-                                        configurable: true,
-                                        enumerable: false });
+  %object_define_property(object, name, { value: f,
+                                          writeable: true,
+                                          configurable: true,
+                                          enumerable: false });
   SetFunctionName(f, name);
   if (!afterInitialBootstrap) %FunctionRemovePrototype(f);
   %SetNativeFlag(f);
@@ -181,10 +181,15 @@
 
   // Whitelist of exports from normal natives to experimental natives and debug.
   var expose_list = [
+    "AddBoundMethod",
     "ArrayToString",
+    "AsyncFunctionNext",
+    "AsyncFunctionThrow",
     "ErrorToString",
     "GetIterator",
     "GetMethod",
+    "IntlParseDate",
+    "IntlParseNumber",
     "IsNaN",
     "MakeError",
     "MakeRangeError",
@@ -195,12 +200,12 @@
     "MaxSimple",
     "MinSimple",
     "NumberIsInteger",
-    "ObjectDefineProperty",
-    "ObserveArrayMethods",
-    "ObserveObjectMethods",
     "PromiseChain",
-    "PromiseDeferred",
-    "PromiseResolved",
+    "PromiseDefer",
+    "PromiseAccept",
+    "PromiseCreateRejected",
+    "PromiseCreateResolved",
+    "PromiseThen",
     "RegExpSubclassExecJS",
     "RegExpSubclassMatch",
     "RegExpSubclassReplace",
@@ -211,12 +216,16 @@
     "SetIteratorNext",
     "SetValues",
     "SymbolToString",
+    "ToLocaleLowerCaseI18N",
+    "ToLocaleUpperCaseI18N",
+    "ToLowerCaseI18N",
     "ToPositiveInteger",
+    "ToUpperCaseI18N",
     // From runtime:
     "is_concat_spreadable_symbol",
     "iterator_symbol",
-    "promise_status_symbol",
-    "promise_value_symbol",
+    "promise_result_symbol",
+    "promise_state_symbol",
     "object_freeze",
     "object_is_frozen",
     "object_is_sealed",
diff --git a/src/js/promise-extra.js b/src/js/promise-extra.js
index f6f7959..34d7323 100644
--- a/src/js/promise-extra.js
+++ b/src/js/promise-extra.js
@@ -11,16 +11,16 @@
 var GlobalPromise = global.Promise;
 
 var PromiseChain = utils.ImportNow("PromiseChain");
-var PromiseDeferred = utils.ImportNow("PromiseDeferred");
-var PromiseResolved = utils.ImportNow("PromiseResolved");
+var PromiseDefer = utils.ImportNow("PromiseDefer");
+var PromiseAccept = utils.ImportNow("PromiseAccept");
 
 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
   "chain", PromiseChain,
 ]);
 
 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
-  "defer", PromiseDeferred,
-  "accept", PromiseResolved,
+  "defer", PromiseDefer,
+  "accept", PromiseAccept,
 ]);
 
 })
diff --git a/src/js/promise.js b/src/js/promise.js
index bcf826a..42b772b 100644
--- a/src/js/promise.js
+++ b/src/js/promise.js
@@ -17,12 +17,13 @@
     utils.ImportNow("promise_combined_deferred_symbol");
 var promiseHasHandlerSymbol =
     utils.ImportNow("promise_has_handler_symbol");
-var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol");
-var promiseOnResolveSymbol =
-    utils.ImportNow("promise_on_resolve_symbol");
+var promiseRejectReactionsSymbol =
+    utils.ImportNow("promise_reject_reactions_symbol");
+var promiseFulfillReactionsSymbol =
+    utils.ImportNow("promise_fulfill_reactions_symbol");
 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
-var promiseStatusSymbol = utils.ImportNow("promise_status_symbol");
-var promiseValueSymbol = utils.ImportNow("promise_value_symbol");
+var promiseStateSymbol = utils.ImportNow("promise_state_symbol");
+var promiseResultSymbol = utils.ImportNow("promise_result_symbol");
 var SpeciesConstructor;
 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
 
@@ -33,22 +34,32 @@
 
 // -------------------------------------------------------------------
 
-// Status values: 0 = pending, +1 = resolved, -1 = rejected
+// [[PromiseState]] values:
+const kPending = 0;
+const kFulfilled = +1;
+const kRejected = -1;
+
 var lastMicrotaskId = 0;
 
+// ES#sec-createresolvingfunctions
+// CreateResolvingFunctions ( promise )
 function CreateResolvingFunctions(promise) {
   var alreadyResolved = false;
 
+  // ES#sec-promise-resolve-functions
+  // Promise Resolve Functions
   var resolve = value => {
     if (alreadyResolved === true) return;
     alreadyResolved = true;
-    PromiseResolve(promise, value);
+    FulfillPromise(promise, value);
   };
 
+  // ES#sec-promise-reject-functions
+  // Promise Reject Functions
   var reject = reason => {
     if (alreadyResolved === true) return;
     alreadyResolved = true;
-    PromiseReject(promise, reason);
+    RejectPromise(promise, reason);
   };
 
   return {
@@ -59,13 +70,16 @@
 }
 
 
+// ES#sec-promise-executor
+// Promise ( executor )
 var GlobalPromise = function Promise(resolver) {
   if (resolver === promiseRawSymbol) {
     return %_NewObject(GlobalPromise, new.target);
   }
   if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);
-  if (!IS_CALLABLE(resolver))
+  if (!IS_CALLABLE(resolver)) {
     throw MakeTypeError(kResolverNotAFunction, resolver);
+  }
 
   var promise = PromiseInit(%_NewObject(GlobalPromise, new.target));
   var callbacks = CreateResolvingFunctions(promise);
@@ -85,27 +99,27 @@
 // Core functionality.
 
 function PromiseSet(promise, status, value, onResolve, onReject) {
-  SET_PRIVATE(promise, promiseStatusSymbol, status);
-  SET_PRIVATE(promise, promiseValueSymbol, value);
-  SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve);
-  SET_PRIVATE(promise, promiseOnRejectSymbol, onReject);
+  SET_PRIVATE(promise, promiseStateSymbol, status);
+  SET_PRIVATE(promise, promiseResultSymbol, value);
+  SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);
+  SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);
   return promise;
 }
 
 function PromiseCreateAndSet(status, value) {
   var promise = new GlobalPromise(promiseRawSymbol);
   // If debug is active, notify about the newly created promise first.
-  if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
+  if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);
   return PromiseSet(promise, status, value);
 }
 
 function PromiseInit(promise) {
   return PromiseSet(
-      promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+      promise, kPending, UNDEFINED, new InternalArray, new InternalArray)
 }
 
 function PromiseDone(promise, status, value, promiseQueue) {
-  if (GET_PRIVATE(promise, promiseStatusSymbol) === 0) {
+  if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
     var tasks = GET_PRIVATE(promise, promiseQueue);
     if (tasks.length) PromiseEnqueue(value, tasks, status);
     PromiseSet(promise, status, value);
@@ -139,7 +153,7 @@
   });
   if (instrumenting) {
     id = ++lastMicrotaskId;
-    name = status > 0 ? "Promise.resolve" : "Promise.reject";
+    name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
     %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
   }
 }
@@ -154,24 +168,27 @@
 
 // For bootstrapper.
 
+// ES#sec-ispromise IsPromise ( x )
 function IsPromise(x) {
-  return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol);
+  return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol);
 }
 
 function PromiseCreate() {
   return new GlobalPromise(PromiseNopResolver)
 }
 
-function PromiseResolve(promise, x) {
+// ES#sec-fulfillpromise
+// FulfillPromise ( promise, value)
+function FulfillPromise(promise, x) {
   if (x === promise) {
-    return PromiseReject(promise, MakeTypeError(kPromiseCyclic, x));
+    return RejectPromise(promise, MakeTypeError(kPromiseCyclic, x));
   }
   if (IS_RECEIVER(x)) {
     // 25.4.1.3.2 steps 8-12
     try {
       var then = x.then;
     } catch (e) {
-      return PromiseReject(promise, e);
+      return RejectPromise(promise, e);
     }
     if (IS_CALLABLE(then)) {
       // PromiseResolveThenableJob
@@ -198,22 +215,26 @@
       return;
     }
   }
-  PromiseDone(promise, +1, x, promiseOnResolveSymbol);
+  PromiseDone(promise, kFulfilled, x, promiseFulfillReactionsSymbol);
 }
 
-function PromiseReject(promise, r) {
+// ES#sec-rejectpromise
+// RejectPromise ( promise, reason )
+function RejectPromise(promise, r) {
   // Check promise status to confirm that this reject has an effect.
   // Call runtime for callbacks to the debugger or for unhandled reject.
-  if (GET_PRIVATE(promise, promiseStatusSymbol) == 0) {
+  if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
     var debug_is_active = DEBUG_IS_ACTIVE;
     if (debug_is_active ||
         !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
       %PromiseRejectEvent(promise, r, debug_is_active);
     }
   }
-  PromiseDone(promise, -1, r, promiseOnRejectSymbol)
+  PromiseDone(promise, kRejected, r, promiseRejectReactionsSymbol)
 }
 
+// ES#sec-newpromisecapability
+// NewPromiseCapability ( C )
 function NewPromiseCapability(C) {
   if (C === GlobalPromise) {
     // Optimized case, avoid extra closure.
@@ -240,23 +261,27 @@
   return result;
 }
 
-function PromiseDeferred() {
+// Unspecified V8-specific legacy function
+function PromiseDefer() {
   %IncrementUseCounter(kPromiseDefer);
   return NewPromiseCapability(this);
 }
 
-function PromiseResolved(x) {
+// Unspecified V8-specific legacy function
+function PromiseAccept(x) {
   %IncrementUseCounter(kPromiseAccept);
-  return %_Call(PromiseCast, this, x);
+  return %_Call(PromiseResolve, this, x);
 }
 
-function PromiseRejected(r) {
+// ES#sec-promise.reject
+// Promise.reject ( x )
+function PromiseReject(r) {
   if (!IS_RECEIVER(this)) {
-    throw MakeTypeError(kCalledOnNonObject, PromiseRejected);
+    throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
   }
   if (this === GlobalPromise) {
     // Optimized case, avoid extra closure.
-    var promise = PromiseCreateAndSet(-1, r);
+    var promise = PromiseCreateAndSet(kRejected, r);
     // The debug event for this would always be an uncaught promise reject,
     // which is usually simply noise. Do not trigger that debug event.
     %PromiseRejectEvent(promise, r, false);
@@ -268,10 +293,21 @@
   }
 }
 
-// Multi-unwrapped chaining with thenable coercion.
+// Shortcut Promise.reject and Promise.resolve() implementations, used by
+// Async Functions implementation.
+function PromiseCreateRejected(r) {
+  return %_Call(PromiseReject, GlobalPromise, r);
+}
 
+function PromiseCreateResolved(x) {
+  return %_Call(PromiseResolve, GlobalPromise, x);
+}
+
+// ES#sec-promise.prototype.then
+// Promise.prototype.then ( onFulfilled, onRejected )
+// Multi-unwrapped chaining with thenable coercion.
 function PromiseThen(onResolve, onReject) {
-  var status = GET_PRIVATE(this, promiseStatusSymbol);
+  var status = GET_PRIVATE(this, promiseStateSymbol);
   if (IS_UNDEFINED(status)) {
     throw MakeTypeError(kNotAPromise, this);
   }
@@ -281,24 +317,25 @@
   onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;
   var deferred = NewPromiseCapability(constructor);
   switch (status) {
-    case 0:  // Pending
-      GET_PRIVATE(this, promiseOnResolveSymbol).push(onResolve, deferred);
-      GET_PRIVATE(this, promiseOnRejectSymbol).push(onReject, deferred);
+    case kPending:
+      GET_PRIVATE(this, promiseFulfillReactionsSymbol).push(onResolve,
+                                                            deferred);
+      GET_PRIVATE(this, promiseRejectReactionsSymbol).push(onReject, deferred);
       break;
-    case +1:  // Resolved
-      PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+    case kFulfilled:
+      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
                      [onResolve, deferred],
-                     +1);
+                     kFulfilled);
       break;
-    case -1:  // Rejected
+    case kRejected:
       if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
         // Promise has already been rejected, but had no handler.
         // Revoke previously triggered reject event.
         %PromiseRevokeReject(this);
       }
-      PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
                      [onReject, deferred],
-                     -1);
+                     kRejected);
       break;
   }
   // Mark this promise as having handler.
@@ -306,21 +343,26 @@
   return deferred.promise;
 }
 
+// Unspecified V8-specific legacy function
 // Chain is left around for now as an alias for then
 function PromiseChain(onResolve, onReject) {
   %IncrementUseCounter(kPromiseChain);
   return %_Call(PromiseThen, this, onResolve, onReject);
 }
 
+// ES#sec-promise.prototype.catch
+// Promise.prototype.catch ( onRejected )
 function PromiseCatch(onReject) {
   return this.then(UNDEFINED, onReject);
 }
 
 // Combinators.
 
-function PromiseCast(x) {
+// ES#sec-promise.resolve
+// Promise.resolve ( x )
+function PromiseResolve(x) {
   if (!IS_RECEIVER(this)) {
-    throw MakeTypeError(kCalledOnNonObject, PromiseCast);
+    throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
   }
   if (IsPromise(x) && x.constructor === this) return x;
 
@@ -329,6 +371,8 @@
   return promiseCapability.promise;
 }
 
+// ES#sec-promise.all
+// Promise.all ( iterable )
 function PromiseAll(iterable) {
   if (!IS_RECEIVER(this)) {
     throw MakeTypeError(kCalledOnNonObject, "Promise.all");
@@ -378,6 +422,8 @@
   return deferred.promise;
 }
 
+// ES#sec-promise.race
+// Promise.race ( iterable )
 function PromiseRace(iterable) {
   if (!IS_RECEIVER(this)) {
     throw MakeTypeError(kCalledOnNonObject, PromiseRace);
@@ -399,7 +445,7 @@
 // Utility for debugger
 
 function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
-  var queue = GET_PRIVATE(promise, promiseOnRejectSymbol);
+  var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
   if (IS_UNDEFINED(queue)) return false;
   for (var i = 0; i < queue.length; i += 2) {
     var handler = queue[i];
@@ -432,10 +478,10 @@
                   DONT_ENUM | READ_ONLY);
 
 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
-  "reject", PromiseRejected,
+  "reject", PromiseReject,
   "all", PromiseAll,
   "race", PromiseRace,
-  "resolve", PromiseCast
+  "resolve", PromiseResolve
 ]);
 
 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
@@ -448,9 +494,11 @@
   "promise_chain", PromiseChain,
   "promise_create", PromiseCreate,
   "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
-  "promise_reject", PromiseReject,
-  "promise_resolve", PromiseResolve,
+  "promise_reject", RejectPromise,
+  "promise_resolve", FulfillPromise,
   "promise_then", PromiseThen,
+  "promise_create_rejected", PromiseCreateRejected,
+  "promise_create_resolved", PromiseCreateResolved
 ]);
 
 // This allows extras to create promises quickly without building extra
@@ -458,18 +506,22 @@
 // promise without having to hold on to those closures forever.
 utils.InstallFunctions(extrasUtils, 0, [
   "createPromise", PromiseCreate,
-  "resolvePromise", PromiseResolve,
-  "rejectPromise", PromiseReject
+  "resolvePromise", FulfillPromise,
+  "rejectPromise", RejectPromise
 ]);
 
 // TODO(v8:4567): Allow experimental natives to remove function prototype
-[PromiseChain, PromiseDeferred, PromiseResolved].forEach(
+[PromiseChain, PromiseDefer, PromiseAccept].forEach(
     fn => %FunctionRemovePrototype(fn));
 
 utils.Export(function(to) {
   to.PromiseChain = PromiseChain;
-  to.PromiseDeferred = PromiseDeferred;
-  to.PromiseResolved = PromiseResolved;
+  to.PromiseDefer = PromiseDefer;
+  to.PromiseAccept = PromiseAccept;
+
+  to.PromiseCreateRejected = PromiseCreateRejected;
+  to.PromiseCreateResolved = PromiseCreateResolved;
+  to.PromiseThen = PromiseThen;
 });
 
 })
diff --git a/src/js/regexp.js b/src/js/regexp.js
index cc8cb41..719a081 100644
--- a/src/js/regexp.js
+++ b/src/js/regexp.js
@@ -4,14 +4,11 @@
 
 (function(global, utils) {
 
-'use strict';
-
 %CheckIsBootstrapping();
 
 // -------------------------------------------------------------------
 // Imports
 
-var AddIndexedProperty;
 var ExpandReplacement;
 var GlobalArray = global.Array;
 var GlobalObject = global.Object;
@@ -29,7 +26,6 @@
 var SpeciesConstructor;
 
 utils.Import(function(from) {
-  AddIndexedProperty = from.AddIndexedProperty;
   ExpandReplacement = from.ExpandReplacement;
   MakeTypeError = from.MakeTypeError;
   MaxSimple = from.MaxSimple;
@@ -502,7 +498,7 @@
   var result;
   if (size === 0) {
     result = RegExpSubclassExec(splitter, string);
-    if (IS_NULL(result)) AddIndexedProperty(array, 0, string);
+    if (IS_NULL(result)) %AddElement(array, 0, string);
     return array;
   }
   var stringIndex = prevStringIndex;
@@ -515,10 +511,10 @@
       stringIndex += AdvanceStringIndex(string, stringIndex, unicode);
     } else {
       var end = MinSimple(TO_LENGTH(splitter.lastIndex), size);
-      if (end === stringIndex) {
+      if (end === prevStringIndex) {
         stringIndex += AdvanceStringIndex(string, stringIndex, unicode);
       } else {
-        AddIndexedProperty(
+        %AddElement(
             array, arrayIndex,
             %_SubString(string, prevStringIndex, stringIndex));
         arrayIndex++;
@@ -526,7 +522,7 @@
         prevStringIndex = end;
         var numberOfCaptures = MaxSimple(TO_LENGTH(result.length), 0);
         for (var i = 1; i < numberOfCaptures; i++) {
-          AddIndexedProperty(array, arrayIndex, result[i]);
+          %AddElement(array, arrayIndex, result[i]);
           arrayIndex++;
           if (arrayIndex === lim) return array;
         }
@@ -534,7 +530,7 @@
       }
     }
   }
-  AddIndexedProperty(array, arrayIndex,
+  %AddElement(array, arrayIndex,
                      %_SubString(string, prevStringIndex, size));
   return array;
 }
diff --git a/src/js/runtime.js b/src/js/runtime.js
index 8e4f283..a6a0b4d 100644
--- a/src/js/runtime.js
+++ b/src/js/runtime.js
@@ -43,19 +43,6 @@
 */
 
 
-// This function should be called rather than %AddElement in contexts where the
-// argument might not be less than 2**32-1. ES2015 ToLength semantics mean that
-// this is a concern at basically all callsites.
-function AddIndexedProperty(obj, index, value) {
-  if (index === TO_UINT32(index) && index !== kMaxUint32) {
-    %AddElement(obj, index, value);
-  } else {
-    %AddNamedProperty(obj, TO_STRING(index), value, NONE);
-  }
-}
-%SetForceInlineFlag(AddIndexedProperty);
-
-
 function ToPositiveInteger(x, rangeErrorIndex) {
   var i = TO_INTEGER_MAP_MINUS_ZERO(x);
   if (i < 0) throw MakeRangeError(rangeErrorIndex);
@@ -122,7 +109,6 @@
 // Exports
 
 utils.Export(function(to) {
-  to.AddIndexedProperty = AddIndexedProperty;
   to.MaxSimple = MaxSimple;
   to.MinSimple = MinSimple;
   to.ToPositiveInteger = ToPositiveInteger;
diff --git a/src/js/string.js b/src/js/string.js
index 0eb394e..badb2b4 100644
--- a/src/js/string.js
+++ b/src/js/string.js
@@ -57,30 +57,6 @@
 }
 
 
-// ECMA-262, section 15.5.4.4
-function StringCharAtJS(pos) {
-  CHECK_OBJECT_COERCIBLE(this, "String.prototype.charAt");
-
-  var result = %_StringCharAt(this, pos);
-  if (%_IsSmi(result)) {
-    result = %_StringCharAt(TO_STRING(this), TO_INTEGER(pos));
-  }
-  return result;
-}
-
-
-// ECMA-262 section 15.5.4.5
-function StringCharCodeAtJS(pos) {
-  CHECK_OBJECT_COERCIBLE(this, "String.prototype.charCodeAt");
-
-  var result = %_StringCharCodeAt(this, pos);
-  if (!%_IsSmi(result)) {
-    result = %_StringCharCodeAt(TO_STRING(this), TO_INTEGER(pos));
-  }
-  return result;
-}
-
-
 // ECMA-262, section 15.5.4.6
 function StringConcat(other /* and more */) {  // length == 1
   "use strict";
@@ -845,13 +821,6 @@
 
 // -------------------------------------------------------------------
 
-// Set the String function and constructor.
-%FunctionSetPrototype(GlobalString, new GlobalString());
-
-// Set up the constructor property on the String prototype object.
-%AddNamedProperty(
-    GlobalString.prototype, "constructor", GlobalString, DONT_ENUM);
-
 // Set up the non-enumerable functions on the String object.
 utils.InstallFunctions(GlobalString, DONT_ENUM, [
   "fromCodePoint", StringFromCodePoint,
@@ -862,8 +831,6 @@
 utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
   "valueOf", StringValueOf,
   "toString", StringToString,
-  "charAt", StringCharAtJS,
-  "charCodeAt", StringCharCodeAtJS,
   "codePointAt", StringCodePointAt,
   "concat", StringConcat,
   "endsWith", StringEndsWith,
@@ -909,7 +876,6 @@
 
 utils.Export(function(to) {
   to.ExpandReplacement = ExpandReplacement;
-  to.StringCharAt = StringCharAtJS;
   to.StringIndexOf = StringIndexOf;
   to.StringLastIndexOf = StringLastIndexOf;
   to.StringMatch = StringMatchJS;
diff --git a/src/js/typedarray.js b/src/js/typedarray.js
index 4fb174b..18f6dde 100644
--- a/src/js/typedarray.js
+++ b/src/js/typedarray.js
@@ -11,7 +11,6 @@
 // -------------------------------------------------------------------
 // Imports
 
-var AddIndexedProperty;
 // array.js has to come before typedarray.js for this to work
 var ArrayToString = utils.ImportNow("ArrayToString");
 var ArrayValues;
@@ -22,7 +21,6 @@
 var GlobalArrayBufferPrototype = GlobalArrayBuffer.prototype;
 var GlobalDataView = global.DataView;
 var GlobalObject = global.Object;
-var InternalArray = utils.InternalArray;
 var InnerArrayCopyWithin;
 var InnerArrayEvery;
 var InnerArrayFill;
@@ -71,7 +69,6 @@
 TYPED_ARRAYS(DECLARE_GLOBALS)
 
 utils.Import(function(from) {
-  AddIndexedProperty = from.AddIndexedProperty;
   ArrayValues = from.ArrayValues;
   GetIterator = from.GetIterator;
   GetMethod = from.GetMethod;
diff --git a/src/js/uri.js b/src/js/uri.js
index dca83c9..19bfbd3 100644
--- a/src/js/uri.js
+++ b/src/js/uri.js
@@ -37,72 +37,6 @@
   return -1;
 }
 
-// Does the char code correspond to an alpha-numeric char.
-function isAlphaNumeric(cc) {
-  // a - z
-  if (97 <= cc && cc <= 122) return true;
-  // A - Z
-  if (65 <= cc && cc <= 90) return true;
-  // 0 - 9
-  if (48 <= cc && cc <= 57) return true;
-
-  return false;
-}
-
-// Lazily initialized.
-var hexCharCodeArray = 0;
-
-function URIAddEncodedOctetToBuffer(octet, result, index) {
-  result[index++] = 37; // Char code of '%'.
-  result[index++] = hexCharCodeArray[octet >> 4];
-  result[index++] = hexCharCodeArray[octet & 0x0F];
-  return index;
-}
-
-function URIEncodeOctets(octets, result, index) {
-  if (hexCharCodeArray === 0) {
-    hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-                        65, 66, 67, 68, 69, 70];
-  }
-  index = URIAddEncodedOctetToBuffer(octets[0], result, index);
-  if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index);
-  if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index);
-  if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index);
-  return index;
-}
-
-function URIEncodeSingle(cc, result, index) {
-  var x = (cc >> 12) & 0xF;
-  var y = (cc >> 6) & 63;
-  var z = cc & 63;
-  var octets = new InternalArray(3);
-  if (cc <= 0x007F) {
-    octets[0] = cc;
-  } else if (cc <= 0x07FF) {
-    octets[0] = y + 192;
-    octets[1] = z + 128;
-  } else {
-    octets[0] = x + 224;
-    octets[1] = y + 128;
-    octets[2] = z + 128;
-  }
-  return URIEncodeOctets(octets, result, index);
-}
-
-function URIEncodePair(cc1 , cc2, result, index) {
-  var u = ((cc1 >> 6) & 0xF) + 1;
-  var w = (cc1 >> 2) & 0xF;
-  var x = cc1 & 3;
-  var y = (cc2 >> 6) & 0xF;
-  var z = cc2 & 63;
-  var octets = new InternalArray(4);
-  octets[0] = (u >> 2) + 240;
-  octets[1] = (((u & 3) << 4) | w) + 128;
-  octets[2] = ((x << 4) | y) + 128;
-  octets[3] = z + 128;
-  return URIEncodeOctets(octets, result, index);
-}
-
 function URIHexCharsToCharCode(highChar, lowChar) {
   var highCode = HexValueOf(highChar);
   var lowCode = HexValueOf(lowChar);
@@ -168,37 +102,6 @@
 }
 
 // ECMA-262, section 15.1.3
-function Encode(uri, unescape) {
-  uri = TO_STRING(uri);
-  var uriLength = uri.length;
-  var array = new InternalArray(uriLength);
-  var index = 0;
-  for (var k = 0; k < uriLength; k++) {
-    var cc1 = %_StringCharCodeAt(uri, k);
-    if (unescape(cc1)) {
-      array[index++] = cc1;
-    } else {
-      if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw MakeURIError();
-      if (cc1 < 0xD800 || cc1 > 0xDBFF) {
-        index = URIEncodeSingle(cc1, array, index);
-      } else {
-        k++;
-        if (k == uriLength) throw MakeURIError();
-        var cc2 = %_StringCharCodeAt(uri, k);
-        if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw MakeURIError();
-        index = URIEncodePair(cc1, cc2, array, index);
-      }
-    }
-  }
-
-  var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
-  for (var i = 0; i < array.length; i++) {
-    %_OneByteSeqStringSetChar(i, array[i], result);
-  }
-  return result;
-}
-
-// ECMA-262, section 15.1.3
 function Decode(uri, reserved) {
   uri = TO_STRING(uri);
   var uriLength = uri.length;
@@ -316,52 +219,6 @@
   return Decode(component, reservedPredicate);
 }
 
-// ECMA-262 - 15.1.3.3.
-function URIEncode(uri) {
-  var unescapePredicate = function(cc) {
-    if (isAlphaNumeric(cc)) return true;
-    // !
-    if (cc == 33) return true;
-    // #$
-    if (35 <= cc && cc <= 36) return true;
-    // &'()*+,-./
-    if (38 <= cc && cc <= 47) return true;
-    // :;
-    if (58 <= cc && cc <= 59) return true;
-    // =
-    if (cc == 61) return true;
-    // ?@
-    if (63 <= cc && cc <= 64) return true;
-    // _
-    if (cc == 95) return true;
-    // ~
-    if (cc == 126) return true;
-
-    return false;
-  };
-  return Encode(uri, unescapePredicate);
-}
-
-// ECMA-262 - 15.1.3.4
-function URIEncodeComponent(component) {
-  var unescapePredicate = function(cc) {
-    if (isAlphaNumeric(cc)) return true;
-    // !
-    if (cc == 33) return true;
-    // '()*
-    if (39 <= cc && cc <= 42) return true;
-    // -.
-    if (45 <= cc && cc <= 46) return true;
-    // _
-    if (cc == 95) return true;
-    // ~
-    if (cc == 126) return true;
-
-    return false;
-  };
-  return Encode(component, unescapePredicate);
-}
-
 // -------------------------------------------------------------------
 // Install exported functions.
 
@@ -371,9 +228,7 @@
   "escape", URIEscapeJS,
   "unescape", URIUnescapeJS,
   "decodeURI", URIDecode,
-  "decodeURIComponent", URIDecodeComponent,
-  "encodeURI", URIEncode,
-  "encodeURIComponent", URIEncodeComponent
+  "decodeURIComponent", URIDecodeComponent
 ]);
 
 })
diff --git a/src/js/v8natives.js b/src/js/v8natives.js
index 5185c62..44be941 100644
--- a/src/js/v8natives.js
+++ b/src/js/v8natives.js
@@ -20,9 +20,6 @@
 var MathAbs;
 var NaN = %GetRootNaN();
 var ObjectToString = utils.ImportNow("object_to_string");
-var ObserveBeginPerformSplice;
-var ObserveEndPerformSplice;
-var ObserveEnqueueSpliceRecord;
 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
 
 utils.Import(function(from) {
@@ -30,9 +27,6 @@
   MakeSyntaxError = from.MakeSyntaxError;
   MakeTypeError = from.MakeTypeError;
   MathAbs = from.MathAbs;
-  ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
-  ObserveEndPerformSplice = from.ObserveEndPerformSplice;
-  ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
 });
 
 // ----------------------------------------------------------------------------
@@ -148,348 +142,6 @@
   return %PropertyIsEnumerable(TO_OBJECT(this), P);
 }
 
-
-// Extensions for providing property getters and setters.
-function ObjectDefineGetter(name, fun) {
-  var receiver = this;
-  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
-    receiver = %GlobalProxy(ObjectDefineGetter);
-  }
-  if (!IS_CALLABLE(fun)) {
-    throw MakeTypeError(kObjectGetterExpectingFunction);
-  }
-  var desc = new PropertyDescriptor();
-  desc.setGet(fun);
-  desc.setEnumerable(true);
-  desc.setConfigurable(true);
-  DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupGetter(name) {
-  var receiver = this;
-  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
-    receiver = %GlobalProxy(ObjectLookupGetter);
-  }
-  return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), GETTER);
-}
-
-
-function ObjectDefineSetter(name, fun) {
-  var receiver = this;
-  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
-    receiver = %GlobalProxy(ObjectDefineSetter);
-  }
-  if (!IS_CALLABLE(fun)) {
-    throw MakeTypeError(kObjectSetterExpectingFunction);
-  }
-  var desc = new PropertyDescriptor();
-  desc.setSet(fun);
-  desc.setEnumerable(true);
-  desc.setConfigurable(true);
-  DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupSetter(name) {
-  var receiver = this;
-  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
-    receiver = %GlobalProxy(ObjectLookupSetter);
-  }
-  return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), SETTER);
-}
-
-
-// ES6 6.2.4.1
-function IsAccessorDescriptor(desc) {
-  if (IS_UNDEFINED(desc)) return false;
-  return desc.hasGetter() || desc.hasSetter();
-}
-
-
-// ES6 6.2.4.2
-function IsDataDescriptor(desc) {
-  if (IS_UNDEFINED(desc)) return false;
-  return desc.hasValue() || desc.hasWritable();
-}
-
-
-// ES6 6.2.4.3
-function IsGenericDescriptor(desc) {
-  if (IS_UNDEFINED(desc)) return false;
-  return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
-}
-
-
-function IsInconsistentDescriptor(desc) {
-  return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
-}
-
-
-// Harmony Proxies
-function FromGenericPropertyDescriptor(desc) {
-  if (IS_UNDEFINED(desc)) return desc;
-  var obj = new GlobalObject();
-
-  if (desc.hasValue()) {
-    %AddNamedProperty(obj, "value", desc.getValue(), NONE);
-  }
-  if (desc.hasWritable()) {
-    %AddNamedProperty(obj, "writable", desc.isWritable(), NONE);
-  }
-  if (desc.hasGetter()) {
-    %AddNamedProperty(obj, "get", desc.getGet(), NONE);
-  }
-  if (desc.hasSetter()) {
-    %AddNamedProperty(obj, "set", desc.getSet(), NONE);
-  }
-  if (desc.hasEnumerable()) {
-    %AddNamedProperty(obj, "enumerable", desc.isEnumerable(), NONE);
-  }
-  if (desc.hasConfigurable()) {
-    %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE);
-  }
-  return obj;
-}
-
-
-// ES6 6.2.4.5
-function ToPropertyDescriptor(obj) {
-  if (!IS_RECEIVER(obj)) throw MakeTypeError(kPropertyDescObject, obj);
-
-  var desc = new PropertyDescriptor();
-
-  if ("enumerable" in obj) {
-    desc.setEnumerable(TO_BOOLEAN(obj.enumerable));
-  }
-
-  if ("configurable" in obj) {
-    desc.setConfigurable(TO_BOOLEAN(obj.configurable));
-  }
-
-  if ("value" in obj) {
-    desc.setValue(obj.value);
-  }
-
-  if ("writable" in obj) {
-    desc.setWritable(TO_BOOLEAN(obj.writable));
-  }
-
-  if ("get" in obj) {
-    var get = obj.get;
-    if (!IS_UNDEFINED(get) && !IS_CALLABLE(get)) {
-      throw MakeTypeError(kObjectGetterCallable, get);
-    }
-    desc.setGet(get);
-  }
-
-  if ("set" in obj) {
-    var set = obj.set;
-    if (!IS_UNDEFINED(set) && !IS_CALLABLE(set)) {
-      throw MakeTypeError(kObjectSetterCallable, set);
-    }
-    desc.setSet(set);
-  }
-
-  if (IsInconsistentDescriptor(desc)) {
-    throw MakeTypeError(kValueAndAccessor, obj);
-  }
-  return desc;
-}
-
-// TODO(cbruni): remove once callers have been removed
-function ToCompletePropertyDescriptor(obj) {
-  var desc = ToPropertyDescriptor(obj);
-  if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
-    if (!desc.hasValue()) desc.setValue(UNDEFINED);
-    if (!desc.hasWritable()) desc.setWritable(false);
-  } else {
-    // Is accessor descriptor.
-    if (!desc.hasGetter()) desc.setGet(UNDEFINED);
-    if (!desc.hasSetter()) desc.setSet(UNDEFINED);
-  }
-  if (!desc.hasEnumerable()) desc.setEnumerable(false);
-  if (!desc.hasConfigurable()) desc.setConfigurable(false);
-  return desc;
-}
-
-
-function PropertyDescriptor() {
-  // Initialize here so they are all in-object and have the same map.
-  // Default values from ES5 8.6.1.
-  this.value_ = UNDEFINED;
-  this.hasValue_ = false;
-  this.writable_ = false;
-  this.hasWritable_ = false;
-  this.enumerable_ = false;
-  this.hasEnumerable_ = false;
-  this.configurable_ = false;
-  this.hasConfigurable_ = false;
-  this.get_ = UNDEFINED;
-  this.hasGetter_ = false;
-  this.set_ = UNDEFINED;
-  this.hasSetter_ = false;
-}
-
-utils.SetUpLockedPrototype(PropertyDescriptor, [
-  "value_",
-  "hasValue_",
-  "writable_",
-  "hasWritable_",
-  "enumerable_",
-  "hasEnumerable_",
-  "configurable_",
-  "hasConfigurable_",
-  "get_",
-  "hasGetter_",
-  "set_",
-  "hasSetter_"
-], [
-  "toString", function PropertyDescriptor_ToString() {
-    return "[object PropertyDescriptor]";
-  },
-  "setValue", function PropertyDescriptor_SetValue(value) {
-    this.value_ = value;
-    this.hasValue_ = true;
-  },
-  "getValue", function PropertyDescriptor_GetValue() {
-    return this.value_;
-  },
-  "hasValue", function PropertyDescriptor_HasValue() {
-    return this.hasValue_;
-  },
-  "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
-    this.enumerable_ = enumerable;
-      this.hasEnumerable_ = true;
-  },
-  "isEnumerable", function PropertyDescriptor_IsEnumerable() {
-    return this.enumerable_;
-  },
-  "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
-    return this.hasEnumerable_;
-  },
-  "setWritable", function PropertyDescriptor_SetWritable(writable) {
-    this.writable_ = writable;
-    this.hasWritable_ = true;
-  },
-  "isWritable", function PropertyDescriptor_IsWritable() {
-    return this.writable_;
-  },
-  "hasWritable", function PropertyDescriptor_HasWritable() {
-    return this.hasWritable_;
-  },
-  "setConfigurable",
-  function PropertyDescriptor_SetConfigurable(configurable) {
-    this.configurable_ = configurable;
-    this.hasConfigurable_ = true;
-  },
-  "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
-    return this.hasConfigurable_;
-  },
-  "isConfigurable", function PropertyDescriptor_IsConfigurable() {
-    return this.configurable_;
-  },
-  "setGet", function PropertyDescriptor_SetGetter(get) {
-    this.get_ = get;
-    this.hasGetter_ = true;
-  },
-  "getGet", function PropertyDescriptor_GetGetter() {
-    return this.get_;
-  },
-  "hasGetter", function PropertyDescriptor_HasGetter() {
-    return this.hasGetter_;
-  },
-  "setSet", function PropertyDescriptor_SetSetter(set) {
-    this.set_ = set;
-    this.hasSetter_ = true;
-  },
-  "getSet", function PropertyDescriptor_GetSetter() {
-    return this.set_;
-  },
-  "hasSetter", function PropertyDescriptor_HasSetter() {
-    return this.hasSetter_;
-  }
-]);
-
-
-// Converts an array returned from Runtime_GetOwnProperty to an actual
-// property descriptor. For a description of the array layout please
-// see the runtime.cc file.
-function ConvertDescriptorArrayToDescriptor(desc_array) {
-  if (IS_UNDEFINED(desc_array)) {
-    return UNDEFINED;
-  }
-
-  var desc = new PropertyDescriptor();
-  // This is an accessor.
-  if (desc_array[IS_ACCESSOR_INDEX]) {
-    desc.setGet(desc_array[GETTER_INDEX]);
-    desc.setSet(desc_array[SETTER_INDEX]);
-  } else {
-    desc.setValue(desc_array[VALUE_INDEX]);
-    desc.setWritable(desc_array[WRITABLE_INDEX]);
-  }
-  desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
-  desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
-
-  return desc;
-}
-
-
-// For Harmony proxies.
-function GetTrap(handler, name, defaultTrap) {
-  var trap = handler[name];
-  if (IS_UNDEFINED(trap)) {
-    if (IS_UNDEFINED(defaultTrap)) {
-      throw MakeTypeError(kIllegalInvocation);
-    }
-    trap = defaultTrap;
-  } else if (!IS_CALLABLE(trap)) {
-    throw MakeTypeError(kIllegalInvocation);
-  }
-  return trap;
-}
-
-
-function CallTrap1(handler, name, defaultTrap, x) {
-  return %_Call(GetTrap(handler, name, defaultTrap), handler, x);
-}
-
-
-function CallTrap2(handler, name, defaultTrap, x, y) {
-  return %_Call(GetTrap(handler, name, defaultTrap), handler, x, y);
-}
-
-
-// ES5 section 8.12.1.
-// TODO(jkummerow): Deprecated. Migrate all callers to
-// ObjectGetOwnPropertyDescriptor and delete this.
-function GetOwnPropertyJS(obj, v) {
-  var p = TO_NAME(v);
-  if (IS_PROXY(obj)) {
-    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
-    if (IS_SYMBOL(v)) return UNDEFINED;
-
-    var handler = %JSProxyGetHandler(obj);
-    var descriptor = CallTrap1(
-                         handler, "getOwnPropertyDescriptor", UNDEFINED, p);
-    if (IS_UNDEFINED(descriptor)) return descriptor;
-    var desc = ToCompletePropertyDescriptor(descriptor);
-    if (!desc.isConfigurable()) {
-      throw MakeTypeError(kIllegalInvocation);
-    }
-    return desc;
-  }
-
-  // GetOwnProperty returns an array indexed by the constants
-  // defined in macros.py.
-  // If p is not a property on obj undefined is returned.
-  var props = %GetOwnProperty_Legacy(TO_OBJECT(obj), p);
-
-  return ConvertDescriptorArrayToDescriptor(props);
-}
-
-
 // ES6 7.3.9
 function GetMethod(obj, p) {
   var func = obj[p];
@@ -498,252 +150,6 @@
   throw MakeTypeError(kCalledNonCallable, typeof func);
 }
 
-
-// Harmony proxies.
-function DefineProxyProperty(obj, p, attributes, should_throw) {
-  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
-  if (IS_SYMBOL(p)) return false;
-
-  var handler = %JSProxyGetHandler(obj);
-  var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes);
-  if (!result) {
-    if (should_throw) {
-      throw MakeTypeError(kIllegalInvocation);
-    } else {
-      return false;
-    }
-  }
-  return true;
-}
-
-
-// ES6 9.1.6 [[DefineOwnProperty]](P, Desc)
-function DefineObjectProperty(obj, p, desc, should_throw) {
-  var current_array = %GetOwnProperty_Legacy(obj, TO_NAME(p));
-  var current = ConvertDescriptorArrayToDescriptor(current_array);
-  var extensible = %object_is_extensible(obj);
-
-  if (IS_UNDEFINED(current) && !extensible) {
-    if (should_throw) {
-      throw MakeTypeError(kDefineDisallowed, p);
-    } else {
-      return false;
-    }
-  }
-
-  if (!IS_UNDEFINED(current)) {
-    if ((IsGenericDescriptor(desc) ||
-         IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
-        (!desc.hasEnumerable() ||
-         %SameValue(desc.isEnumerable(), current.isEnumerable())) &&
-        (!desc.hasConfigurable() ||
-         %SameValue(desc.isConfigurable(), current.isConfigurable())) &&
-        (!desc.hasWritable() ||
-         %SameValue(desc.isWritable(), current.isWritable())) &&
-        (!desc.hasValue() ||
-         %SameValue(desc.getValue(), current.getValue())) &&
-        (!desc.hasGetter() ||
-         %SameValue(desc.getGet(), current.getGet())) &&
-        (!desc.hasSetter() ||
-         %SameValue(desc.getSet(), current.getSet()))) {
-      return true;
-    }
-    if (!current.isConfigurable()) {
-      // Step 7
-      if (desc.isConfigurable() ||
-          (desc.hasEnumerable() &&
-           desc.isEnumerable() != current.isEnumerable())) {
-        if (should_throw) {
-          throw MakeTypeError(kRedefineDisallowed, p);
-        } else {
-          return false;
-        }
-      }
-      // Step 8
-      if (!IsGenericDescriptor(desc)) {
-        // Step 9a
-        if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
-          if (should_throw) {
-            throw MakeTypeError(kRedefineDisallowed, p);
-          } else {
-            return false;
-          }
-        }
-        // Step 10a
-        if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
-          var currentIsWritable = current.isWritable();
-          if (currentIsWritable != desc.isWritable()) {
-            if (!currentIsWritable) {
-              if (should_throw) {
-                throw MakeTypeError(kRedefineDisallowed, p);
-              } else {
-                return false;
-              }
-            }
-          }
-          if (!currentIsWritable && desc.hasValue() &&
-              !%SameValue(desc.getValue(), current.getValue())) {
-            if (should_throw) {
-              throw MakeTypeError(kRedefineDisallowed, p);
-            } else {
-              return false;
-            }
-          }
-        }
-        // Step 11
-        if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
-          if (desc.hasSetter() &&
-              !%SameValue(desc.getSet(), current.getSet())) {
-            if (should_throw) {
-              throw MakeTypeError(kRedefineDisallowed, p);
-            } else {
-              return false;
-            }
-          }
-          if (desc.hasGetter() && !%SameValue(desc.getGet(),current.getGet())) {
-            if (should_throw) {
-              throw MakeTypeError(kRedefineDisallowed, p);
-            } else {
-              return false;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // Send flags - enumerable and configurable are common - writable is
-  // only send to the data descriptor.
-  // Take special care if enumerable and configurable is not defined on
-  // desc (we need to preserve the existing values from current).
-  var flag = NONE;
-  if (desc.hasEnumerable()) {
-    flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
-  } else if (!IS_UNDEFINED(current)) {
-    flag |= current.isEnumerable() ? 0 : DONT_ENUM;
-  } else {
-    flag |= DONT_ENUM;
-  }
-
-  if (desc.hasConfigurable()) {
-    flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
-  } else if (!IS_UNDEFINED(current)) {
-    flag |= current.isConfigurable() ? 0 : DONT_DELETE;
-  } else
-    flag |= DONT_DELETE;
-
-  if (IsDataDescriptor(desc) ||
-      (IsGenericDescriptor(desc) &&
-       (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
-    // There are 3 cases that lead here:
-    // Step 4a - defining a new data property.
-    // Steps 9b & 12 - replacing an existing accessor property with a data
-    //                 property.
-    // Step 12 - updating an existing data property with a data or generic
-    //           descriptor.
-
-    if (desc.hasWritable()) {
-      flag |= desc.isWritable() ? 0 : READ_ONLY;
-    } else if (!IS_UNDEFINED(current)) {
-      flag |= current.isWritable() ? 0 : READ_ONLY;
-    } else {
-      flag |= READ_ONLY;
-    }
-
-    var value = UNDEFINED;  // Default value is undefined.
-    if (desc.hasValue()) {
-      value = desc.getValue();
-    } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
-      value = current.getValue();
-    }
-
-    %DefineDataPropertyUnchecked(obj, p, value, flag);
-  } else {
-    // There are 3 cases that lead here:
-    // Step 4b - defining a new accessor property.
-    // Steps 9c & 12 - replacing an existing data property with an accessor
-    //                 property.
-    // Step 12 - updating an existing accessor property with an accessor
-    //           descriptor.
-    var getter = null;
-    if (desc.hasGetter()) {
-      getter = desc.getGet();
-    } else if (IsAccessorDescriptor(current) && current.hasGetter()) {
-      getter = current.getGet();
-    }
-    var setter = null;
-    if (desc.hasSetter()) {
-      setter = desc.getSet();
-    } else if (IsAccessorDescriptor(current) && current.hasSetter()) {
-      setter = current.getSet();
-    }
-    %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag);
-  }
-  return true;
-}
-
-
-// ES5 section 15.4.5.1.
-function DefineArrayProperty(obj, p, desc, should_throw) {
-  // Step 3 - Special handling for array index.
-  if (!IS_SYMBOL(p)) {
-    var index = TO_UINT32(p);
-    var emit_splice = false;
-    if (TO_STRING(index) == p && index != 4294967295) {
-      var length = obj.length;
-      if (index >= length && %IsObserved(obj)) {
-        emit_splice = true;
-        ObserveBeginPerformSplice(obj);
-      }
-
-      var length_desc = GetOwnPropertyJS(obj, "length");
-      if ((index >= length && !length_desc.isWritable()) ||
-          !DefineObjectProperty(obj, p, desc, true)) {
-        if (emit_splice)
-          ObserveEndPerformSplice(obj);
-        if (should_throw) {
-          throw MakeTypeError(kDefineDisallowed, p);
-        } else {
-          return false;
-        }
-      }
-      if (index >= length) {
-        obj.length = index + 1;
-      }
-      if (emit_splice) {
-        ObserveEndPerformSplice(obj);
-        ObserveEnqueueSpliceRecord(obj, length, [], index + 1 - length);
-      }
-      return true;
-    }
-  }
-
-  // Step 5 - Fallback to default implementation.
-  return DefineObjectProperty(obj, p, desc, should_throw);
-}
-
-
-// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
-function DefineOwnProperty(obj, p, desc, should_throw) {
-  if (IS_PROXY(obj)) {
-    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
-    if (IS_SYMBOL(p)) return false;
-
-    var attributes = FromGenericPropertyDescriptor(desc);
-    return DefineProxyProperty(obj, p, attributes, should_throw);
-  } else if (IS_ARRAY(obj)) {
-    return DefineArrayProperty(obj, p, desc, should_throw);
-  } else {
-    return DefineObjectProperty(obj, p, desc, should_throw);
-  }
-}
-
-
-// ES6 section 19.1.2.9
-function ObjectGetPrototypeOf(obj) {
-  return %_GetPrototype(TO_OBJECT(obj));
-}
-
 // ES6 section 19.1.2.18.
 function ObjectSetPrototypeOf(obj, proto) {
   CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
@@ -759,50 +165,9 @@
   return obj;
 }
 
-
-// ES5 section 15.2.3.6.
-function ObjectDefineProperty(obj, p, attributes) {
-  // The new pure-C++ implementation doesn't support O.o.
-  // TODO(jkummerow): Implement missing features and remove fallback path.
-  if (%IsObserved(obj)) {
-    if (!IS_RECEIVER(obj)) {
-      throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty");
-    }
-    var name = TO_NAME(p);
-    var desc = ToPropertyDescriptor(attributes);
-    DefineOwnProperty(obj, name, desc, true);
-    return obj;
-  }
-  return %ObjectDefineProperty(obj, p, attributes);
-}
-
-
-// ES5 section 15.2.3.7.
-function ObjectDefineProperties(obj, properties) {
-  // The new pure-C++ implementation doesn't support O.o.
-  // TODO(jkummerow): Implement missing features and remove fallback path.
-  if (%IsObserved(obj)) {
-    if (!IS_RECEIVER(obj)) {
-      throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties");
-    }
-    var props = TO_OBJECT(properties);
-    var names = %GetOwnPropertyKeys(props, PROPERTY_FILTER_ONLY_ENUMERABLE);
-    var descriptors = new InternalArray();
-    for (var i = 0; i < names.length; i++) {
-      descriptors.push(ToPropertyDescriptor(props[names[i]]));
-    }
-    for (var i = 0; i < names.length; i++) {
-      DefineOwnProperty(obj, names[i], descriptors[i], true);
-    }
-    return obj;
-  }
-  return %ObjectDefineProperties(obj, properties);
-}
-
-
 // ES6 B.2.2.1.1
 function ObjectGetProto() {
-  return %_GetPrototype(TO_OBJECT(this));
+  return %object_get_prototype_of(this);
 }
 
 
@@ -842,26 +207,19 @@
   "valueOf", ObjectValueOf,
   "isPrototypeOf", ObjectIsPrototypeOf,
   "propertyIsEnumerable", ObjectPropertyIsEnumerable,
-  "__defineGetter__", ObjectDefineGetter,
-  "__lookupGetter__", ObjectLookupGetter,
-  "__defineSetter__", ObjectDefineSetter,
-  "__lookupSetter__", ObjectLookupSetter
+  // __defineGetter__ is added in bootstrapper.cc.
+  // __lookupGetter__ is added in bootstrapper.cc.
+  // __defineSetter__ is added in bootstrapper.cc.
+  // __lookupSetter__ is added in bootstrapper.cc.
 ]);
-utils.InstallGetterSetter(GlobalObject.prototype, "__proto__", ObjectGetProto,
-                    ObjectSetProto);
+utils.InstallGetterSetter(
+    GlobalObject.prototype, "__proto__", ObjectGetProto, ObjectSetProto);
 
 // Set up non-enumerable functions in the Object object.
 utils.InstallFunctions(GlobalObject, DONT_ENUM, [
-  // assign is added in bootstrapper.cc.
-  // keys is added in bootstrapper.cc.
-  "defineProperty", ObjectDefineProperty,
-  "defineProperties", ObjectDefineProperties,
-  "getPrototypeOf", ObjectGetPrototypeOf,
   "setPrototypeOf", ObjectSetPrototypeOf,
   // getOwnPropertySymbols is added in symbol.js.
-  // is is added in bootstrapper.cc.
-  // deliverChangeRecords, getNotifier, observe and unobserve are added
-  // in object-observe.js.
+  // Others are added in bootstrapper.cc.
 ]);
 
 
@@ -1096,8 +454,6 @@
   to.IsNaN = GlobalIsNaN;
   to.NumberIsNaN = NumberIsNaN;
   to.NumberIsInteger = NumberIsInteger;
-  to.ObjectDefineProperties = ObjectDefineProperties;
-  to.ObjectDefineProperty = ObjectDefineProperty;
   to.ObjectHasOwnProperty = GlobalObject.prototype.hasOwnProperty;
 });