Version 3.27.11 (based on bleeding_edge revision r21445)

Add support for ES6 Symbol in heap profiler (Chromium issue 376194).

Performance and stability improvements on all platforms.

git-svn-id: https://v8.googlecode.com/svn/trunk@21446 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 61efe5f..706a17b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-05-23: Version 3.27.11
+
+        Add support for ES6 Symbol in heap profiler (Chromium issue 376194).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-05-22: Version 3.27.10
 
         Implement Mirror object for Symbols (issue 3290).
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 306a0ef..7fc193d 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -219,19 +219,20 @@
 class V8_EXPORT HeapGraphNode {
  public:
   enum Type {
-    kHidden = 0,        // Hidden node, may be filtered when shown to user.
-    kArray = 1,         // An array of elements.
-    kString = 2,        // A string.
-    kObject = 3,        // A JS object (except for arrays and strings).
-    kCode = 4,          // Compiled code.
-    kClosure = 5,       // Function closure.
-    kRegExp = 6,        // RegExp.
-    kHeapNumber = 7,    // Number stored in the heap.
-    kNative = 8,        // Native object (not from V8 heap).
-    kSynthetic = 9,     // Synthetic object, usualy used for grouping
-                        // snapshot items together.
-    kConsString = 10,   // Concatenated string. A pair of pointers to strings.
-    kSlicedString = 11  // Sliced string. A fragment of another string.
+    kHidden = 0,         // Hidden node, may be filtered when shown to user.
+    kArray = 1,          // An array of elements.
+    kString = 2,         // A string.
+    kObject = 3,         // A JS object (except for arrays and strings).
+    kCode = 4,           // Compiled code.
+    kClosure = 5,        // Function closure.
+    kRegExp = 6,         // RegExp.
+    kHeapNumber = 7,     // Number stored in the heap.
+    kNative = 8,         // Native object (not from V8 heap).
+    kSynthetic = 9,      // Synthetic object, usualy used for grouping
+                         // snapshot items together.
+    kConsString = 10,    // Concatenated string. A pair of pointers to strings.
+    kSlicedString = 11,  // Sliced string. A fragment of another string.
+    kSymbol = 12         // A Symbol (ES6).
   };
 
   /** Returns node type (see HeapGraphNode::Type). */
diff --git a/include/v8.h b/include/v8.h
index 8c2aaf9..bfd3de0 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2097,7 +2097,7 @@
 
   bool Set(uint32_t index, Handle<Value> value);
 
-  // Sets a local property on this object bypassing interceptors and
+  // Sets an own property on this object bypassing interceptors and
   // overriding accessors or read-only properties.
   //
   // Note that if the object has an interceptor the property will be set
diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc
index 6f8fd35..edb0ba0 100644
--- a/samples/lineprocessor.cc
+++ b/samples/lineprocessor.cc
@@ -69,25 +69,6 @@
   var res = line + " | " + line;
   print(res);
 }
-
- *
- * When run with "-p" argument, the program starts V8 Debugger Agent and
- * allows remote debugger to attach and debug JavaScript code.
- *
- * Interesting aspects:
- * 1. Wait for remote debugger to attach
- * Normally the program compiles custom script and immediately runs it.
- * If programmer needs to debug script from the very beginning, he should
- * run this sample program with "--wait-for-connection" command line parameter.
- * This way V8 will suspend on the first statement and wait for
- * debugger to attach.
- *
- * 2. Unresponsive V8
- * V8 Debugger Agent holds a connection with remote debugger, but it does
- * respond only when V8 is running some script. In particular, when this program
- * is waiting for input, all requests from debugger get deferred until V8
- * is called again. See how "--callback" command-line parameter in this sample
- * fixes this issue.
  */
 
 enum MainCycleType {
@@ -113,7 +94,6 @@
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
   v8::Isolate* isolate = v8::Isolate::New();
   v8::Isolate::Scope isolate_scope(isolate);
-  v8::Locker locker(isolate);
   v8::HandleScope handle_scope(isolate);
 
   v8::Handle<v8::String> script_source;
@@ -224,7 +204,6 @@
                  v8::Local<v8::Context> context,
                  bool report_exceptions) {
   v8::Isolate* isolate = context->GetIsolate();
-  v8::Locker lock(isolate);
 
   v8::Handle<v8::String> fun_name =
       v8::String::NewFromUtf8(isolate, "ProcessLine");
@@ -382,7 +361,6 @@
 
   char* res;
   {
-    v8::Unlocker unlocker(v8::Isolate::GetCurrent());
     res = fgets(buffer, kBufferSize, stdin);
   }
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
diff --git a/src/accessors.cc b/src/accessors.cc
index 6f2c01b..6245613 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -183,7 +183,7 @@
   // causes an infinite loop.
   if (!object->IsJSArray()) {
     MaybeHandle<Object> maybe_result =
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             object, isolate->factory()->length_string(), value, NONE);
     maybe_result.Check();
     return;
@@ -790,7 +790,7 @@
   if (!function->should_have_prototype()) {
     // Since we hit this accessor, object will have no prototype property.
     MaybeHandle<Object> maybe_result =
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             receiver, isolate->factory()->prototype_string(), value, NONE);
     return maybe_result.ToHandleChecked();
   }
diff --git a/src/api.cc b/src/api.cc
index 304d84f..c33365b 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5,10 +5,10 @@
 #include "api.h"
 
 #include <string.h>  // For memcpy, strlen.
-#include <cmath>  // For isnan.
 #ifdef V8_USE_ADDRESS_SANITIZER
 #include <sanitizer/asan_interface.h>
 #endif  // V8_USE_ADDRESS_SANITIZER
+#include <cmath>  // For isnan.
 #include "../include/v8-debug.h"
 #include "../include/v8-profiler.h"
 #include "../include/v8-testing.h"
@@ -1750,12 +1750,10 @@
     Source* source,
     CompileOptions options) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
-  ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()",
-             return Local<Script>());
+  ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
   LOG_API(isolate, "ScriptCompiler::CompiletBound()");
   ENTER_V8(isolate);
-  Local<UnboundScript> generic =
-      CompileUnbound(v8_isolate, source, options);
+  Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options);
   if (generic.IsEmpty()) return Local<Script>();
   return generic->BindToCurrentContext();
 }
@@ -3059,8 +3057,8 @@
 
 
 bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
-  return Set(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
-             value, DontEnum);
+  return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
+                  value, DontEnum);
 }
 
 
@@ -3147,8 +3145,7 @@
 
 Local<Value> v8::Object::GetPrototype() {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-  ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
-             return Local<v8::Value>());
+  ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>());
   ENTER_V8(isolate);
   i::Handle<i::Object> self = Utils::OpenHandle(this);
   i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
@@ -3224,7 +3221,7 @@
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::FixedArray> value;
   has_pending_exception = !i::JSReceiver::GetKeys(
-      self, i::JSReceiver::LOCAL_ONLY).ToHandle(&value);
+      self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
   // Because we use caching to speed up enumeration it is important
   // to never change the result of the basic enumeration function so
@@ -3349,6 +3346,8 @@
 
 
 bool v8::Object::HasPrivate(v8::Handle<Private> key) {
+  // TODO(rossberg): this should use HasOwnProperty, but we'd need to
+  // generalise that to a (noy yet existant) Name argument first.
   return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
 }
 
@@ -3452,7 +3451,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
              return false);
-  return i::JSReceiver::HasLocalProperty(
+  return i::JSReceiver::HasOwnProperty(
       Utils::OpenHandle(this), Utils::OpenHandle(*key));
 }
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index afea875..585108b 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -2934,11 +2934,13 @@
 }
 
 
-void CallFunctionStub::Generate(MacroAssembler* masm) {
+static void CallFunctionNoFeedback(MacroAssembler* masm,
+                                   int argc, bool needs_checks,
+                                   bool call_as_method) {
   // r1 : the function to call
   Label slow, non_function, wrap, cont;
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Check that the function is really a JavaScript function.
     // r1: pushed function (to be verified)
     __ JumpIfSmi(r1, &non_function);
@@ -2950,18 +2952,17 @@
 
   // Fast-case: Invoke the function now.
   // r1: pushed function
-  int argc = argc_;
   ParameterCount actual(argc);
 
-  if (CallAsMethod()) {
-    if (NeedsChecks()) {
+  if (call_as_method) {
+    if (needs_checks) {
       EmitContinueIfStrictOrNative(masm, &cont);
     }
 
     // Compute the receiver in sloppy mode.
     __ ldr(r3, MemOperand(sp, argc * kPointerSize));
 
-    if (NeedsChecks()) {
+    if (needs_checks) {
       __ JumpIfSmi(r3, &wrap);
       __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
       __ b(lt, &wrap);
@@ -2974,19 +2975,24 @@
 
   __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Slow-case: Non-function called.
     __ bind(&slow);
     EmitSlowCase(masm, argc, &non_function);
   }
 
-  if (CallAsMethod()) {
+  if (call_as_method) {
     __ bind(&wrap);
     EmitWrapCase(masm, argc, &cont);
   }
 }
 
 
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+}
+
+
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // r0 : number of arguments
   // r1 : the function to call
@@ -3046,7 +3052,7 @@
   __ bind(&do_call);
   // Set expected number of arguments to zero (not changing r0).
   __ mov(r2, Operand::Zero());
-  __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
 }
 
@@ -3060,6 +3066,51 @@
 }
 
 
+void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
+  // r1 - function
+  // r2 - feedback vector
+  // r3 - slot id
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
+  __ cmp(r1, r4);
+  __ b(ne, miss);
+
+  __ mov(r0, Operand(arg_count()));
+  __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
+  __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize));
+  // Verify that r2 contains an AllocationSite
+  __ AssertUndefinedOrAllocationSite(r2, r4);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+}
+
+
+void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
+  // r1 - function
+  // r2 - feedback vector
+  // r3 - slot id
+  Label miss;
+
+  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
+    Generate_MonomorphicArray(masm, &miss);
+  } else {
+    // So far there is only one customer for our custom feedback scheme.
+    UNREACHABLE();
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm,
+                         arg_count(),
+                         true,
+                         CallAsMethod());
+
+  // Unreachable.
+  __ stop("Unexpected code address");
+}
+
+
 void CallICStub::Generate(MacroAssembler* masm) {
   // r1 - function
   // r3 - slot id (Smi)
@@ -3071,6 +3122,11 @@
 
   EmitLoadTypeFeedbackVector(masm, r2);
 
+  if (state_.stub_type() != CallIC::DEFAULT) {
+    Generate_CustomFeedbackCall(masm);
+    return;
+  }
+
   // The checks. First, does r1 match the recorded monomorphic target?
   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
   __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
index c3270f0..0325774 100644
--- a/src/arm/debug-arm.cc
+++ b/src/arm/debug-arm.cc
@@ -148,7 +148,7 @@
   // jumping to the target address intended by the caller and that was
   // overwritten by the address of DebugBreakXXX.
   ExternalReference after_break_target =
-      ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate());
+      ExternalReference::debug_after_break_target_address(masm->isolate());
   __ mov(ip, Operand(after_break_target));
   __ ldr(ip, MemOperand(ip));
   __ Jump(ip);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 7a4de9f..1e54695 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -337,7 +337,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d]", additional_index());
+    stream->Add(" + %d]", base_offset());
   } else {
     stream->Add("]");
   }
@@ -349,7 +349,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d] <-", additional_index());
+    stream->Add(" + %d] <-", base_offset());
   } else {
     stream->Add("] <- ");
   }
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index b333095..714ec55 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -1648,7 +1648,7 @@
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
 
@@ -2223,7 +2223,7 @@
     }
     return hydrogen()->NeedsCanonicalization();
   }
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 623a9dc..d2e665e 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3168,17 +3168,13 @@
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
   int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
       ? (element_size_shift - kSmiTagSize) : element_size_shift;
-  int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
-      ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-      : 0;
-
+  int base_offset = instr->base_offset();
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS ||
       elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
       elements_kind == FLOAT64_ELEMENTS) {
-    int base_offset =
-      (instr->additional_index() << element_size_shift) + additional_offset;
+    int base_offset = instr->base_offset();
     DwVfpRegister result = ToDoubleRegister(instr->result());
     Operand operand = key_is_constant
         ? Operand(constant_key << element_size_shift)
@@ -3188,15 +3184,14 @@
         elements_kind == FLOAT32_ELEMENTS) {
       __ vldr(double_scratch0().low(), scratch0(), base_offset);
       __ vcvt_f64_f32(result, double_scratch0().low());
-    } else  {  // loading doubles, not floats.
+    } else  {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
       __ vldr(result, scratch0(), base_offset);
     }
   } else {
     Register result = ToRegister(instr->result());
     MemOperand mem_operand = PrepareKeyedOperand(
         key, external_pointer, key_is_constant, constant_key,
-        element_size_shift, shift_size,
-        instr->additional_index(), additional_offset);
+        element_size_shift, shift_size, base_offset);
     switch (elements_kind) {
       case EXTERNAL_INT8_ELEMENTS:
       case INT8_ELEMENTS:
@@ -3256,15 +3251,13 @@
 
   int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
 
-  int base_offset =
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag +
-      (instr->additional_index() << element_size_shift);
+  int base_offset = instr->base_offset();
   if (key_is_constant) {
     int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
     if (constant_key & 0xF0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    base_offset += constant_key << element_size_shift;
+    base_offset += constant_key * kDoubleSize;
   }
   __ add(scratch, elements, Operand(base_offset));
 
@@ -3290,12 +3283,11 @@
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
   Register store_base = scratch;
-  int offset = 0;
+  int offset = instr->base_offset();
 
   if (instr->key()->IsConstantOperand()) {
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                           instr->additional_index());
+    offset += ToInteger32(const_operand) * kPointerSize;
     store_base = elements;
   } else {
     Register key = ToRegister(instr->key());
@@ -3308,9 +3300,8 @@
     } else {
       __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
     }
-    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
   }
-  __ ldr(result, FieldMemOperand(store_base, offset));
+  __ ldr(result, MemOperand(store_base, offset));
 
   // Check for the hole value.
   if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3343,32 +3334,12 @@
                                          int constant_key,
                                          int element_size,
                                          int shift_size,
-                                         int additional_index,
-                                         int additional_offset) {
-  int base_offset = (additional_index << element_size) + additional_offset;
+                                         int base_offset) {
   if (key_is_constant) {
-    return MemOperand(base,
-                      base_offset + (constant_key << element_size));
+    return MemOperand(base, (constant_key << element_size) + base_offset);
   }
 
-  if (additional_offset != 0) {
-    __ mov(scratch0(), Operand(base_offset));
-    if (shift_size >= 0) {
-      __ add(scratch0(), scratch0(), Operand(key, LSL, shift_size));
-    } else {
-      ASSERT_EQ(-1, shift_size);
-      // key can be negative, so using ASR here.
-      __ add(scratch0(), scratch0(), Operand(key, ASR, 1));
-    }
-    return MemOperand(base, scratch0());
-  }
-
-  if (additional_index != 0) {
-    additional_index *= 1 << (element_size - shift_size);
-    __ add(scratch0(), key, Operand(additional_index));
-  }
-
-  if (additional_index == 0) {
+  if (base_offset == 0) {
     if (shift_size >= 0) {
       return MemOperand(base, key, LSL, shift_size);
     } else {
@@ -3378,10 +3349,12 @@
   }
 
   if (shift_size >= 0) {
-    return MemOperand(base, scratch0(), LSL, shift_size);
+    __ add(scratch0(), base, Operand(key, LSL, shift_size));
+    return MemOperand(scratch0(), base_offset);
   } else {
     ASSERT_EQ(-1, shift_size);
-    return MemOperand(base, scratch0(), LSR, 1);
+    __ add(scratch0(), base, Operand(key, ASR, 1));
+    return MemOperand(scratch0(), base_offset);
   }
 }
 
@@ -4211,16 +4184,12 @@
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
   int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
       ? (element_size_shift - kSmiTagSize) : element_size_shift;
-  int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
-      ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-      : 0;
+  int base_offset = instr->base_offset();
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS ||
       elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
       elements_kind == FLOAT64_ELEMENTS) {
-    int base_offset =
-      (instr->additional_index() << element_size_shift) + additional_offset;
     Register address = scratch0();
     DwVfpRegister value(ToDoubleRegister(instr->value()));
     if (key_is_constant) {
@@ -4245,7 +4214,7 @@
     MemOperand mem_operand = PrepareKeyedOperand(
         key, external_pointer, key_is_constant, constant_key,
         element_size_shift, shift_size,
-        instr->additional_index(), additional_offset);
+        base_offset);
     switch (elements_kind) {
       case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
       case EXTERNAL_INT8_ELEMENTS:
@@ -4292,6 +4261,7 @@
   Register scratch = scratch0();
   DwVfpRegister double_scratch = double_scratch0();
   bool key_is_constant = instr->key()->IsConstantOperand();
+  int base_offset = instr->base_offset();
 
   // Calculate the effective address of the slot in the array to store the
   // double value.
@@ -4302,13 +4272,11 @@
       Abort(kArrayIndexConstantValueTooBig);
     }
     __ add(scratch, elements,
-           Operand((constant_key << element_size_shift) +
-                   FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+           Operand((constant_key << element_size_shift) + base_offset));
   } else {
     int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
         ? (element_size_shift - kSmiTagSize) : element_size_shift;
-    __ add(scratch, elements,
-           Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+    __ add(scratch, elements, Operand(base_offset));
     __ add(scratch, scratch,
            Operand(ToRegister(instr->key()), LSL, shift_size));
   }
@@ -4321,10 +4289,9 @@
       __ Assert(ne, kDefaultNaNModeNotSet);
     }
     __ VFPCanonicalizeNaN(double_scratch, value);
-    __ vstr(double_scratch, scratch,
-            instr->additional_index() << element_size_shift);
+    __ vstr(double_scratch, scratch, 0);
   } else {
-    __ vstr(value, scratch, instr->additional_index() << element_size_shift);
+    __ vstr(value, scratch, 0);
   }
 }
 
@@ -4336,14 +4303,13 @@
       : no_reg;
   Register scratch = scratch0();
   Register store_base = scratch;
-  int offset = 0;
+  int offset = instr->base_offset();
 
   // Do the store.
   if (instr->key()->IsConstantOperand()) {
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                           instr->additional_index());
+    offset += ToInteger32(const_operand) * kPointerSize;
     store_base = elements;
   } else {
     // Even though the HLoadKeyed instruction forces the input
@@ -4355,16 +4321,15 @@
     } else {
       __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
     }
-    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
   }
-  __ str(value, FieldMemOperand(store_base, offset));
+  __ str(value, MemOperand(store_base, offset));
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
     SmiCheck check_needed =
         instr->hydrogen()->value()->IsHeapObject()
             ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
-    __ add(key, store_base, Operand(offset - kHeapObjectTag));
+    __ add(key, store_base, Operand(offset));
     __ RecordWrite(elements,
                    key,
                    value,
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index 3e05c32..d541b8e 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -133,8 +133,7 @@
                                  int constant_key,
                                  int element_size,
                                  int shift_size,
-                                 int additional_index,
-                                 int additional_offset);
+                                 int base_offset);
 
   // Emit frame translation commands for an environment.
   void WriteTranslation(LEnvironment* environment, Translation* translation);
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index 0bf89d8..d1185b2 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -3217,10 +3217,10 @@
 }
 
 
-void CallFunctionStub::Generate(MacroAssembler* masm) {
-  ASM_LOCATION("CallFunctionStub::Generate");
+static void CallFunctionNoFeedback(MacroAssembler* masm,
+                                   int argc, bool needs_checks,
+                                   bool call_as_method) {
   // x1  function    the function to call
-
   Register function = x1;
   Register type = x4;
   Label slow, non_function, wrap, cont;
@@ -3228,7 +3228,7 @@
   // TODO(jbramley): This function has a lot of unnamed registers. Name them,
   // and tidy things up a bit.
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Check that the function is really a JavaScript function.
     __ JumpIfSmi(function, &non_function);
 
@@ -3238,18 +3238,17 @@
 
   // Fast-case: Invoke the function now.
   // x1  function  pushed function
-  int argc = argc_;
   ParameterCount actual(argc);
 
-  if (CallAsMethod()) {
-    if (NeedsChecks()) {
+  if (call_as_method) {
+    if (needs_checks) {
       EmitContinueIfStrictOrNative(masm, &cont);
     }
 
     // Compute the receiver in sloppy mode.
     __ Peek(x3, argc * kPointerSize);
 
-    if (NeedsChecks()) {
+    if (needs_checks) {
       __ JumpIfSmi(x3, &wrap);
       __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
     } else {
@@ -3263,20 +3262,25 @@
                     actual,
                     JUMP_FUNCTION,
                     NullCallWrapper());
-
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Slow-case: Non-function called.
     __ Bind(&slow);
     EmitSlowCase(masm, argc, function, type, &non_function);
   }
 
-  if (CallAsMethod()) {
+  if (call_as_method) {
     __ Bind(&wrap);
     EmitWrapCase(masm, argc, &cont);
   }
 }
 
 
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  ASM_LOCATION("CallFunctionStub::Generate");
+  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+}
+
+
 void CallConstructStub::Generate(MacroAssembler* masm) {
   ASM_LOCATION("CallConstructStub::Generate");
   // x0 : number of arguments
@@ -3356,6 +3360,59 @@
 }
 
 
+void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
+  // x1 - function
+  // x2 - feedback vector
+  // x3 - slot id
+  Register function = x1;
+  Register feedback_vector = x2;
+  Register index = x3;
+  Register scratch = x4;
+
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch);
+  __ Cmp(function, scratch);
+  __ B(ne, miss);
+
+  Register allocation_site = feedback_vector;
+  __ Mov(x0, Operand(arg_count()));
+
+  __ Add(scratch, feedback_vector,
+         Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+  __ Ldr(allocation_site, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+
+  // Verify that x2 contains an AllocationSite
+  __ AssertUndefinedOrAllocationSite(allocation_site, scratch);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+}
+
+
+void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
+  // x1 - function
+  // x2 - feedback vector
+  // x3 - slot id
+  Label miss;
+
+  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
+    Generate_MonomorphicArray(masm, &miss);
+  } else {
+    // So far there is only one customer for our custom feedback scheme.
+    UNREACHABLE();
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm,
+                         arg_count(),
+                         true,
+                         CallAsMethod());
+
+  __ Unreachable();
+}
+
+
 void CallICStub::Generate(MacroAssembler* masm) {
   ASM_LOCATION("CallICStub");
 
@@ -3374,6 +3431,11 @@
 
   EmitLoadTypeFeedbackVector(masm, feedback_vector);
 
+  if (state_.stub_type() != CallIC::DEFAULT) {
+    Generate_CustomFeedbackCall(masm);
+    return;
+  }
+
   // The checks. First, does x1 match the recorded monomorphic target?
   __ Add(x4, feedback_vector,
          Operand::UntagSmiAndScale(index, kPointerSizeLog2));
diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc
index 6b18967..e781c28 100644
--- a/src/arm64/debug-arm64.cc
+++ b/src/arm64/debug-arm64.cc
@@ -207,8 +207,8 @@
   // Now that the break point has been handled, resume normal execution by
   // jumping to the target address intended by the caller and that was
   // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target(Debug_Address::AfterBreakTarget(),
-                                       masm->isolate());
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
   __ Mov(scratch, after_break_target);
   __ Ldr(scratch, MemOperand(scratch));
   __ Br(scratch);
diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
index 85629c4..7bd2c5ad 100644
--- a/src/arm64/lithium-arm64.h
+++ b/src/arm64/lithium-arm64.h
@@ -1757,15 +1757,15 @@
   bool is_typed_elements() const {
     return is_external() || is_fixed_typed_array();
   }
-  uint32_t additional_index() const {
-    return this->hydrogen()->index_offset();
+  uint32_t base_offset() const {
+    return this->hydrogen()->base_offset();
   }
   void PrintDataTo(StringStream* stream) V8_OVERRIDE {
     this->elements()->PrintTo(stream);
     stream->Add("[");
     this->key()->PrintTo(stream);
-    if (this->hydrogen()->IsDehoisted()) {
-      stream->Add(" + %d]", this->additional_index());
+    if (this->base_offset() != 0) {
+      stream->Add(" + %d]", this->base_offset());
     } else {
       stream->Add("]");
     }
@@ -2419,14 +2419,14 @@
     }
     return this->hydrogen()->NeedsCanonicalization();
   }
-  uint32_t additional_index() const { return this->hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return this->hydrogen()->base_offset(); }
 
   void PrintDataTo(StringStream* stream) V8_OVERRIDE {
     this->elements()->PrintTo(stream);
     stream->Add("[");
     this->key()->PrintTo(stream);
-    if (this->hydrogen()->IsDehoisted()) {
-      stream->Add(" + %d] <-", this->additional_index());
+    if (this->base_offset() != 0) {
+      stream->Add(" + %d] <-", this->base_offset());
     } else {
       stream->Add("] <- ");
     }
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index dab60e5..4ecc434 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -3373,29 +3373,25 @@
     bool key_is_constant,
     int constant_key,
     ElementsKind elements_kind,
-    int additional_index) {
+    int base_offset) {
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
-  int additional_offset = additional_index << element_size_shift;
-  if (IsFixedTypedArrayElementsKind(elements_kind)) {
-    additional_offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
-  }
 
   if (key_is_constant) {
     int key_offset = constant_key << element_size_shift;
-    return MemOperand(base, key_offset + additional_offset);
+    return MemOperand(base, key_offset + base_offset);
   }
 
   if (key_is_smi) {
     __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift));
-    return MemOperand(scratch, additional_offset);
+    return MemOperand(scratch, base_offset);
   }
 
-  if (additional_offset == 0) {
+  if (base_offset == 0) {
     return MemOperand(base, key, SXTW, element_size_shift);
   }
 
   ASSERT(!AreAliased(scratch, key));
-  __ Add(scratch, base, additional_offset);
+  __ Add(scratch, base, base_offset);
   return MemOperand(scratch, key, SXTW, element_size_shift);
 }
 
@@ -3424,7 +3420,7 @@
       PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi,
                                        key_is_constant, constant_key,
                                        elements_kind,
-                                       instr->additional_index());
+                                       instr->base_offset());
 
   if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) ||
       (elements_kind == FLOAT32_ELEMENTS)) {
@@ -3495,7 +3491,7 @@
                                               bool key_is_tagged,
                                               ElementsKind elements_kind,
                                               Representation representation,
-                                              int additional_index) {
+                                              int base_offset) {
   STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0));
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
 
@@ -3509,9 +3505,9 @@
       ASSERT(elements_kind == FAST_SMI_ELEMENTS);
       // Read or write only the most-significant 32 bits in the case of fast smi
       // arrays.
-      return UntagSmiFieldMemOperand(base, additional_index);
+      return UntagSmiMemOperand(base, base_offset);
     } else {
-      return FieldMemOperand(base, additional_index);
+      return MemOperand(base, base_offset);
     }
   } else {
     // Sign extend key because it could be a 32-bit negative value or contain
@@ -3522,9 +3518,9 @@
       // Read or write only the most-significant 32 bits in the case of fast smi
       // arrays.
       __ Add(base, elements, Operand(key, SXTW, element_size_shift));
-      return UntagSmiFieldMemOperand(base, additional_index);
+      return UntagSmiMemOperand(base, base_offset);
     } else {
-      __ Add(base, elements, additional_index - kHeapObjectTag);
+      __ Add(base, elements, base_offset);
       return MemOperand(base, key, SXTW, element_size_shift);
     }
   }
@@ -3544,18 +3540,16 @@
     if (constant_key & 0xf0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    int offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
-                                                     instr->additional_index());
-    mem_op = FieldMemOperand(elements, offset);
+    int offset = instr->base_offset() + constant_key * kDoubleSize;
+    mem_op = MemOperand(elements, offset);
   } else {
     Register load_base = ToRegister(instr->temp());
     Register key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
-    int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
     mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged,
                                       instr->hydrogen()->elements_kind(),
                                       instr->hydrogen()->representation(),
-                                      offset);
+                                      instr->base_offset());
   }
 
   __ Ldr(result, mem_op);
@@ -3581,25 +3575,24 @@
   if (instr->key()->IsConstantOperand()) {
     ASSERT(instr->temp() == NULL);
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                               instr->additional_index());
+    int offset = instr->base_offset() +
+        ToInteger32(const_operand) * kPointerSize;
     if (representation.IsInteger32()) {
       ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
       STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) &&
                     (kSmiTag == 0));
-      mem_op = UntagSmiFieldMemOperand(elements, offset);
+      mem_op = UntagSmiMemOperand(elements, offset);
     } else {
-      mem_op = FieldMemOperand(elements, offset);
+      mem_op = MemOperand(elements, offset);
     }
   } else {
     Register load_base = ToRegister(instr->temp());
     Register key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
-    int offset = FixedArray::OffsetOfElementAt(instr->additional_index());
 
     mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged,
                                       instr->hydrogen()->elements_kind(),
-                                      representation, offset);
+                                      representation, instr->base_offset());
   }
 
   __ Load(result, mem_op, representation);
@@ -5137,7 +5130,7 @@
     PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi,
                                      key_is_constant, constant_key,
                                      elements_kind,
-                                     instr->additional_index());
+                                     instr->base_offset());
 
   if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) ||
       (elements_kind == FLOAT32_ELEMENTS)) {
@@ -5202,18 +5195,16 @@
     if (constant_key & 0xf0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    int offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
-                                                     instr->additional_index());
-    mem_op = FieldMemOperand(elements, offset);
+    int offset = instr->base_offset() + constant_key * kDoubleSize;
+    mem_op = MemOperand(elements, offset);
   } else {
     Register store_base = ToRegister(instr->temp());
     Register key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
-    int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
     mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged,
                                       instr->hydrogen()->elements_kind(),
                                       instr->hydrogen()->representation(),
-                                      offset);
+                                      instr->base_offset());
   }
 
   if (instr->NeedsCanonicalization()) {
@@ -5241,27 +5232,26 @@
   Representation representation = instr->hydrogen()->value()->representation();
   if (instr->key()->IsConstantOperand()) {
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                               instr->additional_index());
+    int offset = instr->base_offset() +
+        ToInteger32(const_operand) * kPointerSize;
     store_base = elements;
     if (representation.IsInteger32()) {
       ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
       ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
       STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) &&
                     (kSmiTag == 0));
-      mem_op = UntagSmiFieldMemOperand(store_base, offset);
+      mem_op = UntagSmiMemOperand(store_base, offset);
     } else {
-      mem_op = FieldMemOperand(store_base, offset);
+      mem_op = MemOperand(store_base, offset);
     }
   } else {
     store_base = scratch;
     key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
-    int offset = FixedArray::OffsetOfElementAt(instr->additional_index());
 
     mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged,
                                       instr->hydrogen()->elements_kind(),
-                                      representation, offset);
+                                      representation, instr->base_offset());
   }
 
   __ Store(value, mem_op, representation);
diff --git a/src/arm64/lithium-codegen-arm64.h b/src/arm64/lithium-codegen-arm64.h
index 8c25e63..6ee2ec8 100644
--- a/src/arm64/lithium-codegen-arm64.h
+++ b/src/arm64/lithium-codegen-arm64.h
@@ -255,14 +255,14 @@
                                               bool key_is_constant,
                                               int constant_key,
                                               ElementsKind elements_kind,
-                                              int additional_index);
+                                              int base_offset);
   MemOperand PrepareKeyedArrayOperand(Register base,
                                       Register elements,
                                       Register key,
                                       bool key_is_tagged,
                                       ElementsKind elements_kind,
                                       Representation representation,
-                                      int additional_index);
+                                      int base_offset);
 
   void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
                                             Safepoint::DeoptMode mode);
diff --git a/src/array.js b/src/array.js
index 5b036e6..ef7aae4 100644
--- a/src/array.js
+++ b/src/array.js
@@ -271,7 +271,7 @@
 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
   for (var i = 0; i < del_count; i++) {
     var index = start_i + i;
-    // The spec could also be interpreted such that %HasLocalProperty
+    // The spec could also be interpreted such that %HasOwnProperty
     // would be the appropriate test.  We follow KJS in consulting the
     // prototype.
     var current = array[index];
@@ -291,7 +291,7 @@
         var from_index = i + del_count - 1;
         var to_index = i + num_additional_args - 1;
         // The spec could also be interpreted such that
-        // %HasLocalProperty would be the appropriate test.  We follow
+        // %HasOwnProperty would be the appropriate test.  We follow
         // KJS in consulting the prototype.
         var current = array[from_index];
         if (!IS_UNDEFINED(current) || from_index in array) {
@@ -305,7 +305,7 @@
         var from_index = i + del_count;
         var to_index = i + num_additional_args;
         // The spec could also be interpreted such that
-        // %HasLocalProperty would be the appropriate test.  We follow
+        // %HasOwnProperty would be the appropriate test.  We follow
         // KJS in consulting the prototype.
         var current = array[from_index];
         if (!IS_UNDEFINED(current) || from_index in array) {
@@ -628,7 +628,7 @@
   var num_arguments = %_ArgumentsLength();
   var is_sealed = ObjectIsSealed(array);
 
-  if (IS_ARRAY(array) && !is_sealed) {
+  if (IS_ARRAY(array) && !is_sealed && len > 0) {
     SmartMove(array, 0, 0, len, num_arguments);
   } else {
     SimpleMove(array, 0, 0, len, num_arguments);
@@ -1075,7 +1075,7 @@
     // For compatibility with JSC, we also sort elements inherited from
     // the prototype chain on non-Array objects.
     // We do this by copying them to this object and sorting only
-    // local elements. This is not very efficient, but sorting with
+    // own elements. This is not very efficient, but sorting with
     // inherited elements happens very, very rarely, if at all.
     // The specification allows "implementation dependent" behavior
     // if an element on the prototype chain has an element that
diff --git a/src/assembler.cc b/src/assembler.cc
index 103ca13..3cb4929 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -124,7 +124,8 @@
       enabled_cpu_features_(0),
       emit_debug_code_(FLAG_debug_code),
       predictable_code_size_(false),
-      serializer_enabled_(Serializer::enabled(isolate)) {
+      // We may use the assembler without an isolate.
+      serializer_enabled_(isolate && isolate->serializer_enabled()) {
   if (FLAG_mask_constants_with_cookie && isolate != NULL)  {
     jit_cookie_ = isolate->random_number_generator()->NextInt();
   }
@@ -996,9 +997,6 @@
                                      Isolate* isolate)
   : address_(Redirect(isolate, ic_utility.address())) {}
 
-ExternalReference::ExternalReference(const Debug_Address& debug_address,
-                                     Isolate* isolate)
-  : address_(debug_address.address(isolate)) {}
 
 ExternalReference::ExternalReference(StatsCounter* counter)
   : address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
@@ -1431,6 +1429,20 @@
 }
 
 
+ExternalReference ExternalReference::debug_after_break_target_address(
+    Isolate* isolate) {
+  return ExternalReference(isolate->debug()->after_break_target_address());
+}
+
+
+ExternalReference
+    ExternalReference::debug_restarter_frame_function_pointer_address(
+        Isolate* isolate) {
+  return ExternalReference(
+      isolate->debug()->restarter_frame_function_pointer_address());
+}
+
+
 double power_helper(double x, double y) {
   int y_int = static_cast<int>(y);
   if (y == y_int) {
diff --git a/src/assembler.h b/src/assembler.h
index 6d67fc1..2d9bde6 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -794,8 +794,6 @@
 
   ExternalReference(const IC_Utility& ic_utility, Isolate* isolate);
 
-  ExternalReference(const Debug_Address& debug_address, Isolate* isolate);
-
   explicit ExternalReference(StatsCounter* counter);
 
   ExternalReference(Isolate::AddressId id, Isolate* isolate);
@@ -915,6 +913,10 @@
 
   static ExternalReference cpu_features();
 
+  static ExternalReference debug_after_break_target_address(Isolate* isolate);
+  static ExternalReference debug_restarter_frame_function_pointer_address(
+      Isolate* isolate);
+
   static ExternalReference is_profiling_address(Isolate* isolate);
   static ExternalReference invoke_function_callback(Isolate* isolate);
   static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
diff --git a/src/ast.h b/src/ast.h
index 0115d98..e2ea933 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1762,11 +1762,25 @@
     return !target_.is_null();
   }
 
+  bool global_call() const {
+    VariableProxy* proxy = expression_->AsVariableProxy();
+    return proxy != NULL && proxy->var()->IsUnallocated();
+  }
+
+  bool known_global_function() const {
+    return global_call() && !target_.is_null();
+  }
+
   Handle<JSFunction> target() { return target_; }
 
   Handle<Cell> cell() { return cell_; }
 
+  Handle<AllocationSite> allocation_site() { return allocation_site_; }
+
   void set_target(Handle<JSFunction> target) { target_ = target; }
+  void set_allocation_site(Handle<AllocationSite> site) {
+    allocation_site_ = site;
+  }
   bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
 
   BailoutId ReturnId() const { return return_id_; }
@@ -1809,6 +1823,7 @@
 
   Handle<JSFunction> target_;
   Handle<Cell> cell_;
+  Handle<AllocationSite> allocation_site_;
   int call_feedback_slot_;
 
   const BailoutId return_id_;
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 551a04a..0803522 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -371,7 +371,7 @@
   } else {
     attributes = DONT_ENUM;
   }
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       target, internalized_name, function, attributes).Check();
   if (target->IsJSGlobalObject()) {
     function->shared()->set_instance_class_name(*internalized_name);
@@ -748,7 +748,7 @@
     Handle<JSObject> prototype =
         Handle<JSObject>(
             JSObject::cast(js_global_function->instance_prototype()));
-    JSObject::SetLocalPropertyIgnoreAttributes(
+    JSObject::SetOwnPropertyIgnoreAttributes(
         prototype, factory()->constructor_string(),
         isolate()->object_function(), NONE).Check();
   } else {
@@ -863,7 +863,7 @@
   Heap* heap = isolate->heap();
 
   Handle<String> object_name = factory->Object_string();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       inner_global, object_name,
       isolate->object_function(), DONT_ENUM).Check();
 
@@ -1064,7 +1064,7 @@
     cons->SetInstanceClassName(*name);
     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
     ASSERT(json_object->IsJSObject());
-    JSObject::SetLocalPropertyIgnoreAttributes(
+    JSObject::SetOwnPropertyIgnoreAttributes(
         global, name, json_object, DONT_ENUM).Check();
     native_context()->set_json_object(*json_object);
   }
@@ -1130,22 +1130,22 @@
     native_context()->set_sloppy_arguments_boilerplate(*result);
     // Note: length must be added as the first property and
     //       callee must be added as the second property.
-    JSObject::SetLocalPropertyIgnoreAttributes(
+    JSObject::SetOwnPropertyIgnoreAttributes(
         result, factory->length_string(),
         factory->undefined_value(), DONT_ENUM,
         Object::FORCE_TAGGED, FORCE_FIELD).Check();
-    JSObject::SetLocalPropertyIgnoreAttributes(
+    JSObject::SetOwnPropertyIgnoreAttributes(
         result, factory->callee_string(),
         factory->undefined_value(), DONT_ENUM,
         Object::FORCE_TAGGED, FORCE_FIELD).Check();
 
 #ifdef DEBUG
     LookupResult lookup(isolate);
-    result->LocalLookup(factory->callee_string(), &lookup);
+    result->LookupOwn(factory->callee_string(), &lookup);
     ASSERT(lookup.IsField());
     ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
 
-    result->LocalLookup(factory->length_string(), &lookup);
+    result->LookupOwn(factory->length_string(), &lookup);
     ASSERT(lookup.IsField());
     ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
 
@@ -1235,13 +1235,13 @@
     native_context()->set_strict_arguments_boilerplate(*result);
 
     // Add length property only for strict mode boilerplate.
-    JSObject::SetLocalPropertyIgnoreAttributes(
+    JSObject::SetOwnPropertyIgnoreAttributes(
         result, factory->length_string(),
         factory->undefined_value(), DONT_ENUM).Check();
 
 #ifdef DEBUG
     LookupResult lookup(isolate);
-    result->LocalLookup(factory->length_string(), &lookup);
+    result->LookupOwn(factory->length_string(), &lookup);
     ASSERT(lookup.IsField());
     ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
 
@@ -1694,11 +1694,11 @@
   Handle<String> global_string =
       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global"));
   Handle<Object> global_obj(native_context()->global_object(), isolate());
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       builtins, global_string, global_obj, attributes).Check();
   Handle<String> builtins_string =
       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       builtins, builtins_string, builtins, attributes).Check();
 
   // Set up the reference from the global object to the builtins object.
@@ -2148,7 +2148,7 @@
         factory->InternalizeUtf8String(FLAG_expose_natives_as);
     RETURN_ON_EXCEPTION_VALUE(
         isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM),
         false);
   }
@@ -2162,7 +2162,7 @@
         Smi::FromInt(FLAG_stack_trace_limit), isolate);
     RETURN_ON_EXCEPTION_VALUE(
         isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE),
         false);
   }
@@ -2183,7 +2183,7 @@
     Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
     RETURN_ON_EXCEPTION_VALUE(
         isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             global, debug_string, global_proxy, DONT_ENUM),
         false);
   }
@@ -2410,7 +2410,7 @@
           ASSERT(!descs->GetDetails(i).representation().IsDouble());
           Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
                                                 isolate());
-          JSObject::SetLocalPropertyIgnoreAttributes(
+          JSObject::SetOwnPropertyIgnoreAttributes(
               to, key, value, details.attributes()).Check();
           break;
         }
@@ -2418,14 +2418,14 @@
           HandleScope inner(isolate());
           Handle<Name> key = Handle<Name>(descs->GetKey(i));
           Handle<Object> constant(descs->GetConstant(i), isolate());
-          JSObject::SetLocalPropertyIgnoreAttributes(
+          JSObject::SetOwnPropertyIgnoreAttributes(
               to, key, constant, details.attributes()).Check();
           break;
         }
         case CALLBACKS: {
           LookupResult result(isolate());
           Handle<Name> key(Name::cast(descs->GetKey(i)), isolate());
-          to->LocalLookup(key, &result);
+          to->LookupOwn(key, &result);
           // If the property is already there we skip it
           if (result.IsFound()) continue;
           HandleScope inner(isolate());
@@ -2458,7 +2458,7 @@
         // If the property is already there we skip it.
         LookupResult result(isolate());
         Handle<Name> key(Name::cast(raw_key));
-        to->LocalLookup(key, &result);
+        to->LookupOwn(key, &result);
         if (result.IsFound()) continue;
         // Set the property.
         Handle<Object> value = Handle<Object>(properties->ValueAt(i),
@@ -2469,7 +2469,7 @@
                                  isolate());
         }
         PropertyDetails details = properties->DetailsAt(i);
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             to, key, value, details.attributes()).Check();
       }
     }
@@ -2522,8 +2522,8 @@
 class NoTrackDoubleFieldsForSerializerScope {
  public:
   explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
-      : isolate_(isolate), flag_(FLAG_track_double_fields) {
-    if (Serializer::enabled(isolate)) {
+      : flag_(FLAG_track_double_fields) {
+    if (isolate->serializer_enabled()) {
       // Disable tracking double fields because heap numbers treated as
       // immutable by the serializer.
       FLAG_track_double_fields = false;
@@ -2531,13 +2531,10 @@
   }
 
   ~NoTrackDoubleFieldsForSerializerScope() {
-    if (Serializer::enabled(isolate_)) {
-      FLAG_track_double_fields = flag_;
-    }
+    FLAG_track_double_fields = flag_;
   }
 
  private:
-  Isolate* isolate_;
   bool flag_;
 };
 
@@ -2614,7 +2611,7 @@
   // We can't (de-)serialize typed arrays currently, but we are lucky: The state
   // of the random number generator needs no initialization during snapshot
   // creation time and we don't need trigonometric functions then.
-  if (!Serializer::enabled(isolate)) {
+  if (!isolate->serializer_enabled()) {
     // Initially seed the per-context random number generator using the
     // per-isolate random number generator.
     const int num_elems = 2;
@@ -2688,7 +2685,7 @@
 }
 
 
-// Archive statics that are thread local.
+// Archive statics that are thread-local.
 char* Bootstrapper::ArchiveState(char* to) {
   *reinterpret_cast<NestingCounterType*>(to) = nesting_;
   nesting_ = 0;
@@ -2696,7 +2693,7 @@
 }
 
 
-// Restore statics that are thread local.
+// Restore statics that are thread-local.
 char* Bootstrapper::RestoreState(char* from) {
   nesting_ = *reinterpret_cast<NestingCounterType*>(from);
   return from + sizeof(NestingCounterType);
diff --git a/src/builtins.cc b/src/builtins.cc
index 50eaa6f..6cdd4a9 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -382,15 +382,17 @@
   }
 
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
+  int len = Smi::cast(array->length())->value();
+  int to_add = args.length() - 1;
+  if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
+    return CallJsBuiltin(isolate, "ArrayPush", args);
+  }
   ASSERT(!array->map()->is_observed());
 
   ElementsKind kind = array->GetElementsKind();
 
   if (IsFastSmiOrObjectElementsKind(kind)) {
     Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
-
-    int len = Smi::cast(array->length())->value();
-    int to_add = args.length() - 1;
     if (to_add == 0) {
       return Smi::FromInt(len);
     }
@@ -429,10 +431,7 @@
     array->set_length(Smi::FromInt(new_length));
     return Smi::FromInt(new_length);
   } else {
-    int len = Smi::cast(array->length())->value();
     int elms_len = elms_obj->length();
-
-    int to_add = args.length() - 1;
     if (to_add == 0) {
       return Smi::FromInt(len);
     }
@@ -578,8 +577,6 @@
   if (!array->HasFastSmiOrObjectElements()) {
     return CallJsBuiltin(isolate, "ArrayUnshift", args);
   }
-  Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
-
   int len = Smi::cast(array->length())->value();
   int to_add = args.length() - 1;
   int new_length = len + to_add;
@@ -587,6 +584,12 @@
   // we should never hit this case.
   ASSERT(to_add <= (Smi::kMaxValue - len));
 
+  if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
+    return CallJsBuiltin(isolate, "ArrayUnshift", args);
+  }
+
+  Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+
   JSObject::EnsureCanContainElements(array, &args, 1, to_add,
                                      DONT_ALLOW_DOUBLE_ELEMENTS);
 
diff --git a/src/code-stubs.h b/src/code-stubs.h
index fbd0c2b..6d77fc3 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -822,6 +822,8 @@
 
   // Code generation helpers.
   void GenerateMiss(MacroAssembler* masm);
+  void Generate_CustomFeedbackCall(MacroAssembler* masm);
+  void Generate_MonomorphicArray(MacroAssembler* masm, Label* miss);
 
   CallIC::State state_;
 };
diff --git a/src/compiler.cc b/src/compiler.cc
index 2873525..4e55d22 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -456,6 +456,8 @@
     if (optimized_code.is_null()) {
       if (info()->bailout_reason() == kNoReason) {
         info_->set_bailout_reason(kCodeGenerationFailed);
+      } else if (info()->bailout_reason() == kMapBecameUnstable) {
+        return AbortOptimization();
       }
       return AbortAndDisableOptimization();
     }
@@ -518,7 +520,7 @@
   // TODO(yangguo): check whether those heuristics are still up-to-date.
   // We do not shrink objects that go into a snapshot (yet), so we adjust
   // the estimate conservatively.
-  if (Serializer::enabled(shared->GetIsolate())) {
+  if (shared->GetIsolate()->serializer_enabled()) {
     estimate += 2;
   } else if (FLAG_clever_optimizations) {
     // Inobject slack tracking will reclaim redundant inobject space later,
diff --git a/src/contexts.cc b/src/contexts.cc
index 58ae49a..1d0e2f8 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -108,7 +108,7 @@
       // to only do a local lookup for context extension objects.
       if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
           object->IsJSContextExtensionObject()) {
-        *attributes = JSReceiver::GetLocalPropertyAttribute(object, name);
+        *attributes = JSReceiver::GetOwnPropertyAttribute(object, name);
       } else {
         *attributes = JSReceiver::GetPropertyAttribute(object, name);
       }
diff --git a/src/cpu-profiler-inl.h b/src/cpu-profiler-inl.h
index c4efef1..e088f2e 100644
--- a/src/cpu-profiler-inl.h
+++ b/src/cpu-profiler-inl.h
@@ -28,6 +28,14 @@
 }
 
 
+void CodeDisableOptEventRecord::UpdateCodeMap(CodeMap* code_map) {
+  CodeEntry* entry = code_map->FindEntry(start);
+  if (entry != NULL) {
+    entry->set_bailout_reason(bailout_reason);
+  }
+}
+
+
 void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
   code_map->MoveCode(from, to);
 }
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index abe2934..3a7c960 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -304,6 +304,15 @@
 }
 
 
+void CpuProfiler::CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) {
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
+  CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
+  rec->start = code->address();
+  rec->bailout_reason = GetBailoutReason(shared->DisableOptimizationReason());
+  processor_->Enqueue(evt_rec);
+}
+
+
 void CpuProfiler::CodeDeleteEvent(Address from) {
 }
 
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index e87fe9e..b9f9f98 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -26,6 +26,7 @@
 #define CODE_EVENTS_TYPE_LIST(V)                                   \
   V(CODE_CREATION,    CodeCreateEventRecord)                       \
   V(CODE_MOVE,        CodeMoveEventRecord)                         \
+  V(CODE_DISABLE_OPT, CodeDisableOptEventRecord)                   \
   V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)           \
   V(REPORT_BUILTIN,   ReportBuiltinEventRecord)
 
@@ -65,6 +66,15 @@
 };
 
 
+class CodeDisableOptEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  const char* bailout_reason;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
 class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
  public:
   Address from;
@@ -225,6 +235,7 @@
                                Code* code, int args_count);
   virtual void CodeMovingGCEvent() {}
   virtual void CodeMoveEvent(Address from, Address to);
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
   virtual void CodeDeleteEvent(Address from);
   virtual void GetterCallbackEvent(Name* name, Address entry_point);
   virtual void RegExpCodeCreateEvent(Code* code, String* source);
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 225c6f0..a11cf4d 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -82,10 +82,7 @@
 
 Handle<String> ReadLineEditor::Prompt(const char* prompt) {
   char* result = NULL;
-  {  // Release lock for blocking input.
-    Unlocker unlock(isolate_);
-    result = readline(prompt);
-  }
+  result = readline(prompt);
   if (result == NULL) return Handle<String>();
   AddHistory(result);
   return String::NewFromUtf8(isolate_, result);
@@ -123,7 +120,6 @@
   static unsigned current_index;
   static Persistent<Array> current_completions;
   Isolate* isolate = read_line_editor.isolate_;
-  Locker lock(isolate);
   HandleScope scope(isolate);
   Handle<Array> completions;
   if (state == 0) {
diff --git a/src/d8.cc b/src/d8.cc
index a467333..ffc58e6 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -472,10 +472,7 @@
     // not been fully read into the buffer yet (does not end with '\n').
     // If fgets gets an error, just give up.
     char* input = NULL;
-    {  // Release lock for blocking input.
-      Unlocker unlock(isolate);
-      input = fgets(buffer, kBufferSize, stdin);
-    }
+    input = fgets(buffer, kBufferSize, stdin);
     if (input == NULL) return Handle<String>();
     length = static_cast<int>(strlen(buffer));
     if (length == 0) {
@@ -737,7 +734,6 @@
 
 
 void Shell::InstallUtilityScript(Isolate* isolate) {
-  Locker lock(isolate);
   HandleScope scope(isolate);
   // If we use the utility context, we have to set the security tokens so that
   // utility, evaluation and debug context can all access each other.
@@ -904,7 +900,6 @@
 void Shell::InitializeDebugger(Isolate* isolate) {
   if (options.test_shell) return;
 #ifndef V8_SHARED
-  Locker lock(isolate);
   HandleScope scope(isolate);
   Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
   utility_context_.Reset(isolate,
@@ -1031,8 +1026,6 @@
 
 
 static char* ReadChars(Isolate* isolate, const char* name, int* size_out) {
-  // Release the V8 lock while reading files.
-  v8::Unlocker unlocker(isolate);
   FILE* file = FOpen(name, "rb");
   if (file == NULL) return NULL;
 
@@ -1112,7 +1105,6 @@
 
 
 void Shell::RunShell(Isolate* isolate) {
-  Locker locker(isolate);
   HandleScope outer_scope(isolate);
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, evaluation_context_);
@@ -1204,7 +1196,6 @@
     next_semaphore_.Wait();
     {
       Isolate::Scope iscope(isolate);
-      Locker lock(isolate);
       {
         HandleScope scope(isolate);
         PerIsolateData data(isolate);
@@ -1351,34 +1342,31 @@
     options.isolate_sources[i].StartExecuteInThread();
   }
 #endif  // !V8_SHARED
-  {  // NOLINT
-    Locker lock(isolate);
-    {
-      HandleScope scope(isolate);
-      Local<Context> context = CreateEvaluationContext(isolate);
-      if (options.last_run) {
-        // Keep using the same context in the interactive shell.
-        evaluation_context_.Reset(isolate, context);
+  {
+    HandleScope scope(isolate);
+    Local<Context> context = CreateEvaluationContext(isolate);
+    if (options.last_run) {
+      // Keep using the same context in the interactive shell.
+      evaluation_context_.Reset(isolate, context);
 #ifndef V8_SHARED
-        // If the interactive debugger is enabled make sure to activate
-        // it before running the files passed on the command line.
-        if (i::FLAG_debugger) {
-          InstallUtilityScript(isolate);
-        }
+      // If the interactive debugger is enabled make sure to activate
+      // it before running the files passed on the command line.
+      if (i::FLAG_debugger) {
+        InstallUtilityScript(isolate);
+      }
 #endif  // !V8_SHARED
-      }
-      {
-        Context::Scope cscope(context);
-        PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
-        options.isolate_sources[0].Execute(isolate);
-      }
     }
-    if (!options.last_run) {
-      if (options.send_idle_notification) {
-        const int kLongIdlePauseInMs = 1000;
-        V8::ContextDisposedNotification();
-        V8::IdleNotification(kLongIdlePauseInMs);
-      }
+    {
+      Context::Scope cscope(context);
+      PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
+      options.isolate_sources[0].Execute(isolate);
+    }
+  }
+  if (!options.last_run) {
+    if (options.send_idle_notification) {
+      const int kLongIdlePauseInMs = 1000;
+      V8::ContextDisposedNotification();
+      V8::IdleNotification(kLongIdlePauseInMs);
     }
   }
 
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index ebd7dbd..660ea79 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -2485,17 +2485,6 @@
 };
 
 
-function NumberToHex8Str(n) {
-  var r = "";
-  for (var i = 0; i < 8; ++i) {
-    var c = hexCharArray[n & 0x0F];  // hexCharArray is defined in uri.js
-    r = c + r;
-    n = n >>> 4;
-  }
-  return r;
-}
-
-
 /**
  * Convert an Object to its debugger protocol representation. The representation
  * may be serilized to a JSON object using JSON.stringify().
diff --git a/src/debug.cc b/src/debug.cc
index 6cfc500..8956e92 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -2053,6 +2053,7 @@
       Heap* heap = isolate_->heap();
       heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
                               "preparing for breakpoints");
+      HeapIterator iterator(heap);
 
       // Ensure no GC in this scope as we are going to use gc_metadata
       // field in the Code object to mark active functions.
@@ -2072,7 +2073,6 @@
       // Scan the heap for all non-optimized functions which have no
       // debug break slots and are not active or inlined into an active
       // function and mark them for lazy compilation.
-      HeapIterator iterator(heap);
       HeapObject* obj = NULL;
       while (((obj = iterator.next()) != NULL)) {
         if (obj->IsJSFunction()) {
@@ -2197,9 +2197,7 @@
   Handle<SharedFunctionInfo> target;
   Heap* heap = isolate_->heap();
   while (!done) {
-    { // Extra scope for iterator and no-allocation.
-      heap->EnsureHeapIsIterable();
-      DisallowHeapAllocation no_alloc_during_heap_iteration;
+    { // Extra scope for iterator.
       HeapIterator iterator(heap);
       for (HeapObject* obj = iterator.next();
            obj != NULL; obj = iterator.next()) {
@@ -2529,8 +2527,6 @@
   // scripts which are no longer referenced.  The second also sweeps precisely,
   // which saves us doing yet another GC to make the heap iterable.
   heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
-                          "Debug::CreateScriptCache");
 
   ASSERT(script_cache_ == NULL);
   script_cache_ = new ScriptCache(isolate_);
@@ -2538,7 +2534,6 @@
   // Scan heap for Script objects.
   int count = 0;
   HeapIterator iterator(heap);
-  DisallowHeapAllocation no_allocation;
 
   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
     if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
diff --git a/src/debug.h b/src/debug.h
index 7956237..e0f3ea0 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -342,12 +342,13 @@
   };
 
   // Support for setting the address to jump to when returning from break point.
-  Address* after_break_target_address() {
-    return reinterpret_cast<Address*>(&thread_local_.after_break_target_);
+  Address after_break_target_address() {
+    return reinterpret_cast<Address>(&thread_local_.after_break_target_);
   }
-  Address* restarter_frame_function_pointer_address() {
+
+  Address restarter_frame_function_pointer_address() {
     Object*** address = &thread_local_.restarter_frame_function_pointer_;
-    return reinterpret_cast<Address*>(address);
+    return reinterpret_cast<Address>(address);
   }
 
   static const int kEstimatedNofDebugInfoEntries = 16;
@@ -927,39 +928,6 @@
   bool prev_disable_break_;
 };
 
-
-// Debug_Address encapsulates the Address pointers used in generating debug
-// code.
-class Debug_Address {
- public:
-  explicit Debug_Address(Debug::AddressId id) : id_(id) { }
-
-  static Debug_Address AfterBreakTarget() {
-    return Debug_Address(Debug::k_after_break_target_address);
-  }
-
-  static Debug_Address RestarterFrameFunctionPointer() {
-    return Debug_Address(Debug::k_restarter_frame_function_pointer);
-  }
-
-  Address address(Isolate* isolate) const {
-    Debug* debug = isolate->debug();
-    switch (id_) {
-      case Debug::k_after_break_target_address:
-        return reinterpret_cast<Address>(debug->after_break_target_address());
-      case Debug::k_restarter_frame_function_pointer:
-        return reinterpret_cast<Address>(
-            debug->restarter_frame_function_pointer_address());
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-  }
-
- private:
-  Debug::AddressId id_;
-};
-
 } }  // namespace v8::internal
 
 #endif  // V8_DEBUG_H_
diff --git a/src/elements-kind.cc b/src/elements-kind.cc
index adab396..d585eaa 100644
--- a/src/elements-kind.cc
+++ b/src/elements-kind.cc
@@ -51,6 +51,12 @@
 }
 
 
+int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
+  return IsExternalArrayElementsKind(elements_kind)
+      ? 0 : (FixedArray::kHeaderSize - kSmiTagSize);
+}
+
+
 const char* ElementsKindToString(ElementsKind kind) {
   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
   return accessor->name();
diff --git a/src/elements-kind.h b/src/elements-kind.h
index 1a550b0..28f4429 100644
--- a/src/elements-kind.h
+++ b/src/elements-kind.h
@@ -72,6 +72,7 @@
     FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
 
 int ElementsKindToShiftSize(ElementsKind elements_kind);
+int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind);
 const char* ElementsKindToString(ElementsKind kind);
 void PrintElementsKind(FILE* out, ElementsKind kind);
 
diff --git a/src/factory.cc b/src/factory.cc
index f99ea9b..4300b24 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1294,10 +1294,10 @@
   Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
 
   if (!function->shared()->is_generator()) {
-    JSObject::SetLocalPropertyIgnoreAttributes(prototype,
-                                               constructor_string(),
-                                               function,
-                                               DONT_ENUM).Assert();
+    JSObject::SetOwnPropertyIgnoreAttributes(prototype,
+                                             constructor_string(),
+                                             function,
+                                             DONT_ENUM).Assert();
   }
 
   return prototype;
@@ -1990,7 +1990,7 @@
       // cache in the snapshot to keep  boot-time memory usage down.
       // If we expand the number string cache already while creating
       // the snapshot then that didn't work out.
-      ASSERT(!Serializer::enabled(isolate()) || FLAG_extra_code != NULL);
+      ASSERT(!isolate()->serializer_enabled() || FLAG_extra_code != NULL);
       Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
       isolate()->heap()->set_number_string_cache(*new_cache);
       return;
@@ -2131,7 +2131,7 @@
     return result;
   }
 
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       handle(JSObject::cast(result->prototype())),
       constructor_string(),
       result,
diff --git a/src/frames.cc b/src/frames.cc
index e7c2a14..73234e00 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -640,7 +640,7 @@
   // Skip saved double registers.
   if (safepoint_entry.has_doubles()) {
     // Number of doubles not known at snapshot time.
-    ASSERT(!Serializer::enabled(isolate()));
+    ASSERT(!isolate()->serializer_enabled());
     parameters_base += DoubleRegister::NumAllocatableRegisters() *
         kDoubleSize / kPointerSize;
   }
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index 6068bf4..4b7443a 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -173,9 +173,6 @@
 
 
 Handle<HeapObject> HeapProfiler::FindHeapObjectById(SnapshotObjectId id) {
-  heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
-                            "HeapProfiler::FindHeapObjectById");
-  DisallowHeapAllocation no_allocation;
   HeapObject* object = NULL;
   HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
   // Make sure that object with the given id is still reachable.
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index cafee77..fb1fa38 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -155,6 +155,7 @@
     case kSynthetic: return "/synthetic/";
     case kConsString: return "/concatenated string/";
     case kSlicedString: return "/sliced string/";
+    case kSymbol: return "/symbol/";
     default: return "???";
   }
 }
@@ -851,6 +852,8 @@
     return AddEntry(object,
                     HeapEntry::kString,
                     names_->GetName(String::cast(object)));
+  } else if (object->IsSymbol()) {
+    return AddEntry(object, HeapEntry::kSymbol, "symbol");
   } else if (object->IsCode()) {
     return AddEntry(object, HeapEntry::kCode, "");
   } else if (object->IsSharedFunctionInfo()) {
@@ -1098,6 +1101,8 @@
     ExtractJSObjectReferences(entry, JSObject::cast(obj));
   } else if (obj->IsString()) {
     ExtractStringReferences(entry, String::cast(obj));
+  } else if (obj->IsSymbol()) {
+    ExtractSymbolReferences(entry, Symbol::cast(obj));
   } else if (obj->IsMap()) {
     ExtractMapReferences(entry, Map::cast(obj));
   } else if (obj->IsSharedFunctionInfo()) {
@@ -1244,6 +1249,13 @@
 }
 
 
+void V8HeapExplorer::ExtractSymbolReferences(int entry, Symbol* symbol) {
+  SetInternalReference(symbol, entry,
+                       "name", symbol->name(),
+                       Symbol::kNameOffset);
+}
+
+
 void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
   if (context == context->declaration_context()) {
     ScopeInfo* scope_info = context->closure()->shared()->scope_info();
@@ -1752,7 +1764,7 @@
     Object* constructor_prop = NULL;
     Isolate* isolate = heap->isolate();
     LookupResult result(isolate);
-    object->LocalLookupRealNamedProperty(
+    object->LookupOwnRealNamedProperty(
         isolate->factory()->constructor_string(), &result);
     if (!result.IsFound()) return object->constructor_name();
 
@@ -2569,10 +2581,6 @@
   CHECK(!debug_heap->map_space()->was_swept_conservatively());
 #endif
 
-  // The following code uses heap iterators, so we want the heap to be
-  // stable. It should follow TagGlobalObjects as that can allocate.
-  DisallowHeapAllocation no_alloc;
-
 #ifdef VERIFY_HEAP
   debug_heap->Verify();
 #endif
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index a0f2a62..e1c291e 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -83,7 +83,8 @@
     kNative = v8::HeapGraphNode::kNative,
     kSynthetic = v8::HeapGraphNode::kSynthetic,
     kConsString = v8::HeapGraphNode::kConsString,
-    kSlicedString = v8::HeapGraphNode::kSlicedString
+    kSlicedString = v8::HeapGraphNode::kSlicedString,
+    kSymbol = v8::HeapGraphNode::kSymbol
   };
   static const int kNoEntry;
 
@@ -368,6 +369,7 @@
   void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy);
   void ExtractJSObjectReferences(int entry, JSObject* js_obj);
   void ExtractStringReferences(int entry, String* obj);
+  void ExtractSymbolReferences(int entry, Symbol* symbol);
   void ExtractContextReferences(int entry, Context* context);
   void ExtractMapReferences(int entry, Map* map);
   void ExtractSharedFunctionInfoReferences(int entry,
diff --git a/src/heap.cc b/src/heap.cc
index b672bbf..66d17fb 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -699,6 +699,10 @@
   ReportStatisticsAfterGC();
 #endif  // DEBUG
   isolate_->debug()->AfterGarbageCollection();
+
+  // Remember the last top pointer so that we can later find out
+  // whether we allocated in new space since the last GC.
+  new_space_top_after_last_gc_ = new_space()->top();
 }
 
 
@@ -4321,14 +4325,15 @@
 
 bool Heap::IsHeapIterable() {
   return (!old_pointer_space()->was_swept_conservatively() &&
-          !old_data_space()->was_swept_conservatively());
+          !old_data_space()->was_swept_conservatively() &&
+          new_space_top_after_last_gc_ == new_space()->top());
 }
 
 
-void Heap::EnsureHeapIsIterable() {
+void Heap::MakeHeapIterable() {
   ASSERT(AllowHeapAllocation::IsAllowed());
   if (!IsHeapIterable()) {
-    CollectAllGarbage(kMakeHeapIterableMask, "Heap::EnsureHeapIsIterable");
+    CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
   }
   ASSERT(IsHeapIterable());
 }
@@ -4389,7 +4394,7 @@
     return false;
   }
 
-  if (!FLAG_incremental_marking || Serializer::enabled(isolate_)) {
+  if (!FLAG_incremental_marking || isolate_->serializer_enabled()) {
     return IdleGlobalGC();
   }
 
@@ -5052,9 +5057,8 @@
   initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_);
 
   // The external allocation limit should be below 256 MB on all architectures
-  // to avoid unnecessary low memory notifications, as that is the threshold
-  // for some embedders.
-  external_allocation_limit_ = 12 * max_semi_space_size_;
+  // to avoid that resource-constrained embedders run low on memory.
+  external_allocation_limit_ = 192 * MB;
   ASSERT(external_allocation_limit_ <= 256 * MB);
 
   // The old generation is paged and needs at least one page for each space.
@@ -5209,6 +5213,7 @@
   if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) {
     return false;
   }
+  new_space_top_after_last_gc_ = new_space()->top();
 
   // Initialize old pointer space.
   old_pointer_space_ =
@@ -5732,7 +5737,9 @@
 
 
 HeapIterator::HeapIterator(Heap* heap)
-    : heap_(heap),
+    : make_heap_iterable_helper_(heap),
+      no_heap_allocation_(),
+      heap_(heap),
       filtering_(HeapIterator::kNoFiltering),
       filter_(NULL) {
   Init();
@@ -5741,7 +5748,9 @@
 
 HeapIterator::HeapIterator(Heap* heap,
                            HeapIterator::HeapObjectsFiltering filtering)
-    : heap_(heap),
+    : make_heap_iterable_helper_(heap),
+      no_heap_allocation_(),
+      heap_(heap),
       filtering_(filtering),
       filter_(NULL) {
   Init();
diff --git a/src/heap.h b/src/heap.h
index 9ccbe66..08e0fcc 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -767,7 +767,7 @@
 
   // Ensure that we have swept all spaces in such a way that we can iterate
   // over all objects.  May cause a GC.
-  void EnsureHeapIsIterable();
+  void MakeHeapIterable();
 
   // Notify the heap that a context has been disposed.
   int NotifyContextDisposed();
@@ -1549,6 +1549,7 @@
   LargeObjectSpace* lo_space_;
   HeapState gc_state_;
   int gc_post_processing_depth_;
+  Address new_space_top_after_last_gc_;
 
   // Returns the amount of external memory registered since last global gc.
   int64_t PromotedExternalMemorySize();
@@ -2391,6 +2392,9 @@
 // aggregates the specific iterators for the different spaces as
 // these can only iterate over one space only.
 //
+// HeapIterator ensures there is no allocation during its lifetime
+// (using an embedded DisallowHeapAllocation instance).
+//
 // HeapIterator can skip free list nodes (that is, de-allocated heap
 // objects that still remain in the heap). As implementation of free
 // nodes filtering uses GC marks, it can't be used during MS/MC GC
@@ -2413,12 +2417,18 @@
   void reset();
 
  private:
+  struct MakeHeapIterableHelper {
+    explicit MakeHeapIterableHelper(Heap* heap) { heap->MakeHeapIterable(); }
+  };
+
   // Perform the initialization.
   void Init();
   // Perform all necessary shutdown (destruction) work.
   void Shutdown();
   HeapObject* NextObject();
 
+  MakeHeapIterableHelper make_heap_iterable_helper_;
+  DisallowHeapAllocation no_heap_allocation_;
   Heap* heap_;
   HeapObjectsFiltering filtering_;
   HeapObjectsFilter* filter_;
diff --git a/src/hydrogen-dehoist.cc b/src/hydrogen-dehoist.cc
index 44aeb48..e800823 100644
--- a/src/hydrogen-dehoist.cc
+++ b/src/hydrogen-dehoist.cc
@@ -30,12 +30,13 @@
   int32_t value = constant->Integer32Value() * sign;
   // We limit offset values to 30 bits because we want to avoid the risk of
   // overflows when the offset is added to the object header size.
-  if (value >= 1 << array_operation->MaxIndexOffsetBits() || value < 0) return;
+  if (value >= 1 << array_operation->MaxBaseOffsetBits() || value < 0) return;
   array_operation->SetKey(subexpression);
   if (binary_operation->HasNoUses()) {
     binary_operation->DeleteAndReplaceWith(NULL);
   }
-  array_operation->SetIndexOffset(static_cast<uint32_t>(value));
+  value <<= ElementsKindToShiftSize(array_operation->elements_kind());
+  array_operation->IncreaseBaseOffset(static_cast<uint32_t>(value));
   array_operation->SetDehoisted(true);
 }
 
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index bfdc949..9bd0464 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -3457,7 +3457,7 @@
   stream->Add("[");
   key()->PrintNameTo(stream);
   if (IsDehoisted()) {
-    stream->Add(" + %d]", index_offset());
+    stream->Add(" + %d]", base_offset());
   } else {
     stream->Add("]");
   }
@@ -3609,7 +3609,7 @@
   stream->Add("[");
   key()->PrintNameTo(stream);
   if (IsDehoisted()) {
-    stream->Add(" + %d] = ", index_offset());
+    stream->Add(" + %d] = ", base_offset());
   } else {
     stream->Add("] = ");
   }
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index cf3497f..05b3116 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1079,6 +1079,18 @@
     return new(zone) I(p1, p2, p3, p4, p5);                                    \
   }
 
+#define DECLARE_INSTRUCTION_FACTORY_P6(I, P1, P2, P3, P4, P5, P6)              \
+  static I* New(Zone* zone,                                                    \
+                HValue* context,                                               \
+                P1 p1,                                                         \
+                P2 p2,                                                         \
+                P3 p3,                                                         \
+                P4 p4,                                                         \
+                P5 p5,                                                         \
+                P6 p6) {                                                       \
+    return new(zone) I(p1, p2, p3, p4, p5, p6);                                \
+  }
+
 #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I)                         \
   static I* New(Zone* zone, HValue* context) {                                 \
     return new(zone) I(context);                                               \
@@ -6413,8 +6425,9 @@
  public:
   virtual HValue* GetKey() = 0;
   virtual void SetKey(HValue* key) = 0;
-  virtual void SetIndexOffset(uint32_t index_offset) = 0;
-  virtual int MaxIndexOffsetBits() = 0;
+  virtual ElementsKind elements_kind() const = 0;
+  virtual void IncreaseBaseOffset(uint32_t base_offset) = 0;
+  virtual int MaxBaseOffsetBits() = 0;
   virtual bool IsDehoisted() = 0;
   virtual void SetDehoisted(bool is_dehoisted) = 0;
   virtual ~ArrayInstructionInterface() { }
@@ -6426,6 +6439,8 @@
 };
 
 
+static const int kDefaultKeyedHeaderOffsetSentinel = -1;
+
 enum LoadKeyedHoleMode {
   NEVER_RETURN_HOLE,
   ALLOW_RETURN_HOLE
@@ -6439,6 +6454,8 @@
                                  ElementsKind);
   DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*,
                                  ElementsKind, LoadKeyedHoleMode);
+  DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*,
+                                 ElementsKind, LoadKeyedHoleMode, int);
 
   bool is_external() const {
     return IsExternalArrayElementsKind(elements_kind());
@@ -6456,12 +6473,13 @@
     return OperandAt(2);
   }
   bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
-  uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
-  void SetIndexOffset(uint32_t index_offset) {
-    bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
+  uint32_t base_offset() { return BaseOffsetField::decode(bit_field_); }
+  void IncreaseBaseOffset(uint32_t base_offset) {
+    base_offset += BaseOffsetField::decode(bit_field_);
+    bit_field_ = BaseOffsetField::update(bit_field_, base_offset);
   }
-  virtual int MaxIndexOffsetBits() {
-    return kBitsForIndexOffset;
+  virtual int MaxBaseOffsetBits() {
+    return kBitsForBaseOffset;
   }
   HValue* GetKey() { return key(); }
   void SetKey(HValue* key) { SetOperandAt(1, key); }
@@ -6511,7 +6529,7 @@
     if (!other->IsLoadKeyed()) return false;
     HLoadKeyed* other_load = HLoadKeyed::cast(other);
 
-    if (IsDehoisted() && index_offset() != other_load->index_offset())
+    if (IsDehoisted() && base_offset() != other_load->base_offset())
       return false;
     return elements_kind() == other_load->elements_kind();
   }
@@ -6521,10 +6539,15 @@
              HValue* key,
              HValue* dependency,
              ElementsKind elements_kind,
-             LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
+             LoadKeyedHoleMode mode = NEVER_RETURN_HOLE,
+             int offset = kDefaultKeyedHeaderOffsetSentinel)
       : bit_field_(0) {
+    offset = offset == kDefaultKeyedHeaderOffsetSentinel
+        ? GetDefaultHeaderSizeForElementsKind(elements_kind)
+        : offset;
     bit_field_ = ElementsKindField::encode(elements_kind) |
-        HoleModeField::encode(mode);
+        HoleModeField::encode(mode) |
+        BaseOffsetField::encode(offset);
 
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
@@ -6587,16 +6610,16 @@
   enum LoadKeyedBits {
     kBitsForElementsKind = 5,
     kBitsForHoleMode = 1,
-    kBitsForIndexOffset = 25,
+    kBitsForBaseOffset = 25,
     kBitsForIsDehoisted = 1,
 
     kStartElementsKind = 0,
     kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
-    kStartIndexOffset = kStartHoleMode + kBitsForHoleMode,
-    kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset
+    kStartBaseOffset = kStartHoleMode + kBitsForHoleMode,
+    kStartIsDehoisted = kStartBaseOffset + kBitsForBaseOffset
   };
 
-  STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset +
+  STATIC_ASSERT((kBitsForElementsKind + kBitsForBaseOffset +
                  kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
   STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
   class ElementsKindField:
@@ -6605,8 +6628,8 @@
   class HoleModeField:
     public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
     {};  // NOLINT
-  class IndexOffsetField:
-    public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset>
+  class BaseOffsetField:
+    public BitField<uint32_t, kStartBaseOffset, kBitsForBaseOffset>
     {};  // NOLINT
   class IsDehoistedField:
     public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
@@ -6726,6 +6749,7 @@
     ASSERT(!has_transition());  // Only set once.
     SetOperandAt(2, transition);
     has_transition_ = true;
+    SetChangesFlag(kMaps);
   }
 
   bool NeedsWriteBarrier() {
@@ -6752,6 +6776,19 @@
     SetOperandAt(1, value);
   }
 
+  bool CanBeReplacedWith(HStoreNamedField* that) const {
+    if (!this->access().Equals(that->access())) return false;
+    if (SmiValuesAre32Bits() &&
+        this->field_representation().IsSmi() &&
+        this->store_mode() == INITIALIZING_STORE &&
+        that->store_mode() == STORE_TO_INITIALIZED_ENTRY) {
+      // We cannot replace an initializing store to a smi field with a store to
+      // an initialized entry on 64-bit architectures (with 32-bit smis).
+      return false;
+    }
+    return true;
+  }
+
  private:
   HStoreNamedField(HValue* obj,
                    HObjectAccess access,
@@ -6823,6 +6860,8 @@
                                  ElementsKind);
   DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
                                  ElementsKind, StoreFieldOrKeyedMode);
+  DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*,
+                                 ElementsKind, StoreFieldOrKeyedMode, int);
 
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     // kind_fast:               tagged[int32] = tagged
@@ -6895,9 +6934,11 @@
   }
   StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
   ElementsKind elements_kind() const { return elements_kind_; }
-  uint32_t index_offset() { return index_offset_; }
-  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
-  virtual int MaxIndexOffsetBits() {
+  uint32_t base_offset() { return base_offset_; }
+  void IncreaseBaseOffset(uint32_t base_offset) {
+    base_offset_ += base_offset;
+  }
+  virtual int MaxBaseOffsetBits() {
     return 31 - ElementsKindToShiftSize(elements_kind_);
   }
   HValue* GetKey() { return key(); }
@@ -6941,9 +6982,12 @@
  private:
   HStoreKeyed(HValue* obj, HValue* key, HValue* val,
               ElementsKind elements_kind,
-              StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
+              StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
+              int offset = kDefaultKeyedHeaderOffsetSentinel)
       : elements_kind_(elements_kind),
-      index_offset_(0),
+      base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
+          ? GetDefaultHeaderSizeForElementsKind(elements_kind)
+          : offset),
       is_dehoisted_(false),
       is_uninitialized_(false),
       store_mode_(store_mode),
@@ -6983,7 +7027,7 @@
   }
 
   ElementsKind elements_kind_;
-  uint32_t index_offset_;
+  uint32_t base_offset_;
   bool is_dehoisted_ : 1;
   bool is_uninitialized_ : 1;
   StoreFieldOrKeyedMode store_mode_: 1;
diff --git a/src/hydrogen-store-elimination.cc b/src/hydrogen-store-elimination.cc
index cf5f3a1..bbb115a 100644
--- a/src/hydrogen-store-elimination.cc
+++ b/src/hydrogen-store-elimination.cc
@@ -58,7 +58,7 @@
   while (i < unobserved_.length()) {
     HStoreNamedField* prev = unobserved_.at(i);
     if (aliasing_->MustAlias(object, prev->object()->ActualValue()) &&
-        store->access().Equals(prev->access())) {
+        prev->CanBeReplacedWith(store)) {
       // This store is guaranteed to overwrite the previous store.
       prev->DeleteAndReplaceWith(NULL);
       TRACE(("++ Unobserved store S%d overwritten by S%d\n",
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index b296b93..5d78a4a 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2473,14 +2473,14 @@
   }
 
   // Special loop unfolding case
-  static const int kLoopUnfoldLimit = 8;
-  STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit);
+  STATIC_ASSERT(JSArray::kPreallocatedArrayElements <=
+                kElementLoopUnrollThreshold);
   int initial_capacity = -1;
   if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
     int constant_from = from->GetInteger32Constant();
     int constant_to = to->GetInteger32Constant();
 
-    if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) {
+    if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) {
       initial_capacity = constant_to;
     }
   }
@@ -7880,6 +7880,7 @@
       ElementsKind elements_kind = receiver_map->elements_kind();
       if (!IsFastElementsKind(elements_kind)) return false;
       if (receiver_map->is_observed()) return false;
+      if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false;
       ASSERT(receiver_map->is_extensible());
 
       // If there may be elements accessors in the prototype chain, the fast
@@ -8033,7 +8034,7 @@
   if (call_type == kCallApiFunction) {
     // Cannot embed a direct reference to the global proxy map
     // as it maybe dropped on deserialization.
-    CHECK(!Serializer::enabled(isolate()));
+    CHECK(!isolate()->serializer_enabled());
     ASSERT_EQ(0, receiver_maps->length());
     receiver_maps->Add(handle(
         function->context()->global_object()->global_receiver()->map()),
@@ -8220,7 +8221,7 @@
   if (shared->strict_mode() == SLOPPY && !shared->native()) {
     // Cannot embed a direct reference to the global proxy
     // as is it dropped on deserialization.
-    CHECK(!Serializer::enabled(isolate()));
+    CHECK(!isolate()->serializer_enabled());
     Handle<JSObject> global_receiver(
         target->context()->global_object()->global_receiver());
     return Add<HConstant>(global_receiver);
@@ -8229,6 +8230,56 @@
 }
 
 
+void HOptimizedGraphBuilder::BuildArrayCall(Expression* expression,
+                                            int arguments_count,
+                                            HValue* function,
+                                            Handle<AllocationSite> site) {
+  Add<HCheckValue>(function, array_function());
+
+  if (IsCallArrayInlineable(arguments_count, site)) {
+    BuildInlinedCallArray(expression, arguments_count, site);
+    return;
+  }
+
+  HInstruction* call = PreProcessCall(New<HCallNewArray>(
+      function, arguments_count + 1, site->GetElementsKind()));
+  if (expression->IsCall()) {
+    Drop(1);
+  }
+  ast_context()->ReturnInstruction(call, expression->id());
+}
+
+
+bool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) {
+  if (!array_function().is_identical_to(expr->target())) {
+    return false;
+  }
+
+  Handle<AllocationSite> site = expr->allocation_site();
+  if (site.is_null()) return false;
+
+  BuildArrayCall(expr,
+                 expr->arguments()->length(),
+                 function,
+                 site);
+  return true;
+}
+
+
+bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr,
+                                                   HValue* function) {
+  if (!array_function().is_identical_to(expr->target())) {
+    return false;
+  }
+
+  BuildArrayCall(expr,
+                 expr->arguments()->length(),
+                 function,
+                 expr->allocation_site());
+  return true;
+}
+
+
 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
@@ -8323,8 +8374,7 @@
     // evaluation of the arguments.
     CHECK_ALIVE(VisitForValue(expr->expression()));
     HValue* function = Top();
-    bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
-    if (global_call) {
+    if (expr->global_call()) {
       Variable* var = proxy->var();
       bool known_global_function = false;
       // If there is a global property cell for the name at compile time and
@@ -8358,6 +8408,7 @@
           return;
         }
         if (TryInlineApiFunctionCall(expr, receiver)) return;
+        if (TryHandleArrayCall(expr, function)) return;
         if (TryInlineCall(expr)) return;
 
         PushArgumentsFromEnvironment(argument_count);
@@ -8407,20 +8458,21 @@
 }
 
 
-void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) {
+void HOptimizedGraphBuilder::BuildInlinedCallArray(
+    Expression* expression,
+    int argument_count,
+    Handle<AllocationSite> site) {
+  ASSERT(!site.is_null());
+  ASSERT(argument_count >= 0 && argument_count <= 1);
   NoObservableSideEffectsScope no_effects(this);
 
-  int argument_count = expr->arguments()->length();
   // We should at least have the constructor on the expression stack.
   HValue* constructor = environment()->ExpressionStackAt(argument_count);
 
-  ElementsKind kind = expr->elements_kind();
-  Handle<AllocationSite> site = expr->allocation_site();
-  ASSERT(!site.is_null());
-
   // Register on the site for deoptimization if the transition feedback changes.
   AllocationSite::AddDependentCompilationInfo(
       site, AllocationSite::TRANSITIONS, top_info());
+  ElementsKind kind = site->GetElementsKind();
   HInstruction* site_instruction = Add<HConstant>(site);
 
   // In the single constant argument case, we may have to adjust elements kind
@@ -8443,32 +8495,12 @@
                                site_instruction,
                                constructor,
                                DISABLE_ALLOCATION_SITES);
-  HValue* new_object;
-  if (argument_count == 0) {
-    new_object = array_builder.AllocateEmptyArray();
-  } else if (argument_count == 1) {
-    HValue* argument = environment()->Top();
-    new_object = BuildAllocateArrayFromLength(&array_builder, argument);
-  } else {
-    HValue* length = Add<HConstant>(argument_count);
-    // Smi arrays need to initialize array elements with the hole because
-    // bailout could occur if the arguments don't fit in a smi.
-    //
-    // TODO(mvstanton): If all the arguments are constants in smi range, then
-    // we could set fill_with_hole to false and save a few instructions.
-    JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
-        ? JSArrayBuilder::FILL_WITH_HOLE
-        : JSArrayBuilder::DONT_FILL_WITH_HOLE;
-    new_object = array_builder.AllocateArray(length, length, fill_mode);
-    HValue* elements = array_builder.GetElementsLocation();
-    for (int i = 0; i < argument_count; i++) {
-      HValue* value = environment()->ExpressionStackAt(argument_count - i - 1);
-      HValue* constant_i = Add<HConstant>(i);
-      Add<HStoreKeyed>(elements, constant_i, value, kind);
-    }
-  }
+  HValue* new_object = argument_count == 0
+      ? array_builder.AllocateEmptyArray()
+      : BuildAllocateArrayFromLength(&array_builder, Top());
 
-  Drop(argument_count + 1);  // drop constructor and args.
+  int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1);
+  Drop(args_to_drop);
   ast_context()->ReturnValue(new_object);
 }
 
@@ -8482,14 +8514,13 @@
 }
 
 
-bool HOptimizedGraphBuilder::IsCallNewArrayInlineable(CallNew* expr) {
+bool HOptimizedGraphBuilder::IsCallArrayInlineable(
+    int argument_count,
+    Handle<AllocationSite> site) {
   Handle<JSFunction> caller = current_info()->closure();
-  Handle<JSFunction> target(isolate()->native_context()->array_function(),
-                            isolate());
-  int argument_count = expr->arguments()->length();
+  Handle<JSFunction> target = array_function();
   // We should have the function plus array arguments on the environment stack.
   ASSERT(environment()->length() >= (argument_count + 1));
-  Handle<AllocationSite> site = expr->allocation_site();
   ASSERT(!site.is_null());
 
   bool inline_ok = false;
@@ -8499,22 +8530,24 @@
       HValue* argument = Top();
       if (argument->IsConstant()) {
         // Do not inline if the constant length argument is not a smi or
-        // outside the valid range for a fast array.
+        // outside the valid range for unrolled loop initialization.
         HConstant* constant_argument = HConstant::cast(argument);
         if (constant_argument->HasSmiValue()) {
           int value = constant_argument->Integer32Value();
-          inline_ok = value >= 0 &&
-              value < JSObject::kInitialMaxFastElementArray;
+          inline_ok = value >= 0 && value <= kElementLoopUnrollThreshold;
           if (!inline_ok) {
             TraceInline(target, caller,
-                        "Length outside of valid array range");
+                        "Constant length outside of valid inlining range.");
           }
         }
       } else {
-        inline_ok = true;
+        TraceInline(target, caller,
+                    "Dont inline [new] Array(n) where n isn't constant.");
       }
-    } else {
+    } else if (argument_count == 0) {
       inline_ok = true;
+    } else {
+      TraceInline(target, caller, "Too many arguments to inline.");
     }
   } else {
     TraceInline(target, caller, "AllocationSite requested no inlining.");
@@ -8644,25 +8677,10 @@
   } else {
     // The constructor function is both an operand to the instruction and an
     // argument to the construct call.
-    Handle<JSFunction> array_function(
-        isolate()->native_context()->array_function(), isolate());
-    bool use_call_new_array = expr->target().is_identical_to(array_function);
-    if (use_call_new_array && IsCallNewArrayInlineable(expr)) {
-      // Verify we are still calling the array function for our native context.
-      Add<HCheckValue>(function, array_function);
-      BuildInlinedCallNewArray(expr);
-      return;
-    }
+    if (TryHandleArrayCallNew(expr, function)) return;
 
-    HBinaryCall* call;
-    if (use_call_new_array) {
-      Add<HCheckValue>(function, array_function);
-      call = New<HCallNewArray>(function, argument_count,
-                                expr->elements_kind());
-    } else {
-      call = New<HCallNew>(function, argument_count);
-    }
-    PreProcessCall(call);
+    HInstruction* call =
+        PreProcessCall(New<HCallNew>(function, argument_count));
     return ast_context()->ReturnInstruction(call, expr->id());
   }
 }
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 17cb7d1..bb05ebb 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1295,6 +1295,10 @@
 
   void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
 
+  // When initializing arrays, we'll unfold the loop if the number of elements
+  // is known at compile time and is <= kElementLoopUnrollThreshold.
+  static const int kElementLoopUnrollThreshold = 8;
+
  protected:
   virtual bool BuildGraph() = 0;
 
@@ -2242,6 +2246,11 @@
   // Try to optimize fun.apply(receiver, arguments) pattern.
   bool TryCallApply(Call* expr);
 
+  bool TryHandleArrayCall(Call* expr, HValue* function);
+  bool TryHandleArrayCallNew(CallNew* expr, HValue* function);
+  void BuildArrayCall(Expression* expr, int arguments_count, HValue* function,
+                      Handle<AllocationSite> cell);
+
   HValue* ImplicitReceiverFor(HValue* function,
                               Handle<JSFunction> target);
 
@@ -2325,8 +2334,13 @@
       ElementsKind fixed_elements_kind,
       HValue* byte_length, HValue* length);
 
-  bool IsCallNewArrayInlineable(CallNew* expr);
-  void BuildInlinedCallNewArray(CallNew* expr);
+  Handle<JSFunction> array_function() {
+    return handle(isolate()->native_context()->array_function());
+  }
+
+  bool IsCallArrayInlineable(int argument_count, Handle<AllocationSite> site);
+  void BuildInlinedCallArray(Expression* expression, int argument_count,
+                             Handle<AllocationSite> site);
 
   class PropertyAccessInfo {
    public:
diff --git a/src/i18n.cc b/src/i18n.cc
index 2b6b0fb..9883ef2 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -435,7 +435,7 @@
 
   Handle<String> key =
       factory->NewStringFromStaticAscii("minimumSignificantDigits");
-  if (JSReceiver::HasLocalProperty(resolved, key)) {
+  if (JSReceiver::HasOwnProperty(resolved, key)) {
     JSObject::SetProperty(
         resolved,
         factory->NewStringFromStaticAscii("minimumSignificantDigits"),
@@ -445,7 +445,7 @@
   }
 
   key = factory->NewStringFromStaticAscii("maximumSignificantDigits");
-  if (JSReceiver::HasLocalProperty(resolved, key)) {
+  if (JSReceiver::HasOwnProperty(resolved, key)) {
     JSObject::SetProperty(
         resolved,
         factory->NewStringFromStaticAscii("maximumSignificantDigits"),
@@ -823,7 +823,7 @@
     Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromStaticAscii("dateFormat");
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (JSReceiver::HasOwnProperty(obj, key)) {
     return reinterpret_cast<icu::SimpleDateFormat*>(
         obj->GetInternalField(0));
   }
@@ -897,7 +897,7 @@
     Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromStaticAscii("numberFormat");
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (JSReceiver::HasOwnProperty(obj, key)) {
     return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
   }
 
@@ -952,7 +952,7 @@
 icu::Collator* Collator::UnpackCollator(Isolate* isolate,
                                         Handle<JSObject> obj) {
   Handle<String> key = isolate->factory()->NewStringFromStaticAscii("collator");
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (JSReceiver::HasOwnProperty(obj, key)) {
     return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0));
   }
 
@@ -1011,7 +1011,7 @@
                                                        Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromStaticAscii("breakIterator");
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (JSReceiver::HasOwnProperty(obj, key)) {
     return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
   }
 
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index fea67e3..cee926f 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -52,8 +52,6 @@
   CPU cpu;
   CHECK(cpu.has_sse2());  // SSE2 support is mandatory.
   CHECK(cpu.has_cmov());  // CMOV support is mandatory.
-  CHECK(cpu.has_sahf());  // SAHF must be available in compat/legacy mode.
-  supported_ |= 1u << SAHF;
   supported_ |= OS::CpuFeaturesImpliedByPlatform();
 
   // Only use statically determined features for cross compile (snapshot).
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 8f9928e..5547ba2 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -2335,11 +2335,13 @@
 }
 
 
-void CallFunctionStub::Generate(MacroAssembler* masm) {
+static void CallFunctionNoFeedback(MacroAssembler* masm,
+                                   int argc, bool needs_checks,
+                                   bool call_as_method) {
   // edi : the function to call
   Label slow, non_function, wrap, cont;
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Check that the function really is a JavaScript function.
     __ JumpIfSmi(edi, &non_function);
 
@@ -2349,17 +2351,17 @@
   }
 
   // Fast-case: Just invoke the function.
-  ParameterCount actual(argc_);
+  ParameterCount actual(argc);
 
-  if (CallAsMethod()) {
-    if (NeedsChecks()) {
+  if (call_as_method) {
+    if (needs_checks) {
       EmitContinueIfStrictOrNative(masm, &cont);
     }
 
     // Load the receiver from the stack.
-    __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
+    __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
 
-    if (NeedsChecks()) {
+    if (call_as_method) {
       __ JumpIfSmi(eax, &wrap);
 
       __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
@@ -2373,20 +2375,25 @@
 
   __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Slow-case: Non-function called.
     __ bind(&slow);
     // (non_function is bound in EmitSlowCase)
-    EmitSlowCase(isolate(), masm, argc_, &non_function);
+    EmitSlowCase(masm->isolate(), masm, argc, &non_function);
   }
 
-  if (CallAsMethod()) {
+  if (call_as_method) {
     __ bind(&wrap);
-    EmitWrapCase(masm, argc_, &cont);
+    EmitWrapCase(masm, argc, &cont);
   }
 }
 
 
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+}
+
+
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // eax : number of arguments
   // ebx : feedback vector
@@ -2463,6 +2470,51 @@
 }
 
 
+void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
+  // edi - function
+  // ebx - feedback vector
+  // edx - slot id
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
+  __ cmp(edi, ecx);
+  __ j(not_equal, miss);
+
+  __ mov(eax, arg_count());
+  __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
+                           FixedArray::kHeaderSize));
+  // Verify that ecx contains an AllocationSite
+  __ AssertUndefinedOrAllocationSite(ebx);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+}
+
+
+void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
+  // edi - function
+  // ebx - feedback vector
+  // edx - slot id
+  Label miss;
+
+  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
+    Generate_MonomorphicArray(masm, &miss);
+  } else {
+    // So far there is only one customer for our custom feedback scheme.
+    UNREACHABLE();
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm,
+                         arg_count(),
+                         true,
+                         CallAsMethod());
+
+  // Unreachable.
+  __ int3();
+}
+
+
 void CallICStub::Generate(MacroAssembler* masm) {
   // edi - function
   // edx - slot id
@@ -2475,6 +2527,11 @@
 
   EmitLoadTypeFeedbackVector(masm, ebx);
 
+  if (state_.stub_type() != CallIC::DEFAULT) {
+    Generate_CustomFeedbackCall(masm);
+    return;
+  }
+
   // The checks. First, does edi match the recorded monomorphic target?
   __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
                            FixedArray::kHeaderSize));
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index e7a7b60..d9d970e 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -167,7 +167,7 @@
   // jumping to the target address intended by the caller and that was
   // overwritten by the address of DebugBreakXXX.
   ExternalReference after_break_target =
-      ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate());
+      ExternalReference::debug_after_break_target_address(masm->isolate());
   __ jmp(Operand::StaticVariable(after_break_target));
 }
 
@@ -308,8 +308,8 @@
 
 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
   ExternalReference restarter_frame_function_slot =
-      ExternalReference(Debug_Address::RestarterFrameFunctionPointer(),
-                        masm->isolate());
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
   __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
 
   // We do not know our frame height, but set esp based on ebp.
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 906ee3e..1d97d8a 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3041,8 +3041,7 @@
       key,
       instr->hydrogen()->key()->representation(),
       elements_kind,
-      0,
-      instr->additional_index()));
+      instr->base_offset()));
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS) {
     XMMRegister result(ToDoubleRegister(instr->result()));
@@ -3105,14 +3104,11 @@
 
 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
   if (instr->hydrogen()->RequiresHoleCheck()) {
-    int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
-        sizeof(kHoleNanLower32);
     Operand hole_check_operand = BuildFastArrayOperand(
         instr->elements(), instr->key(),
         instr->hydrogen()->key()->representation(),
         FAST_DOUBLE_ELEMENTS,
-        offset,
-        instr->additional_index());
+        instr->base_offset() + sizeof(kHoleNanLower32));
     __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
     DeoptimizeIf(equal, instr->environment());
   }
@@ -3122,8 +3118,7 @@
       instr->key(),
       instr->hydrogen()->key()->representation(),
       FAST_DOUBLE_ELEMENTS,
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
-      instr->additional_index());
+      instr->base_offset());
   XMMRegister result = ToDoubleRegister(instr->result());
   __ movsd(result, double_load_operand);
 }
@@ -3138,8 +3133,7 @@
                                instr->key(),
                                instr->hydrogen()->key()->representation(),
                                FAST_ELEMENTS,
-                               FixedArray::kHeaderSize - kHeapObjectTag,
-                               instr->additional_index()));
+                               instr->base_offset()));
 
   // Check for the hole value.
   if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3170,13 +3164,9 @@
     LOperand* key,
     Representation key_representation,
     ElementsKind elements_kind,
-    uint32_t offset,
-    uint32_t additional_index) {
+    uint32_t base_offset) {
   Register elements_pointer_reg = ToRegister(elements_pointer);
   int element_shift_size = ElementsKindToShiftSize(elements_kind);
-  if (IsFixedTypedArrayElementsKind(elements_kind)) {
-    offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
-  }
   int shift_size = element_shift_size;
   if (key->IsConstantOperand()) {
     int constant_value = ToInteger32(LConstantOperand::cast(key));
@@ -3184,8 +3174,8 @@
       Abort(kArrayIndexConstantValueTooBig);
     }
     return Operand(elements_pointer_reg,
-                   ((constant_value + additional_index) << shift_size)
-                       + offset);
+                   ((constant_value) << shift_size)
+                       + base_offset);
   } else {
     // Take the tag bit into account while computing the shift size.
     if (key_representation.IsSmi() && (shift_size >= 1)) {
@@ -3195,7 +3185,7 @@
     return Operand(elements_pointer_reg,
                    ToRegister(key),
                    scale_factor,
-                   offset + (additional_index << element_shift_size));
+                   base_offset);
   }
 }
 
@@ -4122,8 +4112,7 @@
       key,
       instr->hydrogen()->key()->representation(),
       elements_kind,
-      0,
-      instr->additional_index()));
+      instr->base_offset()));
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS) {
     XMMRegister xmm_scratch = double_scratch0();
@@ -4182,8 +4171,7 @@
       instr->key(),
       instr->hydrogen()->key()->representation(),
       FAST_DOUBLE_ELEMENTS,
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
-      instr->additional_index());
+      instr->base_offset());
 
   XMMRegister value = ToDoubleRegister(instr->value());
 
@@ -4210,8 +4198,7 @@
       instr->key(),
       instr->hydrogen()->key()->representation(),
       FAST_ELEMENTS,
-      FixedArray::kHeaderSize - kHeapObjectTag,
-      instr->additional_index());
+      instr->base_offset());
   if (instr->value()->IsRegister()) {
     __ mov(operand, ToRegister(instr->value()));
   } else {
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index d771893..d5a192e 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -241,8 +241,7 @@
                                 LOperand* key,
                                 Representation key_representation,
                                 ElementsKind elements_kind,
-                                uint32_t offset,
-                                uint32_t additional_index = 0);
+                                uint32_t base_offset);
 
   Operand BuildSeqStringOperand(Register string,
                                 LOperand* index,
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 067863d..76a107d 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -386,7 +386,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d]", additional_index());
+    stream->Add(" + %d]", base_offset());
   } else {
     stream->Add("]");
   }
@@ -398,7 +398,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d] <-", additional_index());
+    stream->Add(" + %d] <-", base_offset());
   } else {
     stream->Add("] <- ");
   }
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index ae80138..6cfe3e1 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -1642,7 +1642,7 @@
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool key_is_smi() {
     return hydrogen()->key()->representation().IsTagged();
   }
@@ -2222,7 +2222,7 @@
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
 };
 
diff --git a/src/ic.cc b/src/ic.cc
index a6efdab..463429e 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -207,7 +207,7 @@
       return;
     }
 
-    holder->LocalLookupRealNamedProperty(name, lookup);
+    holder->LookupOwnRealNamedProperty(name, lookup);
     if (lookup->IsFound()) {
       ASSERT(!lookup->IsInterceptor());
       return;
@@ -285,7 +285,7 @@
   if (receiver->IsGlobalObject()) {
     LookupResult lookup(isolate());
     GlobalObject* global = GlobalObject::cast(*receiver);
-    global->LocalLookupRealNamedProperty(name, &lookup);
+    global->LookupOwnRealNamedProperty(name, &lookup);
     if (!lookup.IsFound()) return false;
     PropertyCell* cell = global->GetPropertyCell(&lookup);
     return cell->type()->IsConstant();
@@ -501,7 +501,14 @@
                    Code* target,
                    ConstantPoolArray* constant_pool) {
   // Currently, CallIC doesn't have state changes.
-  ASSERT(target->ic_state() == v8::internal::GENERIC);
+  if (target->ic_state() != v8::internal::MONOMORPHIC) return;
+  CallIC::State existing_state(target->extra_ic_state());
+
+  // Monomorphic array stubs don't need to be cleared because
+  // 1) the stub doesn't store information that should be cleared, and
+  // 2) the AllocationSite stored in the type feedback vector is immune
+  //    from gc type feedback clearing.
+  ASSERT(existing_state.stub_type() == MONOMORPHIC_ARRAY);
 }
 
 
@@ -1186,7 +1193,7 @@
   receiver->Lookup(name, lookup);
   if (lookup->IsFound()) {
     if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) {
-      receiver->LocalLookupRealNamedProperty(name, lookup);
+      receiver->LookupOwnRealNamedProperty(name, lookup);
       if (!lookup->IsFound()) return false;
     }
 
@@ -1794,6 +1801,15 @@
     }
   }
 
+  if (store_handle.is_null()) {
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate(),
+        store_handle,
+        Runtime::SetObjectProperty(
+            isolate(), object, key, value, NONE, strict_mode()),
+        Object);
+  }
+
   if (!is_target_set()) {
     if (*stub == *generic_stub()) {
       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
@@ -1803,32 +1819,55 @@
     TRACE_IC("StoreIC", key);
   }
 
-  if (!store_handle.is_null()) return store_handle;
-  Handle<Object> result;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate(),
-      result,
-      Runtime::SetObjectProperty(
-          isolate(), object, key, value,  NONE, strict_mode()),
-      Object);
-  return result;
+  return store_handle;
 }
 
 
 CallIC::State::State(ExtraICState extra_ic_state)
     : argc_(ArgcBits::decode(extra_ic_state)),
-      call_type_(CallTypeBits::decode(extra_ic_state)) {
+      call_type_(CallTypeBits::decode(extra_ic_state)),
+      stub_type_(StubTypeBits::decode(extra_ic_state)) {
 }
 
 
 ExtraICState CallIC::State::GetExtraICState() const {
   ExtraICState extra_ic_state =
       ArgcBits::encode(argc_) |
-      CallTypeBits::encode(call_type_);
+      CallTypeBits::encode(call_type_) |
+      StubTypeBits::encode(stub_type_);
   return extra_ic_state;
 }
 
 
+bool CallIC::DoCustomHandler(Handle<Object> receiver,
+                             Handle<Object> function,
+                             Handle<FixedArray> vector,
+                             Handle<Smi> slot,
+                             const State& state) {
+  ASSERT(function->IsJSFunction());
+  // Are we the array function?
+  Handle<JSFunction> array_function = Handle<JSFunction>(
+      isolate()->context()->native_context()->array_function(), isolate());
+  if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
+    // Alter the slot.
+    Handle<AllocationSite> new_site = isolate()->factory()->NewAllocationSite();
+    vector->set(slot->value(), *new_site);
+    State new_state = state.ToMonomorphicArrayCallState();
+    CallICStub stub(isolate(), new_state);
+    set_target(*stub.GetCode());
+    Handle<String> name;
+    if (array_function->shared()->name()->IsString()) {
+      name = Handle<String>(String::cast(array_function->shared()->name()),
+                            isolate());
+    }
+
+    TRACE_IC("CallIC (Array call)", name);
+    return true;
+  }
+  return false;
+}
+
+
 void CallIC::HandleMiss(Handle<Object> receiver,
                         Handle<Object> function,
                         Handle<FixedArray> vector,
@@ -1836,18 +1875,33 @@
   State state(target()->extra_ic_state());
   Object* feedback = vector->get(slot->value());
 
-  if (feedback->IsJSFunction() || !function->IsJSFunction()) {
+  if (feedback->IsJSFunction() || !function->IsJSFunction() ||
+      state.stub_type() != DEFAULT) {
     // We are going generic.
-    ASSERT(!function->IsJSFunction() || *function != feedback);
-
     vector->set(slot->value(),
                 *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
                 SKIP_WRITE_BARRIER);
+
+    State new_state = state.ToGenericState();
+    if (new_state != state) {
+      // Only happens when the array ic goes generic.
+      ASSERT(state.stub_type() == MONOMORPHIC_ARRAY);
+      CallICStub stub(isolate(), new_state);
+      Handle<Code> code = stub.GetCode();
+      set_target(*code);
+    }
+
     TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
   } else {
     // If we came here feedback must be the uninitialized sentinel,
     // and we are going monomorphic.
     ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()));
+
+    // Do we want to install a custom handler?
+    if (DoCustomHandler(receiver, function, vector, slot, state)) {
+      return;
+    }
+
     Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
     Handle<Object> name(js_function->shared()->name(), isolate());
     TRACE_IC("CallIC", name);
@@ -1964,7 +2018,7 @@
 #ifdef DEBUG
   // The length property has to be a writable callback property.
   LookupResult debug_lookup(isolate);
-  receiver->LocalLookup(isolate->factory()->length_string(), &debug_lookup);
+  receiver->LookupOwn(isolate->factory()->length_string(), &debug_lookup);
   ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
 #endif
 
diff --git a/src/ic.h b/src/ic.h
index 197c32e..20b9b73 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -333,20 +333,34 @@
 class CallIC: public IC {
  public:
   enum CallType { METHOD, FUNCTION };
+  enum StubType { DEFAULT, MONOMORPHIC_ARRAY };
 
   class State V8_FINAL BASE_EMBEDDED {
    public:
     explicit State(ExtraICState extra_ic_state);
 
+    static State MonomorphicArrayCallState(int argc, CallType call_type) {
+      return State(argc, call_type, MONOMORPHIC_ARRAY);
+    }
+
     static State DefaultCallState(int argc, CallType call_type) {
-      return State(argc, call_type);
+      return State(argc, call_type, DEFAULT);
     }
 
-    static State MegamorphicCallState(int argc, CallType call_type) {
-      return State(argc, call_type);
+    // Transition from the current state to another.
+    State ToGenericState() const {
+      return DefaultCallState(arg_count(), call_type());
     }
 
-    InlineCacheState GetICState() const { return ::v8::internal::GENERIC; }
+    State ToMonomorphicArrayCallState() const {
+      return MonomorphicArrayCallState(arg_count(), call_type());
+    }
+
+    InlineCacheState GetICState() const {
+      return stub_type_ == CallIC::DEFAULT
+          ? ::v8::internal::GENERIC
+          : ::v8::internal::MONOMORPHIC;
+    }
 
     ExtraICState GetExtraICState() const;
 
@@ -355,6 +369,7 @@
 
     int arg_count() const { return argc_; }
     CallType call_type() const { return call_type_; }
+    StubType stub_type() const { return stub_type_; }
 
     bool CallAsMethod() const { return call_type_ == METHOD; }
 
@@ -370,17 +385,20 @@
     }
 
    private:
-    State(int argc,
-          CallType call_type)
+    State(int argc, CallType call_type, StubType stub_type)
         : argc_(argc),
-        call_type_(call_type) {
+        call_type_(call_type),
+        stub_type_(stub_type) {
     }
 
     class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {};
     class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {};
+    class StubTypeBits:
+        public BitField<StubType, Code::kArgumentsBits + 1, 1> {};  // NOLINT
 
     const int argc_;
     const CallType call_type_;
+    const StubType stub_type_;
   };
 
   explicit CallIC(Isolate* isolate)
@@ -392,6 +410,13 @@
                   Handle<FixedArray> vector,
                   Handle<Smi> slot);
 
+  // Returns true if a custom handler was installed.
+  bool DoCustomHandler(Handle<Object> receiver,
+                       Handle<Object> function,
+                       Handle<FixedArray> vector,
+                       Handle<Smi> slot,
+                       const State& new_state);
+
   // Code generator routines.
   static Handle<Code> initialize_stub(Isolate* isolate,
                                       int argc,
diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc
index b726a9b..7bce832 100644
--- a/src/incremental-marking.cc
+++ b/src/incremental-marking.cc
@@ -463,7 +463,7 @@
   return FLAG_incremental_marking &&
       FLAG_incremental_marking_steps &&
       heap_->gc_state() == Heap::NOT_IN_GC &&
-      !Serializer::enabled(heap_->isolate()) &&
+      !heap_->isolate()->serializer_enabled() &&
       heap_->isolate()->IsInitialized() &&
       heap_->PromotedSpaceSizeOfObjects() > kActivationThreshold;
 }
@@ -541,7 +541,7 @@
   ASSERT(FLAG_incremental_marking_steps);
   ASSERT(state_ == STOPPED);
   ASSERT(heap_->gc_state() == Heap::NOT_IN_GC);
-  ASSERT(!Serializer::enabled(heap_->isolate()));
+  ASSERT(!heap_->isolate()->serializer_enabled());
   ASSERT(heap_->isolate()->IsInitialized());
 
   ResetStepCounters();
diff --git a/src/isolate.cc b/src/isolate.cc
index f7605d8..9572046 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -494,30 +494,30 @@
             // tag.
             column_offset += script->column_offset()->value();
           }
-          JSObject::SetLocalPropertyIgnoreAttributes(
+          JSObject::SetOwnPropertyIgnoreAttributes(
               stack_frame, column_key,
               Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE).Check();
         }
-       JSObject::SetLocalPropertyIgnoreAttributes(
+       JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, line_key,
             Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE).Check();
       }
 
       if (options & StackTrace::kScriptId) {
         Handle<Smi> script_id(script->id(), this);
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, script_id_key, script_id, NONE).Check();
       }
 
       if (options & StackTrace::kScriptName) {
         Handle<Object> script_name(script->name(), this);
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, script_name_key, script_name, NONE).Check();
       }
 
       if (options & StackTrace::kScriptNameOrSourceURL) {
         Handle<Object> result = Script::GetNameOrSourceURL(script);
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, script_name_or_source_url_key, result, NONE).Check();
       }
 
@@ -526,7 +526,7 @@
         if (!fun_name->BooleanValue()) {
           fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
         }
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, function_key, fun_name, NONE).Check();
       }
 
@@ -534,14 +534,14 @@
         Handle<Object> is_eval =
             script->compilation_type() == Script::COMPILATION_TYPE_EVAL ?
                 factory()->true_value() : factory()->false_value();
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, eval_key, is_eval, NONE).Check();
       }
 
       if (options & StackTrace::kIsConstructor) {
         Handle<Object> is_constructor = (frames[i].is_constructor()) ?
             factory()->true_value() : factory()->false_value();
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             stack_frame, constructor_key, is_constructor, NONE).Check();
       }
 
@@ -1133,6 +1133,24 @@
       } else {
         OS::PrintError("Extension or internal compilation error.\n");
       }
+#ifdef OBJECT_PRINT
+      // Since comments and empty lines have been stripped from the source of
+      // builtins, print the actual source here so that line numbers match.
+      if (location->script()->source()->IsString()) {
+        Handle<String> src(String::cast(location->script()->source()));
+        PrintF("Failing script:\n");
+        int len = src->length();
+        int line_number = 1;
+        PrintF("%5d: ", line_number);
+        for (int i = 0; i < len; i++) {
+          uint16_t character = src->Get(i);
+          PrintF("%c", character);
+          if (character == '\n' && i < len - 2) {
+            PrintF("%5d: ", ++line_number);
+          }
+        }
+      }
+#endif
     }
   }
 
@@ -1457,8 +1475,8 @@
       // TODO(bmeurer) Initialized lazily because it depends on flags; can
       // be fixed once the default isolate cleanup is done.
       random_number_generator_(NULL),
+      serializer_enabled_(false),
       has_fatal_error_(false),
-      use_crankshaft_(true),
       initialized_from_snapshot_(false),
       cpu_profiler_(NULL),
       heap_profiler_(NULL),
@@ -1776,10 +1794,6 @@
 
   has_fatal_error_ = false;
 
-  use_crankshaft_ = FLAG_crankshaft
-      && !Serializer::enabled(this)
-      && CpuFeatures::SupportsCrankshaft();
-
   if (function_entry_hook() != NULL) {
     // When function entry hooking is in effect, we have to create the code
     // stubs from scratch to get entry hooks, rather than loading the previously
@@ -1965,7 +1979,7 @@
         kDeoptTableSerializeEntryCount - 1);
   }
 
-  if (!Serializer::enabled(this)) {
+  if (!serializer_enabled()) {
     // Ensure that all stubs which need to be generated ahead of time, but
     // cannot be serialized into the snapshot have been generated.
     HandleScope scope(this);
@@ -2138,6 +2152,13 @@
 }
 
 
+bool Isolate::use_crankshaft() const {
+  return FLAG_crankshaft &&
+         !serializer_enabled_ &&
+         CpuFeatures::SupportsCrankshaft();
+}
+
+
 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
   Map* root_array_map =
       get_initial_js_array_map(GetInitialFastElementsKind());
diff --git a/src/isolate.h b/src/isolate.h
index 3a67510..382cb5d 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -963,10 +963,18 @@
 
   THREAD_LOCAL_TOP_ACCESSOR(LookupResult*, top_lookup_result)
 
+  void enable_serializer() {
+    // The serializer can only be enabled before the isolate init.
+    ASSERT(state_ != INITIALIZED);
+    serializer_enabled_ = true;
+  }
+
+  bool serializer_enabled() const { return serializer_enabled_; }
+
   bool IsDead() { return has_fatal_error_; }
   void SignalFatalError() { has_fatal_error_ = true; }
 
-  bool use_crankshaft() const { return use_crankshaft_; }
+  bool use_crankshaft() const;
 
   bool initialized_from_snapshot() { return initialized_from_snapshot_; }
 
@@ -1232,12 +1240,12 @@
   CallInterfaceDescriptor* call_descriptors_;
   RandomNumberGenerator* random_number_generator_;
 
+  // Whether the isolate has been created for snapshotting.
+  bool serializer_enabled_;
+
   // True if fatal error has been signaled for this isolate.
   bool has_fatal_error_;
 
-  // True if we are using the Crankshaft optimizing compiler.
-  bool use_crankshaft_;
-
   // True if this isolate was initialized from a snapshot.
   bool initialized_from_snapshot_;
 
diff --git a/src/json-parser.h b/src/json-parser.h
index f301778..792fddf 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -425,7 +425,7 @@
         if (value.is_null()) return ReportUnexpectedCharacter();
       }
 
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           json_object, key, value, NONE).Assert();
     } while (MatchSkipWhiteSpace(','));
     if (c0_ != '}') {
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 7eb6746..1b51753 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -675,7 +675,7 @@
     Handle<FixedArray> contents;
     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
         isolate_, contents,
-        JSReceiver::GetKeys(object, JSReceiver::LOCAL_ONLY),
+        JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY),
         EXCEPTION);
 
     for (int i = 0; i < contents->length(); i++) {
diff --git a/src/lithium.cc b/src/lithium.cc
index c6d6413..0001e39 100644
--- a/src/lithium.cc
+++ b/src/lithium.cc
@@ -450,7 +450,7 @@
                    CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
 
     CodeGenerator::PrintCode(code, info());
-    ASSERT(!(Serializer::enabled(info()->isolate()) &&
+    ASSERT(!(info()->isolate()->serializer_enabled() &&
              info()->GetMustNotHaveEagerFrame() &&
              generator.NeedsEagerFrame()));
     return code;
diff --git a/src/liveedit-debugger.js b/src/liveedit-debugger.js
index 021a4f0..07214f9 100644
--- a/src/liveedit-debugger.js
+++ b/src/liveedit-debugger.js
@@ -946,7 +946,9 @@
       BLOCKED_ON_ACTIVE_STACK: 2,
       BLOCKED_ON_OTHER_STACK: 3,
       BLOCKED_UNDER_NATIVE_CODE: 4,
-      REPLACED_ON_ACTIVE_STACK: 5
+      REPLACED_ON_ACTIVE_STACK: 5,
+      BLOCKED_UNDER_GENERATOR: 6,
+      BLOCKED_ACTIVE_GENERATOR: 7
   };
 
   FunctionPatchabilityStatus.SymbolName = function(code) {
diff --git a/src/liveedit.cc b/src/liveedit.cc
index e6bb4b2..f43f38a 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -939,13 +939,10 @@
   // to code objects (that are never in new space) without worrying about
   // write barriers.
   Heap* heap = original->GetHeap();
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
-                          "liveedit.cc ReplaceCodeObject");
+  HeapIterator iterator(heap);
 
   ASSERT(!heap->InNewSpace(*substitution));
 
-  DisallowHeapAllocation no_allocation;
-
   ReplacingVisitor visitor(*original, *substitution);
 
   // Iterate over all roots. Stack frames may have pointer into original code,
@@ -955,7 +952,6 @@
 
   // Now iterate over all pointers of all objects, including code_target
   // implicit pointers.
-  HeapIterator iterator(heap);
   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
     obj->Iterate(&visitor);
   }
@@ -982,7 +978,7 @@
       // If literal count didn't change, simply go over all functions
       // and clear literal arrays.
       ClearValuesVisitor visitor;
-      IterateJSFunctions(*shared_info, &visitor);
+      IterateJSFunctions(shared_info, &visitor);
     } else {
       // When literal count changes, we have to create new array instances.
       // Since we cannot create instances when iterating heap, we should first
@@ -1017,16 +1013,14 @@
   // Iterates all function instances in the HEAP that refers to the
   // provided shared_info.
   template<typename Visitor>
-  static void IterateJSFunctions(SharedFunctionInfo* shared_info,
+  static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info,
                                  Visitor* visitor) {
-    DisallowHeapAllocation no_allocation;
-
     HeapIterator iterator(shared_info->GetHeap());
     for (HeapObject* obj = iterator.next(); obj != NULL;
         obj = iterator.next()) {
       if (obj->IsJSFunction()) {
         JSFunction* function = JSFunction::cast(obj);
-        if (function->shared() == shared_info) {
+        if (function->shared() == *shared_info) {
           visitor->visit(function);
         }
       }
@@ -1039,13 +1033,13 @@
       Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
     CountVisitor count_visitor;
     count_visitor.count = 0;
-    IterateJSFunctions(*shared_info, &count_visitor);
+    IterateJSFunctions(shared_info, &count_visitor);
     int size = count_visitor.count;
 
     Handle<FixedArray> result = isolate->factory()->NewFixedArray(size);
     if (size > 0) {
       CollectVisitor collect_visitor(result);
-      IterateJSFunctions(*shared_info, &collect_visitor);
+      IterateJSFunctions(shared_info, &collect_visitor);
     }
     return result;
   }
@@ -1165,7 +1159,7 @@
 
   Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
 
-  isolate->heap()->EnsureHeapIsIterable();
+  isolate->heap()->MakeHeapIterable();
 
   if (IsJSFunctionCode(shared_info->code())) {
     Handle<Code> code = compile_info_wrapper.GetFunctionCode();
@@ -1402,7 +1396,7 @@
   info->set_end_position(new_function_end);
   info->set_function_token_position(new_function_token_pos);
 
-  info->GetIsolate()->heap()->EnsureHeapIsIterable();
+  info->GetIsolate()->heap()->MakeHeapIterable();
 
   if (IsJSFunctionCode(info->code())) {
     // Patch relocation info section of the code.
@@ -1682,11 +1676,6 @@
 }
 
 
-static bool IsDropableFrame(StackFrame* frame) {
-  return !frame->is_exit();
-}
-
-
 // Describes a set of call frames that execute any of listed functions.
 // Finding no such frames does not mean error.
 class MultipleFunctionTarget {
@@ -1740,12 +1729,20 @@
 
   bool target_frame_found = false;
   int bottom_js_frame_index = top_frame_index;
-  bool c_code_found = false;
+  bool non_droppable_frame_found = false;
+  LiveEdit::FunctionPatchabilityStatus non_droppable_reason;
 
   for (; frame_index < frames.length(); frame_index++) {
     StackFrame* frame = frames[frame_index];
-    if (!IsDropableFrame(frame)) {
-      c_code_found = true;
+    if (frame->is_exit()) {
+      non_droppable_frame_found = true;
+      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE;
+      break;
+    }
+    if (frame->is_java_script() &&
+        JavaScriptFrame::cast(frame)->function()->shared()->is_generator()) {
+      non_droppable_frame_found = true;
+      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
       break;
     }
     if (target.MatchActivation(
@@ -1755,15 +1752,15 @@
     }
   }
 
-  if (c_code_found) {
-    // There is a C frames on stack. Check that there are no target frames
-    // below them.
+  if (non_droppable_frame_found) {
+    // There is a C or generator frame on stack.  We can't drop C frames, and we
+    // can't restart generators.  Check that there are no target frames below
+    // them.
     for (; frame_index < frames.length(); frame_index++) {
       StackFrame* frame = frames[frame_index];
       if (frame->is_java_script()) {
-        if (target.MatchActivation(
-                frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
-          // Cannot drop frame under C frames.
+        if (target.MatchActivation(frame, non_droppable_reason)) {
+          // Fail.
           return NULL;
         }
       }
@@ -1833,6 +1830,44 @@
 }
 
 
+bool LiveEdit::FindActiveGenerators(Handle<FixedArray> shared_info_array,
+                                    Handle<FixedArray> result,
+                                    int len) {
+  Isolate* isolate = shared_info_array->GetIsolate();
+  bool found_suspended_activations = false;
+
+  ASSERT_LE(len, result->length());
+
+  FunctionPatchabilityStatus active = FUNCTION_BLOCKED_ACTIVE_GENERATOR;
+
+  Heap* heap = isolate->heap();
+  HeapIterator iterator(heap);
+  HeapObject* obj = NULL;
+  while ((obj = iterator.next()) != NULL) {
+    if (!obj->IsJSGeneratorObject()) continue;
+
+    JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
+    if (gen->is_closed()) continue;
+
+    HandleScope scope(isolate);
+
+    for (int i = 0; i < len; i++) {
+      Handle<JSValue> jsvalue =
+          Handle<JSValue>::cast(FixedArray::get(shared_info_array, i));
+      Handle<SharedFunctionInfo> shared =
+          UnwrapSharedFunctionInfoFromJSValue(jsvalue);
+
+      if (gen->function()->shared() == *shared) {
+        result->set(i, Smi::FromInt(active));
+        found_suspended_activations = true;
+      }
+    }
+  }
+
+  return found_suspended_activations;
+}
+
+
 class InactiveThreadActivationsChecker : public ThreadVisitor {
  public:
   InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array,
@@ -1863,18 +1898,29 @@
   Isolate* isolate = shared_info_array->GetIsolate();
   int len = GetArrayLength(shared_info_array);
 
+  CHECK(shared_info_array->HasFastElements());
+  Handle<FixedArray> shared_info_array_elements(
+      FixedArray::cast(shared_info_array->elements()));
+
   Handle<JSArray> result = isolate->factory()->NewJSArray(len);
+  Handle<FixedArray> result_elements =
+      JSObject::EnsureWritableFastElements(result);
 
   // Fill the default values.
   for (int i = 0; i < len; i++) {
-    SetElementSloppy(
-        result,
-        i,
-        Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH), isolate));
+    FunctionPatchabilityStatus status = FUNCTION_AVAILABLE_FOR_PATCH;
+    result_elements->set(i, Smi::FromInt(status));
   }
 
+  // Scan the heap for active generators -- those that are either currently
+  // running (as we wouldn't want to restart them, because we don't know where
+  // to restart them from) or suspended.  Fail if any one corresponds to the set
+  // of functions being edited.
+  if (FindActiveGenerators(shared_info_array_elements, result_elements, len)) {
+    return result;
+  }
 
-  // First check inactive threads. Fail if some functions are blocked there.
+  // Check inactive threads. Fail if some functions are blocked there.
   InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
                                                             result);
   isolate->thread_manager()->IterateArchivedThreads(
@@ -1937,6 +1983,9 @@
   if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
     return "Function is blocked under native code";
   }
+  if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR) {
+    return "Function is blocked under a generator activation";
+  }
   return NULL;
 }
 
diff --git a/src/liveedit.h b/src/liveedit.h
index e06688a..b22d01a 100644
--- a/src/liveedit.h
+++ b/src/liveedit.h
@@ -89,6 +89,11 @@
                                          Handle<JSValue> orig_function_shared,
                                          Handle<JSValue> subst_function_shared);
 
+  // Find open generator activations, and set corresponding "result" elements to
+  // FUNCTION_BLOCKED_ACTIVE_GENERATOR.
+  static bool FindActiveGenerators(Handle<FixedArray> shared_info_array,
+                                   Handle<FixedArray> result, int len);
+
   // Checks listed functions on stack and return array with corresponding
   // FunctionPatchabilityStatus statuses; extra array element may
   // contain general error message. Modifies the current stack and
@@ -107,7 +112,9 @@
     FUNCTION_BLOCKED_ON_ACTIVE_STACK = 2,
     FUNCTION_BLOCKED_ON_OTHER_STACK = 3,
     FUNCTION_BLOCKED_UNDER_NATIVE_CODE = 4,
-    FUNCTION_REPLACED_ON_ACTIVE_STACK = 5
+    FUNCTION_REPLACED_ON_ACTIVE_STACK = 5,
+    FUNCTION_BLOCKED_UNDER_GENERATOR = 6,
+    FUNCTION_BLOCKED_ACTIVE_GENERATOR = 7
   };
 
   // Compares 2 strings line-by-line, then token-wise and returns diff in form
diff --git a/src/log.cc b/src/log.cc
index 623e08d..5c88cb4 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -230,6 +230,7 @@
   virtual ~PerfBasicLogger();
 
   virtual void CodeMoveEvent(Address from, Address to) { }
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from) { }
 
  private:
@@ -295,6 +296,7 @@
   virtual ~PerfJitLogger();
 
   virtual void CodeMoveEvent(Address from, Address to) { }
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from) { }
 
  private:
@@ -457,6 +459,7 @@
   virtual ~LowLevelLogger();
 
   virtual void CodeMoveEvent(Address from, Address to);
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from);
   virtual void SnapshotPositionEvent(Address addr, int pos);
   virtual void CodeMovingGCEvent();
@@ -623,6 +626,7 @@
   explicit JitLogger(JitCodeEventHandler code_event_handler);
 
   virtual void CodeMoveEvent(Address from, Address to);
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from);
   virtual void AddCodeLinePosInfoEvent(
       void* jit_handler_data,
@@ -1446,6 +1450,24 @@
 }
 
 
+void Logger::CodeDisableOptEvent(Code* code,
+                                 SharedFunctionInfo* shared) {
+  PROFILER_LOG(CodeDisableOptEvent(code, shared));
+
+  if (!is_logging_code_events()) return;
+  CALL_LISTENERS(CodeDisableOptEvent(code, shared));
+
+  if (!FLAG_log_code || !log_->IsEnabled()) return;
+  Log::MessageBuilder msg(log_);
+  msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]);
+  SmartArrayPointer<char> name =
+      shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+  msg.Append("\"%s\",", name.get());
+  msg.Append("\"%s\"\n", GetBailoutReason(shared->DisableOptimizationReason()));
+  msg.WriteToLogFile();
+}
+
+
 void Logger::CodeMovingGCEvent() {
   PROFILER_LOG(CodeMovingGCEvent());
 
diff --git a/src/log.h b/src/log.h
index b1a41e9..19adecb 100644
--- a/src/log.h
+++ b/src/log.h
@@ -79,6 +79,7 @@
 
 #define LOG_EVENTS_AND_TAGS_LIST(V)                                     \
   V(CODE_CREATION_EVENT,            "code-creation")                    \
+  V(CODE_DISABLE_OPT_EVENT,         "code-disable-optimization")        \
   V(CODE_MOVE_EVENT,                "code-move")                        \
   V(CODE_DELETE_EVENT,              "code-delete")                      \
   V(CODE_MOVING_GC,                 "code-moving-gc")                   \
@@ -237,6 +238,8 @@
                        CompilationInfo* info,
                        Name* source, int line, int column);
   void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
+  // Emits a code deoptimization event.
+  void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
   void CodeMovingGCEvent();
   // Emits a code create event for a RegExp.
   void RegExpCodeCreateEvent(Code* code, String* source);
@@ -470,6 +473,7 @@
   virtual void CodeDeleteEvent(Address from) = 0;
   virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
   virtual void CodeMovingGCEvent() = 0;
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) = 0;
 };
 
 
diff --git a/src/macros.py b/src/macros.py
index 39881fe..9b256cb 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -171,7 +171,7 @@
 macro GLOBAL_PRIVATE(name) = (%CreateGlobalPrivateSymbol(name));
 macro NEW_PRIVATE(name) = (%CreatePrivateSymbol(name));
 macro IS_PRIVATE(sym) = (%SymbolIsPrivate(sym));
-macro HAS_PRIVATE(obj, sym) = (%HasLocalProperty(obj, sym));
+macro HAS_PRIVATE(obj, sym) = (%HasOwnProperty(obj, sym));
 macro GET_PRIVATE(obj, sym) = (obj[sym]);
 macro SET_PRIVATE(obj, sym, val) = (obj[sym] = val);
 macro DELETE_PRIVATE(obj, sym) = (delete obj[sym]);
diff --git a/src/messages.js b/src/messages.js
index d20b34b..859bc0d 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -1240,7 +1240,7 @@
 function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
   var current = error;
   // Climb the prototype chain until we find the holder.
-  while (current && !%HasLocalProperty(current, name)) {
+  while (current && !%HasOwnProperty(current, name)) {
     current = %GetPrototype(current);
   }
   if (IS_NULL(current)) return UNDEFINED;
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 6e033b9..f47ab38 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -3094,11 +3094,13 @@
 }
 
 
-void CallFunctionStub::Generate(MacroAssembler* masm) {
+static void CallFunctionNoFeedback(MacroAssembler* masm,
+                                   int argc, bool needs_checks,
+                                   bool call_as_method) {
   // a1 : the function to call
   Label slow, non_function, wrap, cont;
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Check that the function is really a JavaScript function.
     // a1: pushed function (to be verified)
     __ JumpIfSmi(a1, &non_function);
@@ -3110,18 +3112,17 @@
 
   // Fast-case: Invoke the function now.
   // a1: pushed function
-  int argc = argc_;
   ParameterCount actual(argc);
 
-  if (CallAsMethod()) {
-    if (NeedsChecks()) {
+  if (call_as_method) {
+    if (needs_checks) {
       EmitContinueIfStrictOrNative(masm, &cont);
     }
 
     // Compute the receiver in sloppy mode.
     __ lw(a3, MemOperand(sp, argc * kPointerSize));
 
-    if (NeedsChecks()) {
+    if (needs_checks) {
       __ JumpIfSmi(a3, &wrap);
       __ GetObjectType(a3, t0, t0);
       __ Branch(&wrap, lt, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
@@ -3134,13 +3135,13 @@
 
   __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper());
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Slow-case: Non-function called.
     __ bind(&slow);
     EmitSlowCase(masm, argc, &non_function);
   }
 
-  if (CallAsMethod()) {
+  if (call_as_method) {
     __ bind(&wrap);
     // Wrap the receiver and patch it back onto the stack.
     EmitWrapCase(masm, argc, &cont);
@@ -3148,6 +3149,11 @@
 }
 
 
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+}
+
+
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // a0 : number of arguments
   // a1 : the function to call
@@ -3207,8 +3213,8 @@
   __ bind(&do_call);
   // Set expected number of arguments to zero (not changing r0).
   __ li(a2, Operand(0, RelocInfo::NONE32));
-  __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
-          RelocInfo::CODE_TARGET);
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+           RelocInfo::CODE_TARGET);
 }
 
 
@@ -3221,6 +3227,51 @@
 }
 
 
+void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
+  // a1 - function
+  // a2 - feedback vector
+  // a3 - slot id
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, at);
+  __ Branch(miss, ne, a1, Operand(at));
+
+  __ li(a0, Operand(arg_count()));
+  __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize);
+  __ Addu(at, a2, Operand(at));
+  __ lw(a2, FieldMemOperand(at, FixedArray::kHeaderSize));
+  // Verify that a2 contains an AllocationSite
+  __ AssertUndefinedOrAllocationSite(a2, at);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+}
+
+
+void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
+  // a1 - function
+  // a2 - feedback vector
+  // a3 - slot id
+  Label miss;
+
+  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
+    Generate_MonomorphicArray(masm, &miss);
+  } else {
+    // So far there is only one customer for our custom feedback scheme.
+    UNREACHABLE();
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm,
+                         arg_count(),
+                         true,
+                         CallAsMethod());
+
+  // Unreachable.
+  __ stop("Unexpected code address");
+}
+
+
 void CallICStub::Generate(MacroAssembler* masm) {
   // r1 - function
   // r3 - slot id (Smi)
@@ -3232,6 +3283,11 @@
 
   EmitLoadTypeFeedbackVector(masm, a2);
 
+  if (state_.stub_type() != CallIC::DEFAULT) {
+    Generate_CustomFeedbackCall(masm);
+    return;
+  }
+
   // The checks. First, does r1 match the recorded monomorphic target?
   __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
   __ Addu(t0, a2, Operand(t0));
diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc
index fcb5643..0ef9e29 100644
--- a/src/mips/debug-mips.cc
+++ b/src/mips/debug-mips.cc
@@ -155,8 +155,9 @@
   // Now that the break point has been handled, resume normal execution by
   // jumping to the target address intended by the caller and that was
   // overwritten by the address of DebugBreakXXX.
-  __ li(t9, Operand(
-      ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate())));
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ li(t9, Operand(after_break_target));
   __ lw(t9, MemOperand(t9));
   __ Jump(t9);
 }
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index b5d8fa8..fd30b1a 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -3110,16 +3110,13 @@
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
   int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
       ? (element_size_shift - kSmiTagSize) : element_size_shift;
-  int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
-      ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-      : 0;
+  int base_offset = instr->base_offset();
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS ||
       elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
       elements_kind == FLOAT64_ELEMENTS) {
-    int base_offset =
-      (instr->additional_index() << element_size_shift) + additional_offset;
+    int base_offset = instr->base_offset();
     FPURegister result = ToDoubleRegister(instr->result());
     if (key_is_constant) {
       __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
@@ -3131,15 +3128,14 @@
         elements_kind == FLOAT32_ELEMENTS) {
       __ lwc1(result, MemOperand(scratch0(), base_offset));
       __ cvt_d_s(result, result);
-    } else  {  // loading doubles, not floats.
+    } else  {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
       __ ldc1(result, MemOperand(scratch0(), base_offset));
     }
   } else {
     Register result = ToRegister(instr->result());
     MemOperand mem_operand = PrepareKeyedOperand(
         key, external_pointer, key_is_constant, constant_key,
-        element_size_shift, shift_size,
-        instr->additional_index(), additional_offset);
+        element_size_shift, shift_size, base_offset);
     switch (elements_kind) {
       case EXTERNAL_INT8_ELEMENTS:
       case INT8_ELEMENTS:
@@ -3199,15 +3195,13 @@
 
   int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
 
-  int base_offset =
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag +
-      (instr->additional_index() << element_size_shift);
+  int base_offset = instr->base_offset();
   if (key_is_constant) {
     int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
     if (constant_key & 0xF0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    base_offset += constant_key << element_size_shift;
+    base_offset += constant_key * kDoubleSize;
   }
   __ Addu(scratch, elements, Operand(base_offset));
 
@@ -3233,12 +3227,11 @@
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
   Register store_base = scratch;
-  int offset = 0;
+  int offset = instr->base_offset();
 
   if (instr->key()->IsConstantOperand()) {
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                           instr->additional_index());
+    offset += ToInteger32(const_operand) * kPointerSize;
     store_base = elements;
   } else {
     Register key = ToRegister(instr->key());
@@ -3253,9 +3246,8 @@
       __ sll(scratch, key, kPointerSizeLog2);
       __ addu(scratch, elements, scratch);
     }
-    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
   }
-  __ lw(result, FieldMemOperand(store_base, offset));
+  __ lw(result, MemOperand(store_base, offset));
 
   // Check for the hole value.
   if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3287,34 +3279,12 @@
                                          int constant_key,
                                          int element_size,
                                          int shift_size,
-                                         int additional_index,
-                                         int additional_offset) {
-  int base_offset = (additional_index << element_size) + additional_offset;
+                                         int base_offset) {
   if (key_is_constant) {
-    return MemOperand(base,
-                      base_offset + (constant_key << element_size));
+    return MemOperand(base, (constant_key << element_size) + base_offset);
   }
 
-  if (additional_offset != 0) {
-    if (shift_size >= 0) {
-      __ sll(scratch0(), key, shift_size);
-      __ Addu(scratch0(), scratch0(), Operand(base_offset));
-    } else {
-      ASSERT_EQ(-1, shift_size);
-      // Key can be negative, so using sra here.
-      __ sra(scratch0(), key, 1);
-      __ Addu(scratch0(), scratch0(), Operand(base_offset));
-    }
-    __ Addu(scratch0(), base, scratch0());
-    return MemOperand(scratch0());
-  }
-
-  if (additional_index != 0) {
-    additional_index *= 1 << (element_size - shift_size);
-    __ Addu(scratch0(), key, Operand(additional_index));
-  }
-
-  if (additional_index == 0) {
+  if (base_offset == 0) {
     if (shift_size >= 0) {
       __ sll(scratch0(), key, shift_size);
       __ Addu(scratch0(), base, scratch0());
@@ -3328,14 +3298,14 @@
   }
 
   if (shift_size >= 0) {
-    __ sll(scratch0(), scratch0(), shift_size);
+    __ sll(scratch0(), key, shift_size);
     __ Addu(scratch0(), base, scratch0());
-    return MemOperand(scratch0());
+    return MemOperand(scratch0(), base_offset);
   } else {
     ASSERT_EQ(-1, shift_size);
-    __ srl(scratch0(), scratch0(), 1);
+    __ sra(scratch0(), key, 1);
     __ Addu(scratch0(), base, scratch0());
-    return MemOperand(scratch0());
+    return MemOperand(scratch0(), base_offset);
   }
 }
 
@@ -4208,16 +4178,12 @@
   int element_size_shift = ElementsKindToShiftSize(elements_kind);
   int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
       ? (element_size_shift - kSmiTagSize) : element_size_shift;
-  int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
-      ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-      : 0;
+  int base_offset = instr->base_offset();
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS ||
       elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
       elements_kind == FLOAT64_ELEMENTS) {
-    int base_offset =
-      (instr->additional_index() << element_size_shift) + additional_offset;
     Register address = scratch0();
     FPURegister value(ToDoubleRegister(instr->value()));
     if (key_is_constant) {
@@ -4244,7 +4210,7 @@
     MemOperand mem_operand = PrepareKeyedOperand(
         key, external_pointer, key_is_constant, constant_key,
         element_size_shift, shift_size,
-        instr->additional_index(), additional_offset);
+        base_offset);
     switch (elements_kind) {
       case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
       case EXTERNAL_INT8_ELEMENTS:
@@ -4291,6 +4257,7 @@
   Register scratch = scratch0();
   DoubleRegister double_scratch = double_scratch0();
   bool key_is_constant = instr->key()->IsConstantOperand();
+  int base_offset = instr->base_offset();
   Label not_nan, done;
 
   // Calculate the effective address of the slot in the array to store the
@@ -4302,13 +4269,11 @@
       Abort(kArrayIndexConstantValueTooBig);
     }
     __ Addu(scratch, elements,
-            Operand((constant_key << element_size_shift) +
-                    FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+           Operand((constant_key << element_size_shift) + base_offset));
   } else {
     int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
         ? (element_size_shift - kSmiTagSize) : element_size_shift;
-    __ Addu(scratch, elements,
-            Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+    __ Addu(scratch, elements, Operand(base_offset));
     __ sll(at, ToRegister(instr->key()), shift_size);
     __ Addu(scratch, scratch, at);
   }
@@ -4323,14 +4288,12 @@
     __ bind(&is_nan);
     __ LoadRoot(at, Heap::kNanValueRootIndex);
     __ ldc1(double_scratch, FieldMemOperand(at, HeapNumber::kValueOffset));
-    __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() <<
-        element_size_shift));
+    __ sdc1(double_scratch, MemOperand(scratch, 0));
     __ Branch(&done);
   }
 
   __ bind(&not_nan);
-  __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
-      element_size_shift));
+  __ sdc1(value, MemOperand(scratch, 0));
   __ bind(&done);
 }
 
@@ -4342,14 +4305,13 @@
       : no_reg;
   Register scratch = scratch0();
   Register store_base = scratch;
-  int offset = 0;
+  int offset = instr->base_offset();
 
   // Do the store.
   if (instr->key()->IsConstantOperand()) {
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
-    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
-                                           instr->additional_index());
+    offset += ToInteger32(const_operand) * kPointerSize;
     store_base = elements;
   } else {
     // Even though the HLoadKeyed instruction forces the input
@@ -4363,16 +4325,15 @@
       __ sll(scratch, key, kPointerSizeLog2);
       __ addu(scratch, elements, scratch);
     }
-    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
   }
-  __ sw(value, FieldMemOperand(store_base, offset));
+  __ sw(value, MemOperand(store_base, offset));
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
     SmiCheck check_needed =
         instr->hydrogen()->value()->IsHeapObject()
             ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
-    __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
+    __ Addu(key, store_base, Operand(offset));
     __ RecordWrite(elements,
                    key,
                    value,
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 7c52d81..0657fad 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -132,8 +132,7 @@
                                  int constant_key,
                                  int element_size,
                                  int shift_size,
-                                 int additional_index,
-                                 int additional_offset);
+                                 int base_offset);
 
   // Emit frame translation commands for an environment.
   void WriteTranslation(LEnvironment* environment, Translation* translation);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 97b91fa..28cd6dd 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -342,7 +342,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d]", additional_index());
+    stream->Add(" + %d]", base_offset());
   } else {
     stream->Add("]");
   }
@@ -354,7 +354,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d] <-", additional_index());
+    stream->Add(" + %d] <-", base_offset());
   } else {
     stream->Add("] <- ");
   }
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 8133c31..ad2a1e7 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -1609,7 +1609,7 @@
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
   virtual void PrintDataTo(StringStream* stream);
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
 
@@ -2178,7 +2178,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
 
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 2695e01..b1f67ac 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -676,9 +676,9 @@
 
   // Find all the named properties.
   if (kind & PropertyKind.Named) {
-    // Get all the local property names except for private symbols.
+    // Get all own property names except for private symbols.
     propertyNames =
-        %GetLocalPropertyNames(this.value_, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
+        %GetOwnPropertyNames(this.value_, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
     total += propertyNames.length;
 
     // Get names for named interceptor properties if any.
@@ -694,8 +694,8 @@
 
   // Find all the indexed properties.
   if (kind & PropertyKind.Indexed) {
-    // Get the local element names.
-    elementNames = %GetLocalElementNames(this.value_);
+    // Get own element names.
+    elementNames = %GetOwnElementNames(this.value_);
     total += elementNames.length;
 
     // Get names for indexed interceptor properties.
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index 4f8d414..e04d8da 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -296,106 +296,103 @@
   i::FLAG_logfile_per_isolate = false;
 
   Isolate* isolate = v8::Isolate::New();
-  isolate->Enter();
-  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  i::Serializer::RequestEnable(internal_isolate);
-  Persistent<Context> context;
-  {
-    HandleScope handle_scope(isolate);
-    context.Reset(isolate, Context::New(isolate));
-  }
+  { Isolate::Scope isolate_scope(isolate);
+    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+    internal_isolate->enable_serializer();
 
-  if (context.IsEmpty()) {
-    fprintf(stderr,
-            "\nException thrown while compiling natives - see above.\n\n");
-    exit(1);
-  }
-  if (i::FLAG_extra_code != NULL) {
-    // Capture 100 frames if anything happens.
-    V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
-    HandleScope scope(isolate);
-    v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
-    const char* name = i::FLAG_extra_code;
-    FILE* file = i::OS::FOpen(name, "rb");
-    if (file == NULL) {
-      fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
-      exit(1);
+    Persistent<Context> context;
+    {
+      HandleScope handle_scope(isolate);
+      context.Reset(isolate, Context::New(isolate));
     }
 
-    fseek(file, 0, SEEK_END);
-    int size = ftell(file);
-    rewind(file);
-
-    char* chars = new char[size + 1];
-    chars[size] = '\0';
-    for (int i = 0; i < size;) {
-      int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
-      if (read < 0) {
-        fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
+    if (context.IsEmpty()) {
+      fprintf(stderr,
+              "\nException thrown while compiling natives - see above.\n\n");
+      exit(1);
+    }
+    if (i::FLAG_extra_code != NULL) {
+      // Capture 100 frames if anything happens.
+      V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
+      HandleScope scope(isolate);
+      v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
+      const char* name = i::FLAG_extra_code;
+      FILE* file = i::OS::FOpen(name, "rb");
+      if (file == NULL) {
+        fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
         exit(1);
       }
-      i += read;
+
+      fseek(file, 0, SEEK_END);
+      int size = ftell(file);
+      rewind(file);
+
+      char* chars = new char[size + 1];
+      chars[size] = '\0';
+      for (int i = 0; i < size;) {
+        int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
+        if (read < 0) {
+          fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
+          exit(1);
+        }
+        i += read;
+      }
+      fclose(file);
+      Local<String> source = String::NewFromUtf8(isolate, chars);
+      TryCatch try_catch;
+      Local<Script> script = Script::Compile(source);
+      if (try_catch.HasCaught()) {
+        fprintf(stderr, "Failure compiling '%s'\n", name);
+        DumpException(try_catch.Message());
+        exit(1);
+      }
+      script->Run();
+      if (try_catch.HasCaught()) {
+        fprintf(stderr, "Failure running '%s'\n", name);
+        DumpException(try_catch.Message());
+        exit(1);
+      }
     }
-    fclose(file);
-    Local<String> source = String::NewFromUtf8(isolate, chars);
-    TryCatch try_catch;
-    Local<Script> script = Script::Compile(source);
-    if (try_catch.HasCaught()) {
-      fprintf(stderr, "Failure compiling '%s'\n", name);
-      DumpException(try_catch.Message());
-      exit(1);
+    // Make sure all builtin scripts are cached.
+    { HandleScope scope(isolate);
+      for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
+        internal_isolate->bootstrapper()->NativesSourceLookup(i);
+      }
     }
-    script->Run();
-    if (try_catch.HasCaught()) {
-      fprintf(stderr, "Failure running '%s'\n", name);
-      DumpException(try_catch.Message());
-      exit(1);
+    // If we don't do this then we end up with a stray root pointing at the
+    // context even after we have disposed of the context.
+    internal_isolate->heap()->CollectAllGarbage(
+        i::Heap::kNoGCFlags, "mksnapshot");
+    i::Object* raw_context = *v8::Utils::OpenPersistent(context);
+    context.Reset();
+
+    // This results in a somewhat smaller snapshot, probably because it gets
+    // rid of some things that are cached between garbage collections.
+    i::List<char> snapshot_data;
+    ListSnapshotSink snapshot_sink(&snapshot_data);
+    i::StartupSerializer ser(internal_isolate, &snapshot_sink);
+    ser.SerializeStrongReferences();
+
+    i::List<char> context_data;
+    ListSnapshotSink contex_sink(&context_data);
+    i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
+    context_ser.Serialize(&raw_context);
+    ser.SerializeWeakReferences();
+
+    {
+      SnapshotWriter writer(argv[1]);
+      writer.SetOmit(i::FLAG_omit);
+      if (i::FLAG_raw_file && i::FLAG_raw_context_file)
+        writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
+  #ifdef COMPRESS_STARTUP_DATA_BZ2
+      BZip2Compressor bzip2;
+      writer.SetCompressor(&bzip2);
+  #endif
+      writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
     }
   }
-  // Make sure all builtin scripts are cached.
-  { HandleScope scope(isolate);
-    for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
-      internal_isolate->bootstrapper()->NativesSourceLookup(i);
-    }
-  }
-  // If we don't do this then we end up with a stray root pointing at the
-  // context even after we have disposed of the context.
-  internal_isolate->heap()->CollectAllGarbage(
-      i::Heap::kNoGCFlags, "mksnapshot");
-  i::Object* raw_context = *v8::Utils::OpenPersistent(context);
-  context.Reset();
 
-  // This results in a somewhat smaller snapshot, probably because it gets rid
-  // of some things that are cached between garbage collections.
-  i::List<char> snapshot_data;
-  ListSnapshotSink snapshot_sink(&snapshot_data);
-  i::StartupSerializer ser(internal_isolate, &snapshot_sink);
-  ser.SerializeStrongReferences();
-
-  i::List<char> context_data;
-  ListSnapshotSink contex_sink(&context_data);
-  i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
-  context_ser.Serialize(&raw_context);
-  ser.SerializeWeakReferences();
-
-  {
-    SnapshotWriter writer(argv[1]);
-    writer.SetOmit(i::FLAG_omit);
-    if (i::FLAG_raw_file && i::FLAG_raw_context_file)
-      writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-    BZip2Compressor bzip2;
-    writer.SetCompressor(&bzip2);
-#endif
-    writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
-  }
-
-  isolate->Exit();
   isolate->Dispose();
-  // TODO(svenpanne) Alas, we can't cleanly dispose V8 here, because
-  // Serializer::code_address_map_ is static (a.k.a. a global variable), and
-  // disposing that would involve accessing the Isolate just disposed.
-  // code_address_map_ really has to be an instance variable...
-  // V8::Dispose();
+  V8::Dispose();
   return 0;
 }
diff --git a/src/objects-inl.h b/src/objects-inl.h
index dca3eca..0be46bc 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5715,6 +5715,14 @@
   return continuation() > 0;
 }
 
+bool JSGeneratorObject::is_closed() {
+  return continuation() == kGeneratorClosed;
+}
+
+bool JSGeneratorObject::is_executing() {
+  return continuation() == kGeneratorExecuting;
+}
+
 JSGeneratorObject* JSGeneratorObject::cast(Object* obj) {
   ASSERT(obj->IsJSGeneratorObject());
   ASSERT(HeapObject::cast(obj)->Size() == JSGeneratorObject::kSize);
@@ -6276,13 +6284,12 @@
 }
 
 
-bool JSReceiver::HasLocalProperty(Handle<JSReceiver> object,
-                                  Handle<Name> name) {
+bool JSReceiver::HasOwnProperty(Handle<JSReceiver> object, Handle<Name> name) {
   if (object->IsJSProxy()) {
     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
     return JSProxy::HasPropertyWithHandler(proxy, name);
   }
-  return GetLocalPropertyAttribute(object, name) != ABSENT;
+  return GetOwnPropertyAttribute(object, name) != ABSENT;
 }
 
 
@@ -6341,7 +6348,7 @@
 }
 
 
-bool JSReceiver::HasLocalElement(Handle<JSReceiver> object, uint32_t index) {
+bool JSReceiver::HasOwnElement(Handle<JSReceiver> object, uint32_t index) {
   if (object->IsJSProxy()) {
     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
     return JSProxy::HasElementWithHandler(proxy, index);
@@ -6351,7 +6358,7 @@
 }
 
 
-PropertyAttributes JSReceiver::GetLocalElementAttribute(
+PropertyAttributes JSReceiver::GetOwnElementAttribute(
     Handle<JSReceiver> object, uint32_t index) {
   if (object->IsJSProxy()) {
     return JSProxy::GetElementAttributeWithHandler(
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index bb2e992..9234a9e 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -290,7 +290,7 @@
   if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
       && (target->ic_state() == MEGAMORPHIC || target->ic_state() == GENERIC ||
           target->ic_state() == POLYMORPHIC || heap->flush_monomorphic_ics() ||
-          Serializer::enabled(heap->isolate()) ||
+          heap->isolate()->serializer_enabled() ||
           target->ic_age() != heap->global_ic_age() ||
           target->is_invalidated_weak_stub())) {
     IC::Clear(heap->isolate(), rinfo->pc(), rinfo->host()->constant_pool());
@@ -406,7 +406,7 @@
     Map* map, HeapObject* object) {
   Heap* heap = map->GetHeap();
   Code* code = Code::cast(object);
-  if (FLAG_age_code && !Serializer::enabled(heap->isolate())) {
+  if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
     code->MakeOlder(heap->mark_compact_collector()->marking_parity());
   }
   code->CodeIterateBody<StaticVisitor>(heap);
diff --git a/src/objects.cc b/src/objects.cc
index 769d5fc..352e5d6 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -560,7 +560,7 @@
         if (continue_search) {
           result->holder()->LookupRealNamedProperty(name, &r);
         } else {
-          result->holder()->LocalLookupRealNamedProperty(name, &r);
+          result->holder()->LookupOwnRealNamedProperty(name, &r);
         }
         if (!r.IsFound()) break;
         return GetPropertyAttributeWithFailedAccessCheck(
@@ -2014,10 +2014,10 @@
     Handle<Object> value,
     PropertyAttributes attributes,
     StrictMode strict_mode) {
-  // Check local property, ignore interceptor.
+  // Check own property, ignore interceptor.
   Isolate* isolate = object->GetIsolate();
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(name, &result);
+  object->LookupOwnRealNamedProperty(name, &result);
   if (!result.IsFound()) {
     object->map()->LookupTransition(*object, *name, &result);
   }
@@ -2996,7 +2996,7 @@
                                             StrictMode strict_mode,
                                             StoreFromKeyed store_mode) {
   LookupResult result(object->GetIsolate());
-  object->LocalLookup(name, &result, true);
+  object->LookupOwn(name, &result, true);
   if (!result.IsFound()) {
     object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
   }
@@ -3144,7 +3144,7 @@
   Isolate* isolate = object->GetIsolate();
 
   *done = false;
-  // We could not find a local property so let's check whether there is an
+  // We could not find an own property, so let's check whether there is an
   // accessor that wants to handle the property, or whether the property is
   // read-only on the prototype chain.
   LookupResult result(isolate);
@@ -3520,20 +3520,20 @@
 }
 
 
-void JSObject::LocalLookupRealNamedProperty(Handle<Name> name,
-                                            LookupResult* result) {
+void JSObject::LookupOwnRealNamedProperty(Handle<Name> name,
+                                          LookupResult* result) {
   DisallowHeapAllocation no_gc;
   if (IsJSGlobalProxy()) {
     Object* proto = GetPrototype();
     if (proto->IsNull()) return result->NotFound();
     ASSERT(proto->IsJSGlobalObject());
-    return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result);
+    return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result);
   }
 
   if (HasFastProperties()) {
     map()->LookupDescriptor(this, *name, result);
     // A property or a map transition was found. We return all of these result
-    // types because LocalLookupRealNamedProperty is used when setting
+    // types because LookupOwnRealNamedProperty is used when setting
     // properties where map transitions are handled.
     ASSERT(!result->IsFound() ||
            (result->holder() == this && result->IsFastPropertyType()));
@@ -3572,7 +3572,7 @@
 void JSObject::LookupRealNamedProperty(Handle<Name> name,
                                        LookupResult* result) {
   DisallowHeapAllocation no_gc;
-  LocalLookupRealNamedProperty(name, result);
+  LookupOwnRealNamedProperty(name, result);
   if (result->IsFound()) return;
 
   LookupRealNamedPropertyInPrototypes(name, result);
@@ -3590,7 +3590,7 @@
     if (pt->IsJSProxy()) {
       return result->HandlerResult(JSProxy::cast(pt));
     }
-    JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
+    JSObject::cast(pt)->LookupOwnRealNamedProperty(name, result);
     ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
     if (result->IsFound()) return;
   }
@@ -4153,10 +4153,10 @@
 }
 
 
-static void ConvertAndSetLocalProperty(LookupResult* lookup,
-                                       Handle<Name> name,
-                                       Handle<Object> value,
-                                       PropertyAttributes attributes) {
+static void ConvertAndSetOwnProperty(LookupResult* lookup,
+                                     Handle<Name> name,
+                                     Handle<Object> value,
+                                     PropertyAttributes attributes) {
   Handle<JSObject> object(lookup->holder());
   if (object->TooManyFastProperties()) {
     JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
@@ -4191,7 +4191,7 @@
     if (value->IsUninitialized()) return;
     SetPropertyToField(lookup, value);
   } else {
-    ConvertAndSetLocalProperty(lookup, name, value, attributes);
+    ConvertAndSetOwnProperty(lookup, name, value, attributes);
   }
 }
 
@@ -4314,7 +4314,7 @@
       EnqueueChangeRecord(object, "add", name, old_value);
     } else {
       LookupResult new_lookup(isolate);
-      object->LocalLookup(name, &new_lookup, true);
+      object->LookupOwn(name, &new_lookup, true);
       if (new_lookup.IsDataProperty()) {
         Handle<Object> new_value =
             Object::GetPropertyOrElement(object, name).ToHandleChecked();
@@ -4329,7 +4329,7 @@
 }
 
 
-// Set a real local property, even if it is READ_ONLY.  If the property is not
+// Set a real own property, even if it is READ_ONLY.  If the property is not
 // present, add it with attributes NONE.  This code is an exact clone of
 // SetProperty, with the check for IsReadOnly and the check for a
 // callback setter removed.  The two lines looking up the LookupResult
@@ -4338,7 +4338,7 @@
 // Note that this method cannot be used to set the prototype of a function
 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
 // doesn't handle function prototypes correctly.
-MaybeHandle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
+MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
     Handle<JSObject> object,
     Handle<Name> name,
     Handle<Object> value,
@@ -4354,7 +4354,7 @@
   AssertNoContextChange ncc(isolate);
 
   LookupResult lookup(isolate);
-  object->LocalLookup(name, &lookup, true);
+  object->LookupOwn(name, &lookup, true);
   if (!lookup.IsFound()) {
     object->map()->LookupTransition(*object, *name, &lookup);
   }
@@ -4371,13 +4371,13 @@
     Handle<Object> proto(object->GetPrototype(), isolate);
     if (proto->IsNull()) return value;
     ASSERT(proto->IsJSGlobalObject());
-    return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
+    return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
         name, value, attributes, value_type, mode, extensibility_check);
   }
 
   if (lookup.IsInterceptor() ||
       (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) {
-    object->LocalLookupRealNamedProperty(name, &lookup);
+    object->LookupOwnRealNamedProperty(name, &lookup);
   }
 
   // Check for accessor in prototype chain removed here in clone.
@@ -4425,7 +4425,7 @@
         }
         break;
       case CALLBACKS:
-        ConvertAndSetLocalProperty(&lookup, name, value, attributes);
+        ConvertAndSetOwnProperty(&lookup, name, value, attributes);
         break;
       case NONEXISTENT:
       case HANDLER:
@@ -4441,7 +4441,7 @@
       EnqueueChangeRecord(object, "reconfigure", name, old_value);
     } else {
       LookupResult new_lookup(isolate);
-      object->LocalLookup(name, &new_lookup, true);
+      object->LookupOwn(name, &new_lookup, true);
       bool value_changed = false;
       if (new_lookup.IsDataProperty()) {
         Handle<Object> new_value =
@@ -4466,10 +4466,10 @@
     Handle<JSObject> receiver,
     Handle<Name> name,
     bool continue_search) {
-  // Check local property, ignore interceptor.
+  // Check own property, ignore interceptor.
   Isolate* isolate = object->GetIsolate();
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(name, &result);
+  object->LookupOwnRealNamedProperty(name, &result);
   if (result.IsFound()) return result.GetAttributes();
 
   if (continue_search) {
@@ -4583,16 +4583,16 @@
 }
 
 
-PropertyAttributes JSReceiver::GetLocalPropertyAttribute(
+PropertyAttributes JSReceiver::GetOwnPropertyAttribute(
     Handle<JSReceiver> object, Handle<Name> name) {
   // Check whether the name is an array index.
   uint32_t index = 0;
   if (object->IsJSObject() && name->AsArrayIndex(&index)) {
-    return GetLocalElementAttribute(object, index);
+    return GetOwnElementAttribute(object, index);
   }
   // Named property.
   LookupResult lookup(object->GetIsolate());
-  object->LocalLookup(name, &lookup, true);
+  object->LookupOwn(name, &lookup, true);
   return GetPropertyAttributeForResult(object, object, &lookup, name, false);
 }
 
@@ -5299,7 +5299,7 @@
   } else {
     Isolate* isolate = GetIsolate();
     LookupResult result(isolate);
-    LocalLookupRealNamedProperty(isolate->factory()->hidden_string(), &result);
+    LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result);
     if (result.IsFound()) {
       ASSERT(result.IsNormal());
       ASSERT(result.holder() == this);
@@ -5331,7 +5331,7 @@
                                      inline_value);
   }
 
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       object,
       isolate->factory()->hidden_string(),
       hashtable,
@@ -5369,13 +5369,13 @@
     }
   }
 
-  SetLocalPropertyIgnoreAttributes(object,
-                                   isolate->factory()->hidden_string(),
-                                   value,
-                                   DONT_ENUM,
-                                   OPTIMAL_REPRESENTATION,
-                                   ALLOW_AS_CONSTANT,
-                                   OMIT_EXTENSIBILITY_CHECK).Assert();
+  SetOwnPropertyIgnoreAttributes(object,
+                                 isolate->factory()->hidden_string(),
+                                 value,
+                                 DONT_ENUM,
+                                 OPTIMAL_REPRESENTATION,
+                                 ALLOW_AS_CONSTANT,
+                                 OMIT_EXTENSIBILITY_CHECK).Assert();
   return object;
 }
 
@@ -5383,10 +5383,10 @@
 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
                                                        Handle<Name> name,
                                                        DeleteMode mode) {
-  // Check local property, ignore interceptor.
+  // Check own property, ignore interceptor.
   Isolate* isolate = object->GetIsolate();
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(name, &result);
+  object->LookupOwnRealNamedProperty(name, &result);
   if (!result.IsFound()) return isolate->factory()->true_value();
 
   // Normalize object if needed.
@@ -5499,9 +5499,9 @@
   Handle<Object> old_value;
   bool should_enqueue_change_record = false;
   if (object->map()->is_observed()) {
-    should_enqueue_change_record = HasLocalElement(object, index);
+    should_enqueue_change_record = HasOwnElement(object, index);
     if (should_enqueue_change_record) {
-      if (!GetLocalElementAccessorPair(object, index).is_null()) {
+      if (!GetOwnElementAccessorPair(object, index).is_null()) {
         old_value = Handle<Object>::cast(factory->the_hole_value());
       } else {
         old_value = Object::GetElement(
@@ -5520,7 +5520,7 @@
   Handle<Object> result;
   ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
 
-  if (should_enqueue_change_record && !HasLocalElement(object, index)) {
+  if (should_enqueue_change_record && !HasOwnElement(object, index)) {
     Handle<String> name = factory->Uint32ToString(index);
     EnqueueChangeRecord(object, "delete", name, old_value);
   }
@@ -5558,7 +5558,7 @@
   }
 
   LookupResult lookup(isolate);
-  object->LocalLookup(name, &lookup, true);
+  object->LookupOwn(name, &lookup, true);
   if (!lookup.IsFound()) return isolate->factory()->true_value();
   // Ignore attributes if forcing a deletion.
   if (lookup.IsDontDelete() && mode != FORCE_DELETION) {
@@ -5599,7 +5599,7 @@
     result = DeleteNormalizedProperty(object, name, mode);
   }
 
-  if (is_observed && !HasLocalProperty(object, name)) {
+  if (is_observed && !HasOwnProperty(object, name)) {
     EnqueueChangeRecord(object, "delete", name, old_value);
   }
 
@@ -6053,7 +6053,7 @@
   if (!shallow) {
     HandleScope scope(isolate);
 
-    // Deep copy local properties.
+    // Deep copy own properties.
     if (copy->HasFastProperties()) {
       Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
       int limit = copy->map()->NumberOfOwnDescriptors();
@@ -6077,13 +6077,13 @@
       }
     } else {
       Handle<FixedArray> names =
-          isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
-      copy->GetLocalPropertyNames(*names, 0);
+          isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties());
+      copy->GetOwnPropertyNames(*names, 0);
       for (int i = 0; i < names->length(); i++) {
         ASSERT(names->get(i)->IsString());
         Handle<String> key_string(String::cast(names->get(i)));
         PropertyAttributes attributes =
-            JSReceiver::GetLocalPropertyAttribute(copy, key_string);
+            JSReceiver::GetOwnPropertyAttribute(copy, key_string);
         // Only deep copy fields from the object literal expression.
         // In particular, don't try to copy the length attribute of
         // an array.
@@ -6105,7 +6105,7 @@
       }
     }
 
-    // Deep copy local elements.
+    // Deep copy own elements.
     // Pixel elements cannot be created using an object literal.
     ASSERT(!copy->HasExternalArrayElements());
     switch (kind) {
@@ -6317,7 +6317,7 @@
 }
 
 
-void JSReceiver::LocalLookup(
+void JSReceiver::LookupOwn(
     Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) {
   DisallowHeapAllocation no_gc;
   ASSERT(name->IsName());
@@ -6326,7 +6326,7 @@
     Object* proto = GetPrototype();
     if (proto->IsNull()) return result->NotFound();
     ASSERT(proto->IsJSGlobalObject());
-    return JSReceiver::cast(proto)->LocalLookup(
+    return JSReceiver::cast(proto)->LookupOwn(
         name, result, search_hidden_prototypes);
   }
 
@@ -6350,14 +6350,14 @@
     return;
   }
 
-  js_object->LocalLookupRealNamedProperty(name, result);
+  js_object->LookupOwnRealNamedProperty(name, result);
   if (result->IsFound() || !search_hidden_prototypes) return;
 
   Object* proto = js_object->GetPrototype();
   if (!proto->IsJSReceiver()) return;
   JSReceiver* receiver = JSReceiver::cast(proto);
   if (receiver->map()->is_hidden_prototype()) {
-    receiver->LocalLookup(name, result, search_hidden_prototypes);
+    receiver->LookupOwn(name, result, search_hidden_prototypes);
   }
 }
 
@@ -6369,7 +6369,7 @@
   for (Object* current = this;
        current != *null_value;
        current = JSObject::cast(current)->GetPrototype()) {
-    JSReceiver::cast(current)->LocalLookup(name, result, false);
+    JSReceiver::cast(current)->LookupOwn(name, result, false);
     if (result->IsFound()) return;
   }
   result->NotFound();
@@ -6383,7 +6383,7 @@
   for (Object* current = this;
        current != *null_value && current->IsJSObject();
        current = JSObject::cast(current)->GetPrototype()) {
-    JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
+    JSObject::cast(current)->LookupOwnRealNamedProperty(name, result);
     if (result->IsPropertyCallbacks()) return;
   }
   result->NotFound();
@@ -6623,9 +6623,9 @@
       ASSERT(ContainsOnlyValidKeys(content));
     }
 
-    // If we only want local properties we bail out after the first
+    // If we only want own properties we bail out after the first
     // iteration.
-    if (type == LOCAL_ONLY) break;
+    if (type == OWN_ONLY) break;
   }
   return content;
 }
@@ -6730,7 +6730,7 @@
                                                      Handle<Name> name) {
   Isolate* isolate = object->GetIsolate();
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(name, &result);
+  object->LookupOwnRealNamedProperty(name, &result);
   if (result.IsPropertyCallbacks()) {
     // Note that the result can actually have IsDontDelete() == true when we
     // e.g. have to fall back to the slow case while adding a setter after
@@ -6937,14 +6937,14 @@
   bool preexists = false;
   if (is_observed) {
     if (is_element) {
-      preexists = HasLocalElement(object, index);
-      if (preexists && GetLocalElementAccessorPair(object, index).is_null()) {
+      preexists = HasOwnElement(object, index);
+      if (preexists && GetOwnElementAccessorPair(object, index).is_null()) {
         old_value =
             Object::GetElement(isolate, object, index).ToHandleChecked();
       }
     } else {
       LookupResult lookup(isolate);
-      object->LocalLookup(name, &lookup, true);
+      object->LookupOwn(name, &lookup, true);
       preexists = lookup.IsProperty();
       if (preexists && lookup.IsDataProperty()) {
         old_value =
@@ -7005,7 +7005,7 @@
   ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
   Isolate* isolate = object->GetIsolate();
   LookupResult result(isolate);
-  object->LocalLookup(name, &result);
+  object->LookupOwn(name, &result);
 
   if (result.IsFound() && !result.IsPropertyCallbacks()) {
     return false;
@@ -7140,7 +7140,7 @@
   } else {
     // Lookup the name.
     LookupResult result(isolate);
-    object->LocalLookup(name, &result, true);
+    object->LookupOwn(name, &result, true);
     // ES5 forbids turning a property into an accessor if it's not
     // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
     if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
@@ -7196,7 +7196,7 @@
          !obj->IsNull();
          obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
       LookupResult result(isolate);
-      JSReceiver::cast(*obj)->LocalLookup(name, &result);
+      JSReceiver::cast(*obj)->LookupOwn(name, &result);
       if (result.IsFound()) {
         if (result.IsReadOnly()) return isolate->factory()->undefined_value();
         if (result.IsPropertyCallbacks()) {
@@ -8826,7 +8826,7 @@
 }
 
 
-// Archive statics that are thread local.
+// Archive statics that are thread-local.
 char* Relocatable::ArchiveState(Isolate* isolate, char* to) {
   *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
   isolate->set_relocatable_top(NULL);
@@ -8834,7 +8834,7 @@
 }
 
 
-// Restore statics that are thread local.
+// Restore statics that are thread-local.
 char* Relocatable::RestoreState(Isolate* isolate, char* from) {
   isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
   return from + ArchiveSpacePerThread();
@@ -10706,9 +10706,7 @@
   if (code()->kind() == Code::FUNCTION) {
     code()->set_optimizable(false);
   }
-  PROFILE(GetIsolate(),
-      LogExistingFunction(Handle<SharedFunctionInfo>(this),
-                          Handle<Code>(code())));
+  PROFILE(GetIsolate(), CodeDisableOptEvent(code(), this));
   if (FLAG_trace_opt) {
     PrintF("[disabled optimization for ");
     ShortPrint();
@@ -10739,7 +10737,7 @@
 
   // No tracking during the snapshot construction phase.
   Isolate* isolate = GetIsolate();
-  if (Serializer::enabled(isolate)) return;
+  if (isolate->serializer_enabled()) return;
 
   if (map->unused_property_fields() == 0) return;
 
@@ -11247,13 +11245,30 @@
 void SharedFunctionInfo::ClearTypeFeedbackInfo() {
   FixedArray* vector = feedback_vector();
   Heap* heap = GetHeap();
-  for (int i = 0; i < vector->length(); i++) {
+  int length = vector->length();
+
+  for (int i = 0; i < length; i++) {
     Object* obj = vector->get(i);
-    if (!obj->IsAllocationSite()) {
-      vector->set(
-          i,
-          TypeFeedbackInfo::RawUninitializedSentinel(heap),
-          SKIP_WRITE_BARRIER);
+    if (obj->IsHeapObject()) {
+      InstanceType instance_type =
+          HeapObject::cast(obj)->map()->instance_type();
+      switch (instance_type) {
+        case ALLOCATION_SITE_TYPE:
+          // AllocationSites are not cleared because they do not store
+          // information that leaks.
+          break;
+        case JS_FUNCTION_TYPE:
+          // No need to clear the native context array function.
+          if (obj == JSFunction::cast(obj)->context()->native_context()->
+              get(Context::ARRAY_FUNCTION_INDEX)) {
+            break;
+          }
+          // Fall through...
+
+        default:
+          vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap),
+                      SKIP_WRITE_BARRIER);
+      }
     }
   }
 }
@@ -11918,11 +11933,11 @@
                         List<Handle<Object> >* old_values,
                         List<uint32_t>* indices) {
   PropertyAttributes attributes =
-      JSReceiver::GetLocalElementAttribute(object, index);
+      JSReceiver::GetOwnElementAttribute(object, index);
   ASSERT(attributes != ABSENT);
   if (attributes == DONT_DELETE) return false;
   Handle<Object> value;
-  if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) {
+  if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) {
     value = Handle<Object>::cast(isolate->factory()->the_hole_value());
   } else {
     value = Object::GetElement(isolate, object, index).ToHandleChecked();
@@ -11998,7 +12013,7 @@
   CHECK(new_length_handle->ToArrayIndex(&new_length));
 
   static const PropertyAttributes kNoAttrFilter = NONE;
-  int num_elements = array->NumberOfLocalElements(kNoAttrFilter);
+  int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
   if (num_elements > 0) {
     if (old_length == static_cast<uint32_t>(num_elements)) {
       // Simple case for arrays without holes.
@@ -12010,7 +12025,7 @@
       // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
       // the to-be-removed indices twice.
       Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
-      array->GetLocalElementKeys(*keys, kNoAttrFilter);
+      array->GetOwnElementKeys(*keys, kNoAttrFilter);
       while (num_elements-- > 0) {
         uint32_t index = NumberToUint32(keys->get(num_elements));
         if (index < new_length) break;
@@ -12503,17 +12518,17 @@
 }
 
 
-MaybeHandle<AccessorPair> JSObject::GetLocalPropertyAccessorPair(
+MaybeHandle<AccessorPair> JSObject::GetOwnPropertyAccessorPair(
     Handle<JSObject> object,
     Handle<Name> name) {
   uint32_t index = 0;
   if (name->AsArrayIndex(&index)) {
-    return GetLocalElementAccessorPair(object, index);
+    return GetOwnElementAccessorPair(object, index);
   }
 
   Isolate* isolate = object->GetIsolate();
   LookupResult lookup(isolate);
-  object->LocalLookupRealNamedProperty(name, &lookup);
+  object->LookupOwnRealNamedProperty(name, &lookup);
 
   if (lookup.IsPropertyCallbacks() &&
       lookup.GetCallbackObject()->IsAccessorPair()) {
@@ -12523,14 +12538,14 @@
 }
 
 
-MaybeHandle<AccessorPair> JSObject::GetLocalElementAccessorPair(
+MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair(
     Handle<JSObject> object,
     uint32_t index) {
   if (object->IsJSGlobalProxy()) {
     Handle<Object> proto(object->GetPrototype(), object->GetIsolate());
     if (proto->IsNull()) return MaybeHandle<AccessorPair>();
     ASSERT(proto->IsJSGlobalObject());
-    return GetLocalElementAccessorPair(Handle<JSObject>::cast(proto), index);
+    return GetOwnElementAccessorPair(Handle<JSObject>::cast(proto), index);
   }
 
   // Check for lookup interceptor.
@@ -13168,13 +13183,13 @@
   }
 
   PropertyAttributes old_attributes =
-      JSReceiver::GetLocalElementAttribute(object, index);
+      JSReceiver::GetOwnElementAttribute(object, index);
   Handle<Object> old_value = isolate->factory()->the_hole_value();
   Handle<Object> old_length_handle;
   Handle<Object> new_length_handle;
 
   if (old_attributes != ABSENT) {
-    if (GetLocalElementAccessorPair(object, index).is_null()) {
+    if (GetOwnElementAccessorPair(object, index).is_null()) {
       old_value = Object::GetElement(isolate, object, index).ToHandleChecked();
     }
   } else if (object->IsJSArray()) {
@@ -13197,7 +13212,7 @@
       Object);
 
   Handle<String> name = isolate->factory()->Uint32ToString(index);
-  PropertyAttributes new_attributes = GetLocalElementAttribute(object, index);
+  PropertyAttributes new_attributes = GetOwnElementAttribute(object, index);
   if (old_attributes == ABSENT) {
     if (object->IsJSArray() &&
         !old_length_handle->SameValue(
@@ -13260,6 +13275,14 @@
       CheckArrayAbuse(object, "elements write", index, true);
     }
   }
+  if (object->IsJSArray() && JSArray::WouldChangeReadOnlyLength(
+      Handle<JSArray>::cast(object), index)) {
+    if (strict_mode == SLOPPY) {
+      return value;
+    } else {
+      return JSArray::ReadOnlyLengthError(Handle<JSArray>::cast(object));
+    }
+  }
   switch (object->GetElementsKind()) {
     case FAST_SMI_ELEMENTS:
     case FAST_ELEMENTS:
@@ -13545,6 +13568,41 @@
 }
 
 
+bool JSArray::IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map) {
+    Isolate* isolate = jsarray_map->GetIsolate();
+    ASSERT(!jsarray_map->is_dictionary_map());
+    LookupResult lookup(isolate);
+    Handle<Name> length_string = isolate->factory()->length_string();
+    jsarray_map->LookupDescriptor(NULL, *length_string, &lookup);
+    return lookup.IsReadOnly();
+}
+
+
+bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
+                                        uint32_t index) {
+  uint32_t length = 0;
+  CHECK(array->length()->ToArrayIndex(&length));
+  if (length <= index) {
+    Isolate* isolate = array->GetIsolate();
+    LookupResult lookup(isolate);
+    Handle<Name> length_string = isolate->factory()->length_string();
+    array->LookupOwnRealNamedProperty(length_string, &lookup);
+    return lookup.IsReadOnly();
+  }
+  return false;
+}
+
+
+MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
+  Isolate* isolate = array->GetIsolate();
+  Handle<Name> length = isolate->factory()->length_string();
+  Handle<Object> args[2] = { length, array };
+  Handle<Object> error = isolate->factory()->NewTypeError(
+      "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
+  return isolate->Throw<Object>(error);
+}
+
+
 MaybeHandle<Object> JSObject::GetElementWithInterceptor(
     Handle<JSObject> object,
     Handle<Object> receiver,
@@ -13834,10 +13892,10 @@
     Handle<Object> receiver,
     Handle<Name> name,
     PropertyAttributes* attributes) {
-  // Check local property in holder, ignore interceptor.
+  // Check own property in holder, ignore interceptor.
   Isolate* isolate = object->GetIsolate();
   LookupResult lookup(isolate);
-  object->LocalLookupRealNamedProperty(name, &lookup);
+  object->LookupOwnRealNamedProperty(name, &lookup);
   if (lookup.IsFound()) {
     return GetProperty(object, receiver, &lookup, name, attributes);
   } else {
@@ -13951,7 +14009,7 @@
   }
 
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(key, &result);
+  object->LookupOwnRealNamedProperty(key, &result);
   return result.IsFound() && !result.IsInterceptor();
 }
 
@@ -13995,12 +14053,12 @@
   }
 
   LookupResult result(isolate);
-  object->LocalLookupRealNamedProperty(key, &result);
+  object->LookupOwnRealNamedProperty(key, &result);
   return result.IsPropertyCallbacks();
 }
 
 
-int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
+int JSObject::NumberOfOwnProperties(PropertyAttributes filter) {
   if (HasFastProperties()) {
     Map* map = this->map();
     if (filter == NONE) return map->NumberOfOwnDescriptors();
@@ -14127,12 +14185,12 @@
 }
 
 
-// Fill in the names of local properties into the supplied storage. The main
+// Fill in the names of own properties into the supplied storage. The main
 // purpose of this function is to provide reflection information for the object
 // mirrors.
-void JSObject::GetLocalPropertyNames(
+void JSObject::GetOwnPropertyNames(
     FixedArray* storage, int index, PropertyAttributes filter) {
-  ASSERT(storage->length() >= (NumberOfLocalProperties(filter) - index));
+  ASSERT(storage->length() >= (NumberOfOwnProperties(filter) - index));
   if (HasFastProperties()) {
     int real_size = map()->NumberOfOwnDescriptors();
     DescriptorArray* descs = map()->instance_descriptors();
@@ -14151,8 +14209,8 @@
 }
 
 
-int JSObject::NumberOfLocalElements(PropertyAttributes filter) {
-  return GetLocalElementKeys(NULL, filter);
+int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
+  return GetOwnElementKeys(NULL, filter);
 }
 
 
@@ -14166,12 +14224,12 @@
     if (length == 0) return 0;
   }
   // Compute the number of enumerable elements.
-  return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM));
+  return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM));
 }
 
 
-int JSObject::GetLocalElementKeys(FixedArray* storage,
-                                  PropertyAttributes filter) {
+int JSObject::GetOwnElementKeys(FixedArray* storage,
+                                PropertyAttributes filter) {
   int counter = 0;
   switch (GetElementsKind()) {
     case FAST_SMI_ELEMENTS:
@@ -14196,7 +14254,7 @@
     case FAST_HOLEY_DOUBLE_ELEMENTS: {
       int length = IsJSArray() ?
           Smi::cast(JSArray::cast(this)->length())->value() :
-          FixedDoubleArray::cast(elements())->length();
+          FixedArrayBase::cast(elements())->length();
       for (int i = 0; i < length; i++) {
         if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
           if (storage != NULL) {
@@ -14297,8 +14355,7 @@
 
 
 int JSObject::GetEnumElementKeys(FixedArray* storage) {
-  return GetLocalElementKeys(storage,
-                             static_cast<PropertyAttributes>(DONT_ENUM));
+  return GetOwnElementKeys(storage, static_cast<PropertyAttributes>(DONT_ENUM));
 }
 
 
@@ -16991,7 +17048,7 @@
       // Since the stamp is not NaN, the value is also not NaN.
       int64_t local_time_ms =
           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
-      SetLocalFields(local_time_ms, date_cache);
+      SetCachedFields(local_time_ms, date_cache);
     }
     switch (index) {
       case kYear: return year();
@@ -17084,7 +17141,7 @@
 }
 
 
-void JSDate::SetLocalFields(int64_t local_time_ms, DateCache* date_cache) {
+void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   int days = DateCache::DaysFromTime(local_time_ms);
   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
   int year, month, day;
diff --git a/src/objects.h b/src/objects.h
index 944efb9..47fea39 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1922,9 +1922,9 @@
 
   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
-  static inline bool HasLocalProperty(Handle<JSReceiver>, Handle<Name> name);
+  static inline bool HasOwnProperty(Handle<JSReceiver>, Handle<Name> name);
   static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
-  static inline bool HasLocalElement(Handle<JSReceiver> object, uint32_t index);
+  static inline bool HasOwnElement(Handle<JSReceiver> object, uint32_t index);
 
   // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
   MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
@@ -1953,14 +1953,14 @@
       Handle<JSReceiver> object,
       Handle<JSReceiver> receiver,
       Handle<Name> name);
-  static PropertyAttributes GetLocalPropertyAttribute(
+  static PropertyAttributes GetOwnPropertyAttribute(
       Handle<JSReceiver> object,
       Handle<Name> name);
 
   static inline PropertyAttributes GetElementAttribute(
       Handle<JSReceiver> object,
       uint32_t index);
-  static inline PropertyAttributes GetLocalElementAttribute(
+  static inline PropertyAttributes GetOwnElementAttribute(
       Handle<JSReceiver> object,
       uint32_t index);
 
@@ -1981,11 +1981,11 @@
 
   // Lookup a property.  If found, the result is valid and has
   // detailed information.
-  void LocalLookup(Handle<Name> name, LookupResult* result,
-                   bool search_hidden_prototypes = false);
+  void LookupOwn(Handle<Name> name, LookupResult* result,
+                 bool search_hidden_prototypes = false);
   void Lookup(Handle<Name> name, LookupResult* result);
 
-  enum KeyCollectionType { LOCAL_ONLY, INCLUDE_PROTOS };
+  enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
 
   // Computes the enumerable keys for a JSObject. Used for implementing
   // "for (n in object) { }".
@@ -2157,7 +2157,7 @@
       StrictMode strict_mode,
       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
 
-  MUST_USE_RESULT static MaybeHandle<Object> SetLocalPropertyIgnoreAttributes(
+  MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
       Handle<JSObject> object,
       Handle<Name> key,
       Handle<Object> value,
@@ -2273,8 +2273,8 @@
 
   // Accessors for hidden properties object.
   //
-  // Hidden properties are not local properties of the object itself.
-  // Instead they are stored in an auxiliary structure kept as a local
+  // Hidden properties are not own properties of the object itself.
+  // Instead they are stored in an auxiliary structure kept as an own
   // property with a special name Heap::hidden_string(). But if the
   // receiver is a JSGlobalProxy then the auxiliary object is a property
   // of its prototype, and if it's a detached proxy, then you can't have
@@ -2344,10 +2344,10 @@
   }
 
   // These methods do not perform access checks!
-  MUST_USE_RESULT static MaybeHandle<AccessorPair> GetLocalPropertyAccessorPair(
+  MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnPropertyAccessorPair(
       Handle<JSObject> object,
       Handle<Name> name);
-  MUST_USE_RESULT static MaybeHandle<AccessorPair> GetLocalElementAccessorPair(
+  MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnElementAccessorPair(
       Handle<JSObject> object,
       uint32_t index);
 
@@ -2432,7 +2432,7 @@
   inline void SetInternalField(int index, Smi* value);
 
   // The following lookup functions skip interceptors.
-  void LocalLookupRealNamedProperty(Handle<Name> name, LookupResult* result);
+  void LookupOwnRealNamedProperty(Handle<Name> name, LookupResult* result);
   void LookupRealNamedProperty(Handle<Name> name, LookupResult* result);
   void LookupRealNamedPropertyInPrototypes(Handle<Name> name,
                                            LookupResult* result);
@@ -2440,20 +2440,20 @@
 
   // Returns the number of properties on this object filtering out properties
   // with the specified attributes (ignoring interceptors).
-  int NumberOfLocalProperties(PropertyAttributes filter = NONE);
+  int NumberOfOwnProperties(PropertyAttributes filter = NONE);
   // Fill in details for properties into storage starting at the specified
   // index.
-  void GetLocalPropertyNames(
+  void GetOwnPropertyNames(
       FixedArray* storage, int index, PropertyAttributes filter = NONE);
 
   // Returns the number of properties on this object filtering out properties
   // with the specified attributes (ignoring interceptors).
-  int NumberOfLocalElements(PropertyAttributes filter);
+  int NumberOfOwnElements(PropertyAttributes filter);
   // Returns the number of enumerable elements (ignoring interceptors).
   int NumberOfEnumElements();
   // Returns the number of elements on this object filtering out elements
   // with the specified attributes (ignoring interceptors).
-  int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter);
+  int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter);
   // Count and fill in the enumerable elements into storage.
   // (storage->length() == NumberOfEnumElements()).
   // If storage is NULL, will count the elements without adding
@@ -2468,7 +2468,7 @@
   static void TransitionElementsKind(Handle<JSObject> object,
                                      ElementsKind to_kind);
 
-  // TODO(mstarzinger): Both public because of ConvertAnsSetLocalProperty().
+  // TODO(mstarzinger): Both public because of ConvertAndSetOwnProperty().
   static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
   static void GeneralizeFieldRepresentation(Handle<JSObject> object,
                                             int modify_index,
@@ -7495,6 +7495,8 @@
   // cannot be resumed.
   inline int continuation();
   inline void set_continuation(int continuation);
+  inline bool is_closed();
+  inline bool is_executing();
   inline bool is_suspended();
 
   // [operand_stack]: Saved operand stack.
@@ -7920,7 +7922,7 @@
   // [sec]: caches seconds. Either undefined, smi, or NaN.
   DECL_ACCESSORS(sec, Object)
   // [cache stamp]: sample of the date cache stamp at the
-  // moment when local fields were cached.
+  // moment when chached fields were cached.
   DECL_ACCESSORS(cache_stamp, Object)
 
   // Casting.
@@ -7984,7 +7986,7 @@
   Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
 
   // Computes and caches the cacheable fields of the date.
-  inline void SetLocalFields(int64_t local_time_ms, DateCache* date_cache);
+  inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
 
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
@@ -10336,6 +10338,10 @@
                                            uint32_t index,
                                            Handle<Object> value);
 
+  static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
+  static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
+  static MaybeHandle<Object> ReadOnlyLengthError(Handle<JSArray> array);
+
   // Initialize the array with the given capacity. The function may
   // fail due to out-of-memory situations, but only if the requested
   // capacity is non-zero.
@@ -10569,7 +10575,7 @@
 // the request is ignored.
 //
 // If the accessor in the prototype has the READ_ONLY property attribute, then
-// a new value is added to the local object when the property is set.
+// a new value is added to the derived object when the property is set.
 // This shadows the accessor in the prototype.
 class ExecutableAccessorInfo: public AccessorInfo {
  public:
diff --git a/src/parser.cc b/src/parser.cc
index 5efcba6..572b0f4 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1267,7 +1267,7 @@
   Interface* interface = scope->interface();
   for (Interface::Iterator it = interface->iterator();
        !it.done(); it.Advance()) {
-    if (scope->LocalLookup(it.name()) == NULL) {
+    if (scope->LookupLocal(it.name()) == NULL) {
       ParserTraits::ReportMessage("module_export_undefined", it.name());
       *ok = false;
       return NULL;
@@ -1679,7 +1679,7 @@
     // global scope.
     var = declaration_scope->is_global_scope()
         ? declaration_scope->Lookup(name)
-        : declaration_scope->LocalLookup(name);
+        : declaration_scope->LookupLocal(name);
     if (var == NULL) {
       // Declare the name.
       var = declaration_scope->DeclareLocal(
diff --git a/src/promise.js b/src/promise.js
index d202f28..f7d6307 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -9,28 +9,18 @@
 // var $Object = global.Object
 // var $WeakMap = global.WeakMap
 
+// For bootstrapper.
 
-var $Promise = function Promise(resolver) {
-  if (resolver === promiseRaw) return;
-  if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
-  if (!IS_SPEC_FUNCTION(resolver))
-    throw MakeTypeError('resolver_not_a_function', [resolver]);
-  var promise = PromiseInit(this);
-  try {
-    %DebugPromiseHandlePrologue(function() { return promise });
-    resolver(function(x) { PromiseResolve(promise, x) },
-             function(r) { PromiseReject(promise, r) });
-  } catch (e) {
-    PromiseReject(promise, e);
-  } finally {
-    %DebugPromiseHandleEpilogue();
-  }
-}
+var IsPromise;
+var PromiseCreate;
+var PromiseResolve;
+var PromiseReject;
+var PromiseChain;
+var PromiseCatch;
 
-
-//-------------------------------------------------------------------
-
-// Core functionality.
+// mirror-debugger.js currently uses builtins.promiseStatus. It would be nice
+// if we could move these property names into the closure below.
+// TODO(jkummerow/rossberg/yangguo): Find a better solution.
 
 // Status values: 0 = pending, +1 = resolved, -1 = rejected
 var promiseStatus = GLOBAL_PRIVATE("Promise#status");
@@ -39,250 +29,274 @@
 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject");
 var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
 
-function IsPromise(x) {
-  return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus);
-}
+(function() {
 
-function PromiseSet(promise, status, value, onResolve, onReject) {
-  SET_PRIVATE(promise, promiseStatus, status);
-  SET_PRIVATE(promise, promiseValue, value);
-  SET_PRIVATE(promise, promiseOnResolve, onResolve);
-  SET_PRIVATE(promise, promiseOnReject, onReject);
-  return promise;
-}
-
-function PromiseInit(promise) {
-  return PromiseSet(promise, 0, UNDEFINED, new InternalArray, new InternalArray)
-}
-
-function PromiseDone(promise, status, value, promiseQueue) {
-  if (GET_PRIVATE(promise, promiseStatus) === 0) {
-    PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue));
-    PromiseSet(promise, status, value);
-  }
-}
-
-function PromiseResolve(promise, x) {
-  PromiseDone(promise, +1, x, promiseOnResolve)
-}
-
-function PromiseReject(promise, r) {
-  PromiseDone(promise, -1, r, promiseOnReject)
-}
-
-
-// For API.
-
-function PromiseNopResolver() {}
-
-function PromiseCreate() {
-  return new $Promise(PromiseNopResolver)
-}
-
-
-// Convenience.
-
-function PromiseDeferred() {
-  if (this === $Promise) {
-    // Optimized case, avoid extra closure.
-    var promise = PromiseInit(new $Promise(promiseRaw));
-    return {
-      promise: promise,
-      resolve: function(x) { PromiseResolve(promise, x) },
-      reject: function(r) { PromiseReject(promise, r) }
-    };
-  } else {
-    var result = {};
-    result.promise = new this(function(resolve, reject) {
-      result.resolve = resolve;
-      result.reject = reject;
-    })
-    return result;
-  }
-}
-
-function PromiseResolved(x) {
-  if (this === $Promise) {
-    // Optimized case, avoid extra closure.
-    return PromiseSet(new $Promise(promiseRaw), +1, x);
-  } else {
-    return new this(function(resolve, reject) { resolve(x) });
-  }
-}
-
-function PromiseRejected(r) {
-  if (this === $Promise) {
-    // Optimized case, avoid extra closure.
-    return PromiseSet(new $Promise(promiseRaw), -1, r);
-  } else {
-    return new this(function(resolve, reject) { reject(r) });
-  }
-}
-
-
-// Simple chaining.
-
-function PromiseIdResolveHandler(x) { return x }
-function PromiseIdRejectHandler(r) { throw r }
-
-function PromiseChain(onResolve, onReject) {  // a.k.a.  flatMap
-  onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
-  onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
-  var deferred = %_CallFunction(this.constructor, PromiseDeferred);
-  switch (GET_PRIVATE(this, promiseStatus)) {
-    case UNDEFINED:
-      throw MakeTypeError('not_a_promise', [this]);
-    case 0:  // Pending
-      GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred);
-      GET_PRIVATE(this, promiseOnReject).push(onReject, deferred);
-      break;
-    case +1:  // Resolved
-      PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onResolve, deferred]);
-      break;
-    case -1:  // Rejected
-      PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onReject, deferred]);
-      break;
-  }
-  return deferred.promise;
-}
-
-function PromiseCatch(onReject) {
-  return this.then(UNDEFINED, onReject);
-}
-
-function PromiseEnqueue(value, tasks) {
-  %EnqueueMicrotask(function() {
-    for (var i = 0; i < tasks.length; i += 2) {
-      PromiseHandle(value, tasks[i], tasks[i + 1])
-    }
-  });
-}
-
-function PromiseHandle(value, handler, deferred) {
-  try {
-    %DebugPromiseHandlePrologue(
-        function() {
-          var queue = GET_PRIVATE(deferred.promise, promiseOnReject);
-          return (queue && queue.length == 0) ? deferred.promise : UNDEFINED;
-        });
-    var result = handler(value);
-    if (result === deferred.promise)
-      throw MakeTypeError('promise_cyclic', [result]);
-    else if (IsPromise(result))
-      %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain);
-    else
-      deferred.resolve(result);
-  } catch (exception) {
+  var $Promise = function Promise(resolver) {
+    if (resolver === promiseRaw) return;
+    if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
+    if (!IS_SPEC_FUNCTION(resolver))
+      throw MakeTypeError('resolver_not_a_function', [resolver]);
+    var promise = PromiseInit(this);
     try {
-      %DebugPromiseHandlePrologue(function() { return deferred.promise });
-      deferred.reject(exception);
-    } catch (e) { } finally {
+      %DebugPromiseHandlePrologue(function() { return promise });
+      resolver(function(x) { PromiseResolve(promise, x) },
+               function(r) { PromiseReject(promise, r) });
+    } catch (e) {
+      PromiseReject(promise, e);
+    } finally {
       %DebugPromiseHandleEpilogue();
     }
-  } finally {
-    %DebugPromiseHandleEpilogue();
   }
-}
 
+  // Core functionality.
 
-// Multi-unwrapped chaining with thenable coercion.
+  function PromiseSet(promise, status, value, onResolve, onReject) {
+    SET_PRIVATE(promise, promiseStatus, status);
+    SET_PRIVATE(promise, promiseValue, value);
+    SET_PRIVATE(promise, promiseOnResolve, onResolve);
+    SET_PRIVATE(promise, promiseOnReject, onReject);
+    return promise;
+  }
 
-function PromiseThen(onResolve, onReject) {
-  onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve : PromiseIdResolveHandler;
-  onReject = IS_SPEC_FUNCTION(onReject) ? onReject : PromiseIdRejectHandler;
-  var that = this;
-  var constructor = this.constructor;
-  return %_CallFunction(
-    this,
-    function(x) {
-      x = PromiseCoerce(constructor, x);
-      return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) :
-             IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x);
-    },
-    onReject,
-    PromiseChain
-  );
-}
+  function PromiseInit(promise) {
+    return PromiseSet(
+        promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+  }
 
-function PromiseCoerce(constructor, x) {
-  if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
-    var then;
-    try {
-      then = x.then;
-    } catch(r) {
-      return %_CallFunction(constructor, r, PromiseRejected);
+  function PromiseDone(promise, status, value, promiseQueue) {
+    if (GET_PRIVATE(promise, promiseStatus) === 0) {
+      PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue));
+      PromiseSet(promise, status, value);
     }
-    if (IS_SPEC_FUNCTION(then)) {
-      var deferred = %_CallFunction(constructor, PromiseDeferred);
+  }
+
+  function PromiseCoerce(constructor, x) {
+    if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
+      var then;
       try {
-        %_CallFunction(x, deferred.resolve, deferred.reject, then);
+        then = x.then;
       } catch(r) {
-        deferred.reject(r);
+        return %_CallFunction(constructor, r, PromiseRejected);
       }
-      return deferred.promise;
+      if (IS_SPEC_FUNCTION(then)) {
+        var deferred = %_CallFunction(constructor, PromiseDeferred);
+        try {
+          %_CallFunction(x, deferred.resolve, deferred.reject, then);
+        } catch(r) {
+          deferred.reject(r);
+        }
+        return deferred.promise;
+      }
+    }
+    return x;
+  }
+
+  function PromiseHandle(value, handler, deferred) {
+    try {
+      %DebugPromiseHandlePrologue(
+          function() {
+            var queue = GET_PRIVATE(deferred.promise, promiseOnReject);
+            return (queue && queue.length == 0) ? deferred.promise : UNDEFINED;
+          });
+      var result = handler(value);
+      if (result === deferred.promise)
+        throw MakeTypeError('promise_cyclic', [result]);
+      else if (IsPromise(result))
+        %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain);
+      else
+        deferred.resolve(result);
+    } catch (exception) {
+      try {
+        %DebugPromiseHandlePrologue(function() { return deferred.promise });
+        deferred.reject(exception);
+      } catch (e) { } finally {
+        %DebugPromiseHandleEpilogue();
+      }
+    } finally {
+      %DebugPromiseHandleEpilogue();
     }
   }
-  return x;
-}
 
+  function PromiseEnqueue(value, tasks) {
+    %EnqueueMicrotask(function() {
+      for (var i = 0; i < tasks.length; i += 2) {
+        PromiseHandle(value, tasks[i], tasks[i + 1])
+      }
+    });
+  }
 
-// Combinators.
+  function PromiseIdResolveHandler(x) { return x }
+  function PromiseIdRejectHandler(r) { throw r }
 
-function PromiseCast(x) {
-  // TODO(rossberg): cannot do better until we support @@create.
-  return IsPromise(x) ? x : new this(function(resolve) { resolve(x) });
-}
+  function PromiseNopResolver() {}
 
-function PromiseAll(values) {
-  var deferred = %_CallFunction(this, PromiseDeferred);
-  var resolutions = [];
-  if (!%_IsArray(values)) {
-    deferred.reject(MakeTypeError('invalid_argument'));
+  // -------------------------------------------------------------------
+  // Define exported functions.
+
+  // For bootstrapper.
+
+  IsPromise = function IsPromise(x) {
+    return IS_SPEC_OBJECT(x) && HAS_PRIVATE(x, promiseStatus);
+  }
+
+  PromiseCreate = function PromiseCreate() {
+    return new $Promise(PromiseNopResolver)
+  }
+
+  PromiseResolve = function PromiseResolve(promise, x) {
+    PromiseDone(promise, +1, x, promiseOnResolve)
+  }
+
+  PromiseReject = function PromiseReject(promise, r) {
+    PromiseDone(promise, -1, r, promiseOnReject)
+  }
+
+  // Convenience.
+
+  function PromiseDeferred() {
+    if (this === $Promise) {
+      // Optimized case, avoid extra closure.
+      var promise = PromiseInit(new $Promise(promiseRaw));
+      return {
+        promise: promise,
+        resolve: function(x) { PromiseResolve(promise, x) },
+        reject: function(r) { PromiseReject(promise, r) }
+      };
+    } else {
+      var result = {};
+      result.promise = new this(function(resolve, reject) {
+        result.resolve = resolve;
+        result.reject = reject;
+      })
+      return result;
+    }
+  }
+
+  function PromiseResolved(x) {
+    if (this === $Promise) {
+      // Optimized case, avoid extra closure.
+      return PromiseSet(new $Promise(promiseRaw), +1, x);
+    } else {
+      return new this(function(resolve, reject) { resolve(x) });
+    }
+  }
+
+  function PromiseRejected(r) {
+    if (this === $Promise) {
+      // Optimized case, avoid extra closure.
+      return PromiseSet(new $Promise(promiseRaw), -1, r);
+    } else {
+      return new this(function(resolve, reject) { reject(r) });
+    }
+  }
+
+  // Simple chaining.
+
+  PromiseChain = function PromiseChain(onResolve, onReject) {  // a.k.a.
+                                                                // flatMap
+    onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
+    onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
+    var deferred = %_CallFunction(this.constructor, PromiseDeferred);
+    switch (GET_PRIVATE(this, promiseStatus)) {
+      case UNDEFINED:
+        throw MakeTypeError('not_a_promise', [this]);
+      case 0:  // Pending
+        GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred);
+        GET_PRIVATE(this, promiseOnReject).push(onReject, deferred);
+        break;
+      case +1:  // Resolved
+        PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onResolve, deferred]);
+        break;
+      case -1:  // Rejected
+        PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onReject, deferred]);
+        break;
+    }
     return deferred.promise;
   }
-  try {
-    var count = values.length;
-    if (count === 0) {
-      deferred.resolve(resolutions);
-    } else {
+
+  PromiseCatch = function PromiseCatch(onReject) {
+    return this.then(UNDEFINED, onReject);
+  }
+
+  // Multi-unwrapped chaining with thenable coercion.
+
+  function PromiseThen(onResolve, onReject) {
+    onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve
+                                            : PromiseIdResolveHandler;
+    onReject = IS_SPEC_FUNCTION(onReject) ? onReject
+                                          : PromiseIdRejectHandler;
+    var that = this;
+    var constructor = this.constructor;
+    return %_CallFunction(
+      this,
+      function(x) {
+        x = PromiseCoerce(constructor, x);
+        return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) :
+               IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x);
+      },
+      onReject,
+      PromiseChain
+    );
+  }
+
+  // Combinators.
+
+  function PromiseCast(x) {
+    // TODO(rossberg): cannot do better until we support @@create.
+    return IsPromise(x) ? x : new this(function(resolve) { resolve(x) });
+  }
+
+  function PromiseAll(values) {
+    var deferred = %_CallFunction(this, PromiseDeferred);
+    var resolutions = [];
+    if (!%_IsArray(values)) {
+      deferred.reject(MakeTypeError('invalid_argument'));
+      return deferred.promise;
+    }
+    try {
+      var count = values.length;
+      if (count === 0) {
+        deferred.resolve(resolutions);
+      } else {
+        for (var i = 0; i < values.length; ++i) {
+          this.resolve(values[i]).then(
+            function(i, x) {
+              resolutions[i] = x;
+              if (--count === 0) deferred.resolve(resolutions);
+            }.bind(UNDEFINED, i),  // TODO(rossberg): use let loop once
+                                    // available
+            function(r) { deferred.reject(r) }
+          );
+        }
+      }
+    } catch (e) {
+      deferred.reject(e)
+    }
+    return deferred.promise;
+  }
+
+  function PromiseOne(values) {
+    var deferred = %_CallFunction(this, PromiseDeferred);
+    if (!%_IsArray(values)) {
+      deferred.reject(MakeTypeError('invalid_argument'));
+      return deferred.promise;
+    }
+    try {
       for (var i = 0; i < values.length; ++i) {
         this.resolve(values[i]).then(
-          function(i, x) {
-            resolutions[i] = x;
-            if (--count === 0) deferred.resolve(resolutions);
-          }.bind(UNDEFINED, i),  // TODO(rossberg): use let loop once available
+          function(x) { deferred.resolve(x) },
           function(r) { deferred.reject(r) }
         );
       }
+    } catch (e) {
+      deferred.reject(e)
     }
-  } catch (e) {
-    deferred.reject(e)
-  }
-  return deferred.promise;
-}
-
-function PromiseOne(values) {
-  var deferred = %_CallFunction(this, PromiseDeferred);
-  if (!%_IsArray(values)) {
-    deferred.reject(MakeTypeError('invalid_argument'));
     return deferred.promise;
   }
-  try {
-    for (var i = 0; i < values.length; ++i) {
-      this.resolve(values[i]).then(
-        function(x) { deferred.resolve(x) },
-        function(r) { deferred.reject(r) }
-      );
-    }
-  } catch (e) {
-    deferred.reject(e)
-  }
-  return deferred.promise;
-}
 
-//-------------------------------------------------------------------
+  // -------------------------------------------------------------------
+  // Install exported functions.
 
-function SetUpPromise() {
   %CheckIsBootstrapping();
   %SetProperty(global, 'Promise', $Promise, DONT_ENUM);
   InstallFunctions($Promise, DONT_ENUM, [
@@ -298,6 +312,5 @@
     "then", PromiseThen,
     "catch", PromiseCatch
   ]);
-}
 
-SetUpPromise();
+})();
diff --git a/src/runtime.cc b/src/runtime.cc
index 29a3efe..39c3d29 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -277,7 +277,7 @@
       } else {
         Handle<String> name(String::cast(*key));
         ASSERT(!name->AsArrayIndex(&element_index));
-        maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
+        maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
             boilerplate, name, value, NONE,
             Object::OPTIMAL_REPRESENTATION, mode);
       }
@@ -293,7 +293,7 @@
       Vector<char> buffer(arr, ARRAY_SIZE(arr));
       const char* str = DoubleToCString(num, buffer);
       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
-      maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
+      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
           boilerplate, name, value, NONE,
           Object::OPTIMAL_REPRESENTATION, mode);
     }
@@ -1946,7 +1946,7 @@
 
   Isolate* isolate = obj->GetIsolate();
   LookupResult lookup(isolate);
-  obj->LocalLookup(name, &lookup, true);
+  obj->LookupOwn(name, &lookup, true);
 
   if (!lookup.IsProperty()) return ACCESS_ABSENT;
   Handle<JSObject> holder(lookup.holder(), isolate);
@@ -2013,7 +2013,7 @@
     case ACCESS_ABSENT: return factory->undefined_value();
   }
 
-  PropertyAttributes attrs = JSReceiver::GetLocalPropertyAttribute(obj, name);
+  PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttribute(obj, name);
   if (attrs == ABSENT) {
     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
     return factory->undefined_value();
@@ -2021,7 +2021,7 @@
   ASSERT(!isolate->has_scheduled_exception());
   Handle<AccessorPair> accessors;
   bool has_accessors =
-      JSObject::GetLocalPropertyAccessorPair(obj, name).ToHandle(&accessors);
+      JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
@@ -2263,9 +2263,9 @@
     if (is_var || is_const) {
       // Lookup the property in the global object, and don't set the
       // value of the variable if the property is already there.
-      // Do the lookup locally only, see ES5 erratum.
+      // Do the lookup own properties only, see ES5 erratum.
       LookupResult lookup(isolate);
-      global->LocalLookup(name, &lookup, true);
+      global->LookupOwn(name, &lookup, true);
       if (lookup.IsFound()) {
         // We found an existing property. Unless it was an interceptor
         // that claims the property is absent, skip this declaration.
@@ -2285,7 +2285,7 @@
     }
 
     LookupResult lookup(isolate);
-    global->LocalLookup(name, &lookup, true);
+    global->LookupOwn(name, &lookup, true);
 
     // Compute the property attributes. According to ECMA-262,
     // the property must be non-configurable except in eval.
@@ -2302,7 +2302,7 @@
     StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
 
     if (!lookup.IsFound() || is_function) {
-      // If the local property exists, check that we can reconfigure it
+      // If the own property exists, check that we can reconfigure it
       // as required for function declarations.
       if (lookup.IsFound() && lookup.IsDontDelete()) {
         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
@@ -2314,7 +2314,7 @@
       }
       // Define or redefine own property.
       RETURN_FAILURE_ON_EXCEPTION(isolate,
-          JSObject::SetLocalPropertyIgnoreAttributes(
+          JSObject::SetOwnPropertyIgnoreAttributes(
               global, name, value, static_cast<PropertyAttributes>(attr)));
     } else {
       // Do a [[Put]] on the existing (own) property.
@@ -2400,7 +2400,7 @@
     // Declare the property by setting it to the initial value if provided,
     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
     // constant declarations).
-    ASSERT(!JSReceiver::HasLocalProperty(object, name));
+    ASSERT(!JSReceiver::HasOwnProperty(object, name));
     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
     if (*initial_value != NULL) value = initial_value;
     // Declaring a const context slot is a conflicting declaration if
@@ -2420,7 +2420,7 @@
     if (object->IsJSGlobalObject()) {
       // Define own property on the global object.
       RETURN_FAILURE_ON_EXCEPTION(isolate,
-         JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
+         JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
     } else {
       RETURN_FAILURE_ON_EXCEPTION(isolate,
          JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
@@ -2449,15 +2449,15 @@
   // not be deletable.
   PropertyAttributes attributes = DONT_DELETE;
 
-  // Lookup the property locally in the global object. If it isn't
+  // Lookup the property as own on the global object. If it isn't
   // there, there is a property with this name in the prototype chain.
   // We follow Safari and Firefox behavior and only set the property
-  // locally if there is an explicit initialization value that we have
+  // if there is an explicit initialization value that we have
   // to assign to the property.
   // Note that objects can have hidden prototypes, so we need to traverse
-  // the whole chain of hidden prototypes to do a 'local' lookup.
+  // the whole chain of hidden prototypes to do an 'own' lookup.
   LookupResult lookup(isolate);
-  isolate->context()->global_object()->LocalLookup(name, &lookup, true);
+  isolate->context()->global_object()->LookupOwn(name, &lookup, true);
   if (lookup.IsInterceptor()) {
     Handle<JSObject> holder(lookup.holder());
     PropertyAttributes intercepted =
@@ -2508,20 +2508,19 @@
   PropertyAttributes attributes =
       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
 
-  // Lookup the property locally in the global object. If it isn't
+  // Lookup the property as own on the global object. If it isn't
   // there, we add the property and take special precautions to always
-  // add it as a local property even in case of callbacks in the
-  // prototype chain (this rules out using SetProperty).
-  // We use SetLocalPropertyIgnoreAttributes instead
+  // add it even in case of callbacks in the prototype chain (this rules
+  // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
   LookupResult lookup(isolate);
-  global->LocalLookup(name, &lookup);
+  global->LookupOwn(name, &lookup);
   if (!lookup.IsFound()) {
     HandleScope handle_scope(isolate);
     Handle<GlobalObject> global(isolate->context()->global_object());
     RETURN_FAILURE_ON_EXCEPTION(
         isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
-                                                   attributes));
+        JSObject::SetOwnPropertyIgnoreAttributes(global, name, value,
+                                                 attributes));
     return *value;
   }
 
@@ -2630,7 +2629,7 @@
     // Set it if it hasn't been set before.  NOTE: We cannot use
     // GetProperty() to get the current value as it 'unholes' the value.
     LookupResult lookup(isolate);
-    object->LocalLookupRealNamedProperty(name, &lookup);
+    object->LookupOwnRealNamedProperty(name, &lookup);
     ASSERT(lookup.IsFound());  // the property was declared
     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
 
@@ -2763,15 +2762,15 @@
       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
   Handle<Object> zero(Smi::FromInt(0), isolate);
   Factory* factory = isolate->factory();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       regexp, factory->source_string(), source, final).Check();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       regexp, factory->global_string(), global, final).Check();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       regexp, factory->multiline_string(), multiline, final).Check();
-  JSObject::SetLocalPropertyIgnoreAttributes(
+  JSObject::SetOwnPropertyIgnoreAttributes(
       regexp, factory->last_index_string(), zero, writable).Check();
   return *regexp;
 }
@@ -5043,11 +5042,11 @@
   // Fast cases for getting named properties of the receiver JSObject
   // itself.
   //
-  // The global proxy objects has to be excluded since LocalLookup on
+  // The global proxy objects has to be excluded since LookupOwn on
   // the global proxy object can return a valid result even though the
   // global proxy object never has properties.  This is the case
   // because the global proxy object forwards everything to its hidden
-  // prototype including local lookups.
+  // prototype including own lookups.
   //
   // Additionally, we need to make sure that we do not cache results
   // for objects that require access checks.
@@ -5073,7 +5072,7 @@
         // Lookup cache miss.  Perform lookup and update the cache if
         // appropriate.
         LookupResult result(isolate);
-        receiver->LocalLookup(key, &result);
+        receiver->LookupOwn(key, &result);
         if (result.IsField()) {
           int offset = result.GetFieldIndex().field_index();
           // Do not track double fields in the keyed lookup cache. Reading
@@ -5198,7 +5197,7 @@
   }
 
   LookupResult lookup(isolate);
-  js_object->LocalLookupRealNamedProperty(name, &lookup);
+  js_object->LookupOwnRealNamedProperty(name, &lookup);
 
   // Special case for callback properties.
   if (lookup.IsPropertyCallbacks()) {
@@ -5243,7 +5242,7 @@
     Handle<Object> result;
     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
         isolate, result,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             js_object, name, obj_value, attr));
     return *result;
   }
@@ -5397,7 +5396,7 @@
                                   SLOPPY, false, DEFINE_PROPERTY);
     } else {
       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return JSObject::SetLocalPropertyIgnoreAttributes(
+      return JSObject::SetOwnPropertyIgnoreAttributes(
           js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
           ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
           store_from_keyed);
@@ -5414,7 +5413,7 @@
     return JSObject::SetElement(js_object, index, value, attr,
                                 SLOPPY, false, DEFINE_PROPERTY);
   } else {
-    return JSObject::SetLocalPropertyIgnoreAttributes(
+    return JSObject::SetOwnPropertyIgnoreAttributes(
         js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
         ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
         store_from_keyed);
@@ -5647,7 +5646,7 @@
 }
 
 
-// Set a local property, even if it is READ_ONLY.  If the property does not
+// Set an own property, even if it is READ_ONLY.  If the property does not
 // exist, it will be added with attributes NONE.
 RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
   HandleScope scope(isolate);
@@ -5667,7 +5666,7 @@
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           object, name, value, attributes));
   return *result;
 }
@@ -5689,10 +5688,10 @@
 }
 
 
-static Object* HasLocalPropertyImplementation(Isolate* isolate,
-                                              Handle<JSObject> object,
-                                              Handle<Name> key) {
-  if (JSReceiver::HasLocalProperty(object, key)) {
+static Object* HasOwnPropertyImplementation(Isolate* isolate,
+                                            Handle<JSObject> object,
+                                            Handle<Name> key) {
+  if (JSReceiver::HasOwnProperty(object, key)) {
     return isolate->heap()->true_value();
   }
   // Handle hidden prototypes.  If there's a hidden prototype above this thing
@@ -5701,16 +5700,16 @@
   Handle<Object> proto(object->GetPrototype(), isolate);
   if (proto->IsJSObject() &&
       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
-    return HasLocalPropertyImplementation(isolate,
-                                          Handle<JSObject>::cast(proto),
-                                          key);
+    return HasOwnPropertyImplementation(isolate,
+                                        Handle<JSObject>::cast(proto),
+                                        key);
   }
   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   return isolate->heap()->false_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_HasLocalProperty) {
+RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
@@ -5738,9 +5737,9 @@
       return isolate->heap()->false_value();
     }
     // Slow case.
-    return HasLocalPropertyImplementation(isolate,
-                                          Handle<JSObject>(js_obj),
-                                          Handle<Name>(key));
+    return HasOwnPropertyImplementation(isolate,
+                                        Handle<JSObject>(js_obj),
+                                        Handle<Name>(key));
   } else if (object->IsString() && key_is_array_index) {
     // Well, there is one exception:  Handle [] on strings.
     Handle<String> string = Handle<String>::cast(object);
@@ -5784,7 +5783,7 @@
   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
 
-  PropertyAttributes att = JSReceiver::GetLocalPropertyAttribute(object, key);
+  PropertyAttributes att = JSReceiver::GetOwnPropertyAttribute(object, key);
   if (att == ABSENT || (att & DONT_ENUM) != 0) {
     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
     return isolate->heap()->false_value();
@@ -5836,10 +5835,10 @@
 }
 
 
-// Find the length of the prototype chain that is to to handled as one. If a
+// Find the length of the prototype chain that is to be handled as one. If a
 // prototype object is hidden it is to be viewed as part of the the object it
 // is prototype for.
-static int LocalPrototypeChainLength(JSObject* obj) {
+static int OwnPrototypeChainLength(JSObject* obj) {
   int count = 1;
   Object* proto = obj->GetPrototype();
   while (proto->IsJSObject() &&
@@ -5851,10 +5850,10 @@
 }
 
 
-// Return the names of the local named properties.
+// Return the names of the own named properties.
 // args[0]: object
 // args[1]: PropertyAttributes as int
-RUNTIME_FUNCTION(Runtime_GetLocalPropertyNames) {
+RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
   if (!args[0]->IsJSObject()) {
@@ -5879,10 +5878,10 @@
   }
 
   // Find the number of objects making up this.
-  int length = LocalPrototypeChainLength(*obj);
+  int length = OwnPrototypeChainLength(*obj);
 
-  // Find the number of local properties for each of the objects.
-  ScopedVector<int> local_property_count(length);
+  // Find the number of own properties for each of the objects.
+  ScopedVector<int> own_property_count(length);
   int total_property_count = 0;
   Handle<JSObject> jsproto = obj;
   for (int i = 0; i < length; i++) {
@@ -5895,8 +5894,8 @@
       return *isolate->factory()->NewJSArray(0);
     }
     int n;
-    n = jsproto->NumberOfLocalProperties(filter);
-    local_property_count[i] = n;
+    n = jsproto->NumberOfOwnProperties(filter);
+    own_property_count[i] = n;
     total_property_count += n;
     if (i < length - 1) {
       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
@@ -5912,13 +5911,13 @@
   int next_copy_index = 0;
   int hidden_strings = 0;
   for (int i = 0; i < length; i++) {
-    jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
+    jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
     if (i > 0) {
       // Names from hidden prototypes may already have been added
       // for inherited function template instances. Count the duplicates
       // and stub them out; the final copy pass at the end ignores holes.
       for (int j = next_copy_index;
-           j < next_copy_index + local_property_count[i];
+           j < next_copy_index + own_property_count[i];
            j++) {
         Object* name_from_hidden_proto = names->get(j);
         for (int k = 0; k < next_copy_index; k++) {
@@ -5933,7 +5932,7 @@
         }
       }
     }
-    next_copy_index += local_property_count[i];
+    next_copy_index += own_property_count[i];
 
     // Hidden properties only show up if the filter does not skip strings.
     if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
@@ -5966,9 +5965,9 @@
 }
 
 
-// Return the names of the local indexed properties.
+// Return the names of the own indexed properties.
 // args[0]: object
-RUNTIME_FUNCTION(Runtime_GetLocalElementNames) {
+RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
   if (!args[0]->IsJSObject()) {
@@ -5976,9 +5975,9 @@
   }
   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
 
-  int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
+  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
-  obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
+  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
   return *isolate->factory()->NewJSArrayWithElements(names);
 }
 
@@ -6035,7 +6034,7 @@
 }
 
 
-RUNTIME_FUNCTION(Runtime_LocalKeys) {
+RUNTIME_FUNCTION(Runtime_OwnKeys) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
@@ -6060,7 +6059,7 @@
   Handle<FixedArray> contents;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, contents,
-      JSReceiver::GetKeys(object, JSReceiver::LOCAL_ONLY));
+      JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
 
   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
   // property array and since the result is mutable we have to create
@@ -9476,7 +9475,7 @@
 
   // Set the property if it's not read only or doesn't yet exist.
   if ((attributes & READ_ONLY) == 0 ||
-      (JSReceiver::GetLocalPropertyAttribute(object, name) == ABSENT)) {
+      (JSReceiver::GetOwnPropertyAttribute(object, name) == ABSENT)) {
     RETURN_FAILURE_ON_EXCEPTION(
         isolate,
         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
@@ -10716,9 +10715,8 @@
       }
       Handle<JSObject> current = Handle<JSObject>::cast(p);
       Handle<FixedArray> current_keys =
-          isolate->factory()->NewFixedArray(
-              current->NumberOfLocalElements(NONE));
-      current->GetLocalElementKeys(*current_keys, NONE);
+          isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
+      current->GetOwnElementKeys(*current_keys, NONE);
       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
     }
@@ -10901,13 +10899,13 @@
   }
 
   // Find the number of objects making up this.
-  int length = LocalPrototypeChainLength(*obj);
+  int length = OwnPrototypeChainLength(*obj);
 
-  // Try local lookup on each of the objects.
+  // Try own lookup on each of the objects.
   Handle<JSObject> jsproto = obj;
   for (int i = 0; i < length; i++) {
     LookupResult result(isolate);
-    jsproto->LocalLookup(name, &result);
+    jsproto->LookupOwn(name, &result);
     if (result.IsFound()) {
       // LookupResult is not GC safe as it holds raw object pointers.
       // GC can happen later in this code so put the required fields into
@@ -12842,8 +12840,8 @@
   // Do not materialize the arguments object for eval or top-level code.
   // Skip if "arguments" is already taken.
   if (!function->shared()->is_function() ||
-      JSReceiver::HasLocalProperty(target,
-                                   isolate->factory()->arguments_string())) {
+      JSReceiver::HasOwnProperty(
+          target, isolate->factory()->arguments_string())) {
     return target;
   }
 
@@ -13115,14 +13113,6 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
 
-  // First perform a full GC in order to avoid references from dead objects.
-  Heap* heap = isolate->heap();
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugReferencedBy");
-  // The heap iterator reserves the right to do a GC to make the heap iterable.
-  // Due to the GC above we know it won't need to do that, but it seems cleaner
-  // to get the heap iterator constructed before we start having unprotected
-  // Object* locals that are not protected by handles.
-
   // Check parameters.
   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
@@ -13140,21 +13130,27 @@
 
   // Get the number of referencing objects.
   int count;
-  HeapIterator heap_iterator(heap);
-  count = DebugReferencedBy(&heap_iterator,
-                            *target, *instance_filter, max_references,
-                            NULL, 0, *arguments_function);
+  // First perform a full GC in order to avoid dead objects and to make the heap
+  // iterable.
+  Heap* heap = isolate->heap();
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugReferencedBy(&heap_iterator,
+                              *target, *instance_filter, max_references,
+                              NULL, 0, *arguments_function);
+  }
 
   // Allocate an array to hold the result.
   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
 
   // Fill the referencing objects.
-  // AllocateFixedArray above does not make the heap non-iterable.
-  ASSERT(heap->IsHeapIterable());
-  HeapIterator heap_iterator2(heap);
-  count = DebugReferencedBy(&heap_iterator2,
-                            *target, *instance_filter, max_references,
-                            *instances, count, *arguments_function);
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugReferencedBy(&heap_iterator,
+                              *target, *instance_filter, max_references,
+                              *instances, count, *arguments_function);
+  }
 
   // Return result as JS array.
   Handle<JSFunction> constructor(
@@ -13205,9 +13201,6 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
 
-  // First perform a full GC in order to avoid dead objects.
-  Heap* heap = isolate->heap();
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
 
   // Check parameters.
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
@@ -13216,24 +13209,31 @@
 
   // Get the number of referencing objects.
   int count;
-  HeapIterator heap_iterator(heap);
-  count = DebugConstructedBy(&heap_iterator,
-                             *constructor,
-                             max_references,
-                             NULL,
-                             0);
+  // First perform a full GC in order to avoid dead objects and to make the heap
+  // iterable.
+  Heap* heap = isolate->heap();
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugConstructedBy(&heap_iterator,
+                               *constructor,
+                               max_references,
+                               NULL,
+                               0);
+  }
 
   // Allocate an array to hold the result.
   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
 
-  ASSERT(heap->IsHeapIterable());
   // Fill the referencing objects.
-  HeapIterator heap_iterator2(heap);
-  count = DebugConstructedBy(&heap_iterator2,
-                             *constructor,
-                             max_references,
-                             *instances,
-                             count);
+  {
+    HeapIterator heap_iterator2(heap);
+    count = DebugConstructedBy(&heap_iterator2,
+                               *constructor,
+                               max_references,
+                               *instances,
+                               count);
+  }
 
   // Return result as JS array.
   Handle<JSFunction> array_function(
@@ -13365,8 +13365,6 @@
   int number;
   Heap* heap = isolate->heap();
   {
-    heap->EnsureHeapIsIterable();
-    DisallowHeapAllocation no_allocation;
     HeapIterator heap_iterator(heap);
     Script* scr = *script;
     FixedArray* arr = *array;
@@ -13374,8 +13372,6 @@
   }
   if (number > kBufferSize) {
     array = isolate->factory()->NewFixedArray(number);
-    heap->EnsureHeapIsIterable();
-    DisallowHeapAllocation no_allocation;
     HeapIterator heap_iterator(heap);
     Script* scr = *script;
     FixedArray* arr = *array;
@@ -13778,7 +13774,7 @@
     }
 
     RETURN_FAILURE_ON_EXCEPTION(isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             locales,
             factory->NewStringFromAsciiChecked(result),
             factory->NewNumber(i),
@@ -13883,13 +13879,13 @@
 
     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
     RETURN_FAILURE_ON_EXCEPTION(isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             result,
             maximized,
             factory->NewStringFromAsciiChecked(base_max_locale),
             NONE));
     RETURN_FAILURE_ON_EXCEPTION(isolate,
-        JSObject::SetLocalPropertyIgnoreAttributes(
+        JSObject::SetOwnPropertyIgnoreAttributes(
             result,
             base,
             factory->NewStringFromAsciiChecked(base_locale),
@@ -14011,7 +14007,7 @@
   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
 
   RETURN_FAILURE_ON_EXCEPTION(isolate,
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           local_object,
           isolate->factory()->NewStringFromStaticAscii("dateFormat"),
           isolate->factory()->NewStringFromStaticAscii("valid"),
@@ -14110,7 +14106,7 @@
   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
 
   RETURN_FAILURE_ON_EXCEPTION(isolate,
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           local_object,
           isolate->factory()->NewStringFromStaticAscii("numberFormat"),
           isolate->factory()->NewStringFromStaticAscii("valid"),
@@ -14218,7 +14214,7 @@
   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
 
   RETURN_FAILURE_ON_EXCEPTION(isolate,
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           local_object,
           isolate->factory()->NewStringFromStaticAscii("collator"),
           isolate->factory()->NewStringFromStaticAscii("valid"),
@@ -14324,7 +14320,7 @@
   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
 
   RETURN_FAILURE_ON_EXCEPTION(isolate,
-      JSObject::SetLocalPropertyIgnoreAttributes(
+      JSObject::SetOwnPropertyIgnoreAttributes(
           local_object,
           isolate->factory()->NewStringFromStaticAscii("breakIterator"),
           isolate->factory()->NewStringFromStaticAscii("valid"),
@@ -14458,8 +14454,6 @@
   Handle<Script> script;
   Factory* factory = script_name->GetIsolate()->factory();
   Heap* heap = script_name->GetHeap();
-  heap->EnsureHeapIsIterable();
-  DisallowHeapAllocation no_allocation_during_heap_iteration;
   HeapIterator iterator(heap);
   HeapObject* obj = NULL;
   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
diff --git a/src/runtime.h b/src/runtime.h
index 1a93bf0..1332bae 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -26,14 +26,14 @@
   F(GetProperty, 2, 1) \
   F(KeyedGetProperty, 2, 1) \
   F(DeleteProperty, 3, 1) \
-  F(HasLocalProperty, 2, 1) \
+  F(HasOwnProperty, 2, 1) \
   F(HasProperty, 2, 1) \
   F(HasElement, 2, 1) \
   F(IsPropertyEnumerable, 2, 1) \
   F(GetPropertyNames, 1, 1) \
   F(GetPropertyNamesFast, 1, 1) \
-  F(GetLocalPropertyNames, 2, 1) \
-  F(GetLocalElementNames, 1, 1) \
+  F(GetOwnPropertyNames, 2, 1) \
+  F(GetOwnElementNames, 1, 1) \
   F(GetInterceptorInfo, 1, 1) \
   F(GetNamedInterceptorPropertyNames, 1, 1) \
   F(GetIndexedInterceptorElementNames, 1, 1) \
@@ -356,7 +356,7 @@
   F(Abort, 1, 1) \
   F(AbortJS, 1, 1) \
   /* ES5 */ \
-  F(LocalKeys, 1, 1) \
+  F(OwnKeys, 1, 1) \
   \
   /* Message objects */ \
   F(MessageGetStartPosition, 1, 1) \
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 1ed7e0b..14b8c4e 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -539,7 +539,7 @@
   int i = 0;
   for (Interface::Iterator it = interface->iterator();
        !it.done(); it.Advance(), ++i) {
-    Variable* var = scope->LocalLookup(it.name());
+    Variable* var = scope->LookupLocal(it.name());
     info->set_name(i, *it.name());
     info->set_mode(i, var->mode());
     ASSERT((var->mode() == MODULE) == (it.interface()->IsModule()));
diff --git a/src/scopes.cc b/src/scopes.cc
index 1818909..43b4f21 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -366,7 +366,7 @@
 }
 
 
-Variable* Scope::LocalLookup(Handle<String> name) {
+Variable* Scope::LookupLocal(Handle<String> name) {
   Variable* result = variables_.Lookup(name);
   if (result != NULL || scope_info_.is_null()) {
     return result;
@@ -425,7 +425,7 @@
   for (Scope* scope = this;
        scope != NULL;
        scope = scope->outer_scope()) {
-    Variable* var = scope->LocalLookup(name);
+    Variable* var = scope->LookupLocal(name);
     if (var != NULL) return var;
   }
   return NULL;
@@ -950,7 +950,7 @@
   }
 
   // Try to find the variable in this scope.
-  Variable* var = LocalLookup(name);
+  Variable* var = LookupLocal(name);
 
   // We found a variable and we are done. (Even if there is an 'eval' in
   // this scope which introduces the same variable again, the resulting
@@ -1211,7 +1211,7 @@
 
 void Scope::AllocateParameterLocals() {
   ASSERT(is_function_scope());
-  Variable* arguments = LocalLookup(isolate_->factory()->arguments_string());
+  Variable* arguments = LookupLocal(isolate_->factory()->arguments_string());
   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly
 
   bool uses_sloppy_arguments = false;
diff --git a/src/scopes.h b/src/scopes.h
index 23a10f1..f6f5431 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -100,7 +100,7 @@
   // Declarations
 
   // Lookup a variable in this scope. Returns the variable or NULL if not found.
-  Variable* LocalLookup(Handle<String> name);
+  Variable* LookupLocal(Handle<String> name);
 
   // This lookup corresponds to a lookup in the "intermediate" scope sitting
   // between this scope and the outer scope. (ECMA-262, 3rd., requires that
diff --git a/src/serialize.cc b/src/serialize.cc
index 2b43c0e..ab0f3ca 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -185,16 +185,6 @@
               isolate);
   }
 
-  // Debug addresses
-  Add(Debug_Address(Debug::k_after_break_target_address).address(isolate),
-      DEBUG_ADDRESS,
-      Debug::k_after_break_target_address << kDebugIdShift,
-      "Debug::after_break_target_address()");
-  Add(Debug_Address(Debug::k_restarter_frame_function_pointer).address(isolate),
-      DEBUG_ADDRESS,
-      Debug::k_restarter_frame_function_pointer << kDebugIdShift,
-      "Debug::restarter_frame_function_pointer_address()");
-
   // Stat counters
   struct StatsRefTableEntry {
     StatsCounter* (Counters::*counter)();
@@ -535,6 +525,18 @@
       66,
       "InvokeAccessorGetterCallback");
 
+  // Debug addresses
+  Add(ExternalReference::debug_after_break_target_address(isolate).address(),
+      UNCLASSIFIED,
+      67,
+      "Debug::after_break_target_address()");
+
+  Add(ExternalReference::debug_restarter_frame_function_pointer_address(
+          isolate).address(),
+      UNCLASSIFIED,
+      68,
+      "Debug::restarter_frame_function_pointer_address()");
+
   // Add a small set of deopt entry addresses to encoder without generating the
   // deopt table code, which isn't possible at deserialization time.
   HandleScope scope(isolate);
@@ -563,7 +565,7 @@
 uint32_t ExternalReferenceEncoder::Encode(Address key) const {
   int index = IndexOf(key);
   ASSERT(key == NULL || index >= 0);
-  return index >=0 ?
+  return index >= 0 ?
          ExternalReferenceTable::instance(isolate_)->code(index) : 0;
 }
 
@@ -613,7 +615,6 @@
   DeleteArray(encodings_);
 }
 
-AtomicWord Serializer::serialization_state_ = SERIALIZER_STATE_UNINITIALIZED;
 
 class CodeAddressMap: public CodeEventLogger {
  public:
@@ -630,6 +631,9 @@
     address_to_name_map_.Move(from, to);
   }
 
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) {
+  }
+
   virtual void CodeDeleteEvent(Address from) {
     address_to_name_map_.Remove(from);
   }
@@ -723,48 +727,6 @@
 };
 
 
-CodeAddressMap* Serializer::code_address_map_ = NULL;
-
-
-void Serializer::RequestEnable(Isolate* isolate) {
-  isolate->InitializeLoggingAndCounters();
-  code_address_map_ = new CodeAddressMap(isolate);
-}
-
-
-void Serializer::InitializeOncePerProcess() {
-  // InitializeOncePerProcess is called by V8::InitializeOncePerProcess, a
-  // method guaranteed to be called only once in a process lifetime.
-  // serialization_state_ is read by many threads, hence the use of
-  // Atomic primitives. Here, we don't need a barrier or mutex to
-  // write it because V8 initialization is done by one thread, and gates
-  // all reads of serialization_state_.
-  ASSERT(NoBarrier_Load(&serialization_state_) ==
-         SERIALIZER_STATE_UNINITIALIZED);
-  SerializationState state = code_address_map_
-      ? SERIALIZER_STATE_ENABLED
-      : SERIALIZER_STATE_DISABLED;
-  NoBarrier_Store(&serialization_state_, state);
-}
-
-
-void Serializer::TearDown() {
-  // TearDown is called by V8::TearDown() for the default isolate. It's safe
-  // to shut down the serializer by that point. Just to be safe, we restore
-  // serialization_state_ to uninitialized.
-  ASSERT(NoBarrier_Load(&serialization_state_) !=
-         SERIALIZER_STATE_UNINITIALIZED);
-  if (code_address_map_) {
-    ASSERT(NoBarrier_Load(&serialization_state_) ==
-           SERIALIZER_STATE_ENABLED);
-    delete code_address_map_;
-    code_address_map_ = NULL;
-  }
-
-  NoBarrier_Store(&serialization_state_, SERIALIZER_STATE_UNINITIALIZED);
-}
-
-
 Deserializer::Deserializer(SnapshotByteSource* source)
     : isolate_(NULL),
       source_(source),
@@ -1262,7 +1224,8 @@
     : isolate_(isolate),
       sink_(sink),
       external_reference_encoder_(new ExternalReferenceEncoder(isolate)),
-      root_index_wave_front_(0) {
+      root_index_wave_front_(0),
+      code_address_map_(NULL) {
   // The serializer is meant to be used only to generate initial heap images
   // from a context in which there is only one isolate.
   for (int i = 0; i <= LAST_SPACE; i++) {
@@ -1273,6 +1236,7 @@
 
 Serializer::~Serializer() {
   delete external_reference_encoder_;
+  if (code_address_map_ != NULL) delete code_address_map_;
 }
 
 
@@ -1338,7 +1302,7 @@
 // deserialized objects.
 void SerializerDeserializer::Iterate(Isolate* isolate,
                                      ObjectVisitor* visitor) {
-  if (Serializer::enabled(isolate)) return;
+  if (isolate->serializer_enabled()) return;
   for (int i = 0; ; i++) {
     if (isolate->serialize_partial_snapshot_cache_length() <= i) {
       // Extend the array ready to get a value from the visitor when
@@ -1578,12 +1542,14 @@
              "ObjectSerialization");
   sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
 
-  ASSERT(code_address_map_);
-  const char* code_name = code_address_map_->Lookup(object_->address());
-  LOG(serializer_->isolate_,
-      CodeNameEvent(object_->address(), sink_->Position(), code_name));
-  LOG(serializer_->isolate_,
-      SnapshotPositionEvent(object_->address(), sink_->Position()));
+  if (serializer_->code_address_map_) {
+    const char* code_name =
+        serializer_->code_address_map_->Lookup(object_->address());
+    LOG(serializer_->isolate_,
+        CodeNameEvent(object_->address(), sink_->Position(), code_name));
+    LOG(serializer_->isolate_,
+        SnapshotPositionEvent(object_->address(), sink_->Position()));
+  }
 
   // Mark this object as already serialized.
   int offset = serializer_->Allocate(space, size);
@@ -1863,6 +1829,12 @@
 }
 
 
+void Serializer::InitializeCodeAddressMap() {
+  isolate_->InitializeLoggingAndCounters();
+  code_address_map_ = new CodeAddressMap(isolate_);
+}
+
+
 bool SnapshotByteSource::AtEOF() {
   if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false;
   for (int x = position_; x < length_; x++) {
diff --git a/src/serialize.h b/src/serialize.h
index 958f20e..aaf97e3 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -17,7 +17,6 @@
   BUILTIN,
   RUNTIME_FUNCTION,
   IC_UTILITY,
-  DEBUG_ADDRESS,
   STATS_COUNTER,
   TOP_ADDRESS,
   C_BUILTIN,
@@ -34,8 +33,6 @@
 const int kReferenceIdBits = 16;
 const int kReferenceIdMask = (1 << kReferenceIdBits) - 1;
 const int kReferenceTypeShift = kReferenceIdBits;
-const int kDebugRegisterBits = 4;
-const int kDebugIdShift = kDebugRegisterBits;
 
 const int kDeoptTableSerializeEntryCount = 12;
 
@@ -60,7 +57,7 @@
 
  private:
   explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
-      PopulateTable(isolate);
+    PopulateTable(isolate);
   }
 
   struct ExternalReferenceEntry {
@@ -447,16 +444,7 @@
   }
 
   Isolate* isolate() const { return isolate_; }
-  static void RequestEnable(Isolate* isolate);
-  static void InitializeOncePerProcess();
-  static void TearDown();
 
-  static bool enabled(Isolate* isolate) {
-    SerializationState state = static_cast<SerializationState>(
-        NoBarrier_Load(&serialization_state_));
-    ASSERT(state != SERIALIZER_STATE_UNINITIALIZED);
-    return state == SERIALIZER_STATE_ENABLED;
-  }
   SerializationAddressMapper* address_mapper() { return &address_mapper_; }
   void PutRoot(int index,
                HeapObject* object,
@@ -555,14 +543,6 @@
   SnapshotByteSink* sink_;
   ExternalReferenceEncoder* external_reference_encoder_;
 
-  enum SerializationState {
-    SERIALIZER_STATE_UNINITIALIZED = 0,
-    SERIALIZER_STATE_DISABLED = 1,
-    SERIALIZER_STATE_ENABLED = 2
-  };
-
-  static AtomicWord serialization_state_;
-
   SerializationAddressMapper address_mapper_;
   intptr_t root_index_wave_front_;
   void Pad();
@@ -570,8 +550,12 @@
   friend class ObjectSerializer;
   friend class Deserializer;
 
+  // We may not need the code address map for logging for every instance
+  // of the serializer.  Initialize it on demand.
+  void InitializeCodeAddressMap();
+
  private:
-  static CodeAddressMap* code_address_map_;
+  CodeAddressMap* code_address_map_;
   DISALLOW_COPY_AND_ASSIGN(Serializer);
 };
 
@@ -584,6 +568,7 @@
     : Serializer(isolate, sink),
       startup_serializer_(startup_snapshot_serializer) {
     set_root_index_wave_front(Heap::kStrongRootListLength);
+    InitializeCodeAddressMap();
   }
 
   // Serialize the objects reachable from a single object pointer.
@@ -623,6 +608,7 @@
     // which will repopulate the cache with objects needed by that partial
     // snapshot.
     isolate->set_serialize_partial_snapshot_cache_length(0);
+    InitializeCodeAddressMap();
   }
   // Serialize the current state of the heap.  The order is:
   // 1) Strong references.
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 6bf209b..3d11dc1 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -759,7 +759,7 @@
 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
                                          Handle<Name> name,
                                          LookupResult* lookup) {
-  holder->LocalLookupRealNamedProperty(name, lookup);
+  holder->LookupOwnRealNamedProperty(name, lookup);
   if (lookup->IsFound()) return;
   if (holder->GetPrototype()->IsNull()) return;
   holder->GetPrototype()->Lookup(name, lookup);
diff --git a/src/type-info.cc b/src/type-info.cc
index 83fcd0f..ca3baa1 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -97,9 +97,7 @@
 
 bool TypeFeedbackOracle::CallIsMonomorphic(int slot) {
   Handle<Object> value = GetInfo(slot);
-  return FLAG_pretenuring_call_new
-      ? value->IsJSFunction()
-      : value->IsAllocationSite() || value->IsJSFunction();
+  return value->IsAllocationSite() || value->IsJSFunction();
 }
 
 
@@ -134,7 +132,10 @@
 
 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
   Handle<Object> info = GetInfo(slot);
-  if (FLAG_pretenuring_call_new || info->IsJSFunction()) {
+  if (info->IsAllocationSite()) {
+    ASSERT(!FLAG_pretenuring_call_new);
+    return Handle<JSFunction>(isolate()->native_context()->array_function());
+  } else {
     return Handle<JSFunction>::cast(info);
   }
 
@@ -154,6 +155,15 @@
 }
 
 
+Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(int slot) {
+  Handle<Object> info = GetInfo(slot);
+  if (info->IsAllocationSite()) {
+    return Handle<AllocationSite>::cast(info);
+  }
+  return Handle<AllocationSite>::null();
+}
+
+
 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(int slot) {
   Handle<Object> info = GetInfo(slot);
   if (FLAG_pretenuring_call_new || info->IsAllocationSite()) {
diff --git a/src/type-info.h b/src/type-info.h
index 24a9edb..6b99826 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -65,6 +65,7 @@
                                     Context* native_context);
 
   Handle<JSFunction> GetCallTarget(int slot);
+  Handle<AllocationSite> GetCallAllocationSite(int slot);
   Handle<JSFunction> GetCallNewTarget(int slot);
   Handle<AllocationSite> GetCallNewAllocationSite(int slot);
 
diff --git a/src/typing.cc b/src/typing.cc
index 434aff34..f32f0eb 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -511,6 +511,9 @@
       expr->IsUsingCallFeedbackSlot(isolate()) &&
       oracle()->CallIsMonomorphic(expr->CallFeedbackSlot())) {
     expr->set_target(oracle()->GetCallTarget(expr->CallFeedbackSlot()));
+    Handle<AllocationSite> site =
+        oracle()->GetCallAllocationSite(expr->CallFeedbackSlot());
+    expr->set_allocation_site(site);
   }
 
   ZoneList<Expression*>* args = expr->arguments();
diff --git a/src/uri.js b/src/uri.js
index fb9742f..4b7d1f7 100644
--- a/src/uri.js
+++ b/src/uri.js
@@ -13,431 +13,380 @@
 // This file contains support for URI manipulations written in
 // JavaScript.
 
-// Lazily initialized.
-var hexCharArray = 0;
-var hexCharCodeArray = 0;
 
+(function() {
 
-function URIAddEncodedOctetToBuffer(octet, result, index) {
-  result[index++] = 37; // Char code of '%'.
-  result[index++] = hexCharCodeArray[octet >> 4];
-  result[index++] = hexCharCodeArray[octet & 0x0F];
-  return index;
-}
+  // -------------------------------------------------------------------
+  // Define internal helper functions.
 
+  function HexValueOf(code) {
+    // 0-9
+    if (code >= 48 && code <= 57) return code - 48;
+    // A-F
+    if (code >= 65 && code <= 70) return code - 55;
+    // a-f
+    if (code >= 97 && code <= 102) return code - 87;
 
-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];
+    return -1;
   }
-  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;
-}
 
+  // 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;
 
-function URIEncodeSingle(cc, result, index) {
-  var x = (cc >> 12) & 0xF;
-  var y = (cc >> 6) & 63;
-  var z = cc & 63;
-  var octets = new $Array(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 false;
   }
-  return URIEncodeOctets(octets, result, index);
-}
 
+  //Lazily initialized.
+  var hexCharCodeArray = 0;
 
-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 $Array(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);
-  if (highCode == -1 || lowCode == -1) {
-    throw new $URIError("URI malformed");
+  function URIAddEncodedOctetToBuffer(octet, result, index) {
+    result[index++] = 37; // Char code of '%'.
+    result[index++] = hexCharCodeArray[octet >> 4];
+    result[index++] = hexCharCodeArray[octet & 0x0F];
+    return index;
   }
-  return (highCode << 4) | lowCode;
-}
 
+  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 URIDecodeOctets(octets, result, index) {
-  if (!IS_STRING(result)) throw new $URIError("Internal error");
-  var value;
-  var o0 = octets[0];
-  if (o0 < 0x80) {
-    value = o0;
-  } else if (o0 < 0xc2) {
-    throw new $URIError("URI malformed");
-  } else {
-    var o1 = octets[1];
-    if (o0 < 0xe0) {
-      var a = o0 & 0x1f;
-      if ((o1 < 0x80) || (o1 > 0xbf)) {
-        throw new $URIError("URI malformed");
-      }
-      var b = o1 & 0x3f;
-      value = (a << 6) + b;
-      if (value < 0x80 || value > 0x7ff) {
-        throw new $URIError("URI malformed");
-      }
+  function URIEncodeSingle(cc, result, index) {
+    var x = (cc >> 12) & 0xF;
+    var y = (cc >> 6) & 63;
+    var z = cc & 63;
+    var octets = new $Array(3);
+    if (cc <= 0x007F) {
+      octets[0] = cc;
+    } else if (cc <= 0x07FF) {
+      octets[0] = y + 192;
+      octets[1] = z + 128;
     } else {
-      var o2 = octets[2];
-      if (o0 < 0xf0) {
-        var a = o0 & 0x0f;
+      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 $Array(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);
+    if (highCode == -1 || lowCode == -1) {
+      throw new $URIError("URI malformed");
+    }
+    return (highCode << 4) | lowCode;
+  }
+
+  // Callers must ensure that |result| is a sufficiently long sequential
+  // two-byte string!
+  function URIDecodeOctets(octets, result, index) {
+    var value;
+    var o0 = octets[0];
+    if (o0 < 0x80) {
+      value = o0;
+    } else if (o0 < 0xc2) {
+      throw new $URIError("URI malformed");
+    } else {
+      var o1 = octets[1];
+      if (o0 < 0xe0) {
+        var a = o0 & 0x1f;
         if ((o1 < 0x80) || (o1 > 0xbf)) {
           throw new $URIError("URI malformed");
         }
         var b = o1 & 0x3f;
-        if ((o2 < 0x80) || (o2 > 0xbf)) {
-          throw new $URIError("URI malformed");
-        }
-        var c = o2 & 0x3f;
-        value = (a << 12) + (b << 6) + c;
-        if ((value < 0x800) || (value > 0xffff)) {
+        value = (a << 6) + b;
+        if (value < 0x80 || value > 0x7ff) {
           throw new $URIError("URI malformed");
         }
       } else {
-        var o3 = octets[3];
-        if (o0 < 0xf8) {
-          var a = (o0 & 0x07);
+        var o2 = octets[2];
+        if (o0 < 0xf0) {
+          var a = o0 & 0x0f;
           if ((o1 < 0x80) || (o1 > 0xbf)) {
             throw new $URIError("URI malformed");
           }
-          var b = (o1 & 0x3f);
+          var b = o1 & 0x3f;
           if ((o2 < 0x80) || (o2 > 0xbf)) {
             throw new $URIError("URI malformed");
           }
-          var c = (o2 & 0x3f);
-          if ((o3 < 0x80) || (o3 > 0xbf)) {
-            throw new $URIError("URI malformed");
-          }
-          var d = (o3 & 0x3f);
-          value = (a << 18) + (b << 12) + (c << 6) + d;
-          if ((value < 0x10000) || (value > 0x10ffff)) {
+          var c = o2 & 0x3f;
+          value = (a << 12) + (b << 6) + c;
+          if ((value < 0x800) || (value > 0xffff)) {
             throw new $URIError("URI malformed");
           }
         } else {
-          throw new $URIError("URI malformed");
+          var o3 = octets[3];
+          if (o0 < 0xf8) {
+            var a = (o0 & 0x07);
+            if ((o1 < 0x80) || (o1 > 0xbf)) {
+              throw new $URIError("URI malformed");
+            }
+            var b = (o1 & 0x3f);
+            if ((o2 < 0x80) || (o2 > 0xbf)) {
+              throw new $URIError("URI malformed");
+            }
+            var c = (o2 & 0x3f);
+            if ((o3 < 0x80) || (o3 > 0xbf)) {
+              throw new $URIError("URI malformed");
+            }
+            var d = (o3 & 0x3f);
+            value = (a << 18) + (b << 12) + (c << 6) + d;
+            if ((value < 0x10000) || (value > 0x10ffff)) {
+              throw new $URIError("URI malformed");
+            }
+          } else {
+            throw new $URIError("URI malformed");
+          }
         }
       }
     }
-  }
-  if (0xD800 <= value && value <= 0xDFFF) {
-    throw new $URIError("URI malformed");
-  }
-  if (value < 0x10000) {
-    if (index < 0 || index >= result.length) {
-      throw new $URIError("Internal error");
+    if (0xD800 <= value && value <= 0xDFFF) {
+      throw new $URIError("URI malformed");
     }
-    %_TwoByteSeqStringSetChar(result, index++, value);
-    return index;
-  } else {
-    if (index < 0 || index >= result.length - 1) {
-      throw new $URIError("Internal error");
+    if (value < 0x10000) {
+      %_TwoByteSeqStringSetChar(result, index++, value);
+    } else {
+      %_TwoByteSeqStringSetChar(result, index++, (value >> 10) + 0xd7c0);
+      %_TwoByteSeqStringSetChar(result, index++, (value & 0x3ff) + 0xdc00);
     }
-    %_TwoByteSeqStringSetChar(result, index++, (value >> 10) + 0xd7c0);
-    %_TwoByteSeqStringSetChar(result, index++, (value & 0x3ff) + 0xdc00);
     return index;
   }
-}
 
-
-// ECMA-262, section 15.1.3
-function Encode(uri, unescape) {
-  var uriLength = uri.length;
-  var array = new InternalArray(uriLength);
-  var index = 0;
-  for (var k = 0; k < uriLength; k++) {
-    var cc1 = uri.charCodeAt(k);
-    if (unescape(cc1)) {
-      array[index++] = cc1;
-    } else {
-      if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed");
-      if (cc1 < 0xD800 || cc1 > 0xDBFF) {
-        index = URIEncodeSingle(cc1, array, index);
+  // ECMA-262, section 15.1.3
+  function Encode(uri, unescape) {
+    var uriLength = uri.length;
+    var array = new InternalArray(uriLength);
+    var index = 0;
+    for (var k = 0; k < uriLength; k++) {
+      var cc1 = uri.charCodeAt(k);
+      if (unescape(cc1)) {
+        array[index++] = cc1;
       } else {
-        k++;
-        if (k == uriLength) throw new $URIError("URI malformed");
-        var cc2 = uri.charCodeAt(k);
-        if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed");
-        index = URIEncodePair(cc1, cc2, array, index);
-      }
-    }
-  }
-
-  var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
-  for (var i = 0; i < array.length; i++) {
-    %_OneByteSeqStringSetChar(result, i, array[i]);
-  }
-  return result;
-}
-
-
-// ECMA-262, section 15.1.3
-function Decode(uri, reserved) {
-  var uriLength = uri.length;
-  var one_byte = %NewString(uriLength, NEW_ONE_BYTE_STRING);
-  var index = 0;
-  var k = 0;
-
-  // Optimistically assume ascii string.
-  for ( ; k < uriLength; k++) {
-    var code = uri.charCodeAt(k);
-    if (code == 37) {  // '%'
-      if (k + 2 >= uriLength) throw new $URIError("URI malformed");
-      var cc = URIHexCharsToCharCode(uri.charCodeAt(k+1), uri.charCodeAt(k+2));
-      if (cc >> 7) break;  // Assumption wrong, two byte string.
-      if (reserved(cc)) {
-        %_OneByteSeqStringSetChar(one_byte, index++, 37);  // '%'.
-        %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+1));
-        %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+2));
-      } else {
-        %_OneByteSeqStringSetChar(one_byte, index++, cc);
-      }
-      k += 2;
-    } else {
-      if (code > 0x7f) break;  // Assumption wrong, two byte string.
-      %_OneByteSeqStringSetChar(one_byte, index++, code);
-    }
-  }
-
-  one_byte = %TruncateString(one_byte, index);
-  if (k == uriLength) return one_byte;
-
-  // Write into two byte string.
-  var two_byte = %NewString(uriLength - k, NEW_TWO_BYTE_STRING);
-  index = 0;
-
-  for ( ; k < uriLength; k++) {
-    var code = uri.charCodeAt(k);
-    if (code == 37) {  // '%'
-      if (k + 2 >= uriLength) throw new $URIError("URI malformed");
-      var cc = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k));
-      if (cc >> 7) {
-        var n = 0;
-        while (((cc << ++n) & 0x80) != 0) { }
-        if (n == 1 || n > 4) throw new $URIError("URI malformed");
-        var octets = new $Array(n);
-        octets[0] = cc;
-        if (k + 3 * (n - 1) >= uriLength) throw new $URIError("URI malformed");
-        for (var i = 1; i < n; i++) {
-          if (uri.charAt(++k) != '%') throw new $URIError("URI malformed");
-          octets[i] = URIHexCharsToCharCode(uri.charCodeAt(++k),
-                                            uri.charCodeAt(++k));
+        if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed");
+        if (cc1 < 0xD800 || cc1 > 0xDBFF) {
+          index = URIEncodeSingle(cc1, array, index);
+        } else {
+          k++;
+          if (k == uriLength) throw new $URIError("URI malformed");
+          var cc2 = uri.charCodeAt(k);
+          if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed");
+          index = URIEncodePair(cc1, cc2, array, index);
         }
-        index = URIDecodeOctets(octets, two_byte, index);
-      } else  if (reserved(cc)) {
-        %_TwoByteSeqStringSetChar(two_byte, index++, 37);  // '%'.
-        %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k - 1));
-        %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k));
-      } else {
-        %_TwoByteSeqStringSetChar(two_byte, index++, cc);
       }
-    } else {
-      %_TwoByteSeqStringSetChar(two_byte, index++, code);
     }
+
+    var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
+    for (var i = 0; i < array.length; i++) {
+      %_OneByteSeqStringSetChar(result, i, array[i]);
+    }
+    return result;
   }
 
-  two_byte = %TruncateString(two_byte, index);
-  return one_byte + two_byte;
-}
+  // ECMA-262, section 15.1.3
+  function Decode(uri, reserved) {
+    var uriLength = uri.length;
+    var one_byte = %NewString(uriLength, NEW_ONE_BYTE_STRING);
+    var index = 0;
+    var k = 0;
 
+    // Optimistically assume ascii string.
+    for ( ; k < uriLength; k++) {
+      var code = uri.charCodeAt(k);
+      if (code == 37) {  // '%'
+        if (k + 2 >= uriLength) throw new $URIError("URI malformed");
+        var cc = URIHexCharsToCharCode(uri.charCodeAt(k+1), uri.charCodeAt(k+2));
+        if (cc >> 7) break;  // Assumption wrong, two byte string.
+        if (reserved(cc)) {
+          %_OneByteSeqStringSetChar(one_byte, index++, 37);  // '%'.
+          %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+1));
+          %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+2));
+        } else {
+          %_OneByteSeqStringSetChar(one_byte, index++, cc);
+        }
+        k += 2;
+      } else {
+        if (code > 0x7f) break;  // Assumption wrong, two byte string.
+        %_OneByteSeqStringSetChar(one_byte, index++, code);
+      }
+    }
 
-// ECMA-262 - 15.1.3.1.
-function URIDecode(uri) {
-  var reservedPredicate = function(cc) {
-    // #$
-    if (35 <= cc && cc <= 36) return true;
-    // &
-    if (cc == 38) return true;
-    // +,
-    if (43 <= cc && cc <= 44) return true;
-    // /
-    if (cc == 47) return true;
-    // :;
-    if (58 <= cc && cc <= 59) return true;
-    // =
-    if (cc == 61) return true;
-    // ?@
-    if (63 <= cc && cc <= 64) return true;
+    one_byte = %TruncateString(one_byte, index);
+    if (k == uriLength) return one_byte;
 
-    return false;
-  };
-  var string = ToString(uri);
-  return Decode(string, reservedPredicate);
-}
+    // Write into two byte string.
+    var two_byte = %NewString(uriLength - k, NEW_TWO_BYTE_STRING);
+    index = 0;
 
+    for ( ; k < uriLength; k++) {
+      var code = uri.charCodeAt(k);
+      if (code == 37) {  // '%'
+        if (k + 2 >= uriLength) throw new $URIError("URI malformed");
+        var cc = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k));
+        if (cc >> 7) {
+          var n = 0;
+          while (((cc << ++n) & 0x80) != 0) { }
+          if (n == 1 || n > 4) throw new $URIError("URI malformed");
+          var octets = new $Array(n);
+          octets[0] = cc;
+          if (k + 3 * (n - 1) >= uriLength) throw new $URIError("URI malformed");
+          for (var i = 1; i < n; i++) {
+            if (uri.charAt(++k) != '%') throw new $URIError("URI malformed");
+            octets[i] = URIHexCharsToCharCode(uri.charCodeAt(++k),
+                                              uri.charCodeAt(++k));
+          }
+          index = URIDecodeOctets(octets, two_byte, index);
+        } else  if (reserved(cc)) {
+          %_TwoByteSeqStringSetChar(two_byte, index++, 37);  // '%'.
+          %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k - 1));
+          %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k));
+        } else {
+          %_TwoByteSeqStringSetChar(two_byte, index++, cc);
+        }
+      } else {
+        %_TwoByteSeqStringSetChar(two_byte, index++, code);
+      }
+    }
 
-// ECMA-262 - 15.1.3.2.
-function URIDecodeComponent(component) {
-  var reservedPredicate = function(cc) { return false; };
-  var string = ToString(component);
-  return Decode(string, reservedPredicate);
-}
-
-
-// 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;
-}
-
-
-// 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;
-  };
-
-  var string = ToString(uri);
-  return Encode(string, 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;
-  };
-
-  var string = ToString(component);
-  return Encode(string, unescapePredicate);
-}
-
-
-function HexValueOf(code) {
-  // 0-9
-  if (code >= 48 && code <= 57) return code - 48;
-  // A-F
-  if (code >= 65 && code <= 70) return code - 55;
-  // a-f
-  if (code >= 97 && code <= 102) return code - 87;
-
-  return -1;
-}
-
-
-// Convert a character code to 4-digit hex string representation
-// 64 -> 0040, 62234 -> F31A.
-function CharCodeToHex4Str(cc) {
-  var r = "";
-  if (hexCharArray === 0) {
-    hexCharArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
-                    "A", "B", "C", "D", "E", "F"];
+    two_byte = %TruncateString(two_byte, index);
+    return one_byte + two_byte;
   }
-  for (var i = 0; i < 4; ++i) {
-    var c = hexCharArray[cc & 0x0F];
-    r = c + r;
-    cc = cc >>> 4;
+
+  // -------------------------------------------------------------------
+  // Define exported functions.
+
+  // ECMA-262 - B.2.1.
+  function URIEscapeJS(str) {
+    var s = ToString(str);
+    return %URIEscape(s);
   }
-  return r;
-}
 
+  // ECMA-262 - B.2.2.
+  function URIUnescapeJS(str) {
+    var s = ToString(str);
+    return %URIUnescape(s);
+  }
 
-// Returns true if all digits in string s are valid hex numbers
-function IsValidHex(s) {
-  for (var i = 0; i < s.length; ++i) {
-    var cc = s.charCodeAt(i);
-    if ((48 <= cc && cc <= 57) ||
-        (65 <= cc && cc <= 70) ||
-        (97 <= cc && cc <= 102)) {
-      // '0'..'9', 'A'..'F' and 'a' .. 'f'.
-    } else {
+  // ECMA-262 - 15.1.3.1.
+  function URIDecode(uri) {
+    var reservedPredicate = function(cc) {
+      // #$
+      if (35 <= cc && cc <= 36) return true;
+      // &
+      if (cc == 38) return true;
+      // +,
+      if (43 <= cc && cc <= 44) return true;
+      // /
+      if (cc == 47) return true;
+      // :;
+      if (58 <= cc && cc <= 59) return true;
+      // =
+      if (cc == 61) return true;
+      // ?@
+      if (63 <= cc && cc <= 64) return true;
+
       return false;
-    }
+    };
+    var string = ToString(uri);
+    return Decode(string, reservedPredicate);
   }
-  return true;
-}
 
+  // ECMA-262 - 15.1.3.2.
+  function URIDecodeComponent(component) {
+    var reservedPredicate = function(cc) { return false; };
+    var string = ToString(component);
+    return Decode(string, reservedPredicate);
+  }
 
-// ECMA-262 - B.2.1.
-function URIEscapeJS(str) {
-  var s = ToString(str);
-  return %URIEscape(s);
-}
+  // 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;
+    };
+    var string = ToString(uri);
+    return Encode(string, unescapePredicate);
+  }
 
-// ECMA-262 - B.2.2.
-function URIUnescapeJS(str) {
-  var s = ToString(str);
-  return %URIUnescape(s);
-}
+  // 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;
+    };
+    var string = ToString(component);
+    return Encode(string, unescapePredicate);
+  }
 
-// -------------------------------------------------------------------
+  // -------------------------------------------------------------------
+  // Install exported functions.
 
-function SetUpUri() {
   %CheckIsBootstrapping();
 
   // Set up non-enumerable URI functions on the global object and set
   // their names.
   InstallFunctions(global, DONT_ENUM, $Array(
-    "escape", URIEscapeJS,
-    "unescape", URIUnescapeJS,
-    "decodeURI", URIDecode,
-    "decodeURIComponent", URIDecodeComponent,
-    "encodeURI", URIEncode,
-    "encodeURIComponent", URIEncodeComponent
+      "escape", URIEscapeJS,
+      "unescape", URIUnescapeJS,
+      "decodeURI", URIDecode,
+      "decodeURIComponent", URIDecodeComponent,
+      "encodeURI", URIEncode,
+      "encodeURIComponent", URIEncodeComponent
   ));
-}
 
-SetUpUri();
+})();
diff --git a/src/v8.cc b/src/v8.cc
index 08afb54..0048340 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -61,7 +61,6 @@
   Isolate::GlobalTearDown();
 
   Sampler::TearDown();
-  Serializer::TearDown();
 
 #ifdef V8_USE_DEFAULT_PLATFORM
   DefaultPlatform* platform = static_cast<DefaultPlatform*>(platform_);
@@ -79,7 +78,6 @@
 
 void V8::InitializeOncePerProcessImpl() {
   FlagList::EnforceFlagImplications();
-  Serializer::InitializeOncePerProcess();
 
   if (FLAG_predictable && FLAG_random_seed == 0) {
     // Avoid random seeds in predictable mode.
diff --git a/src/v8natives.js b/src/v8natives.js
index 1a50a84..4bbbac5 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -244,7 +244,7 @@
     var handler = %GetHandler(this);
     return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V));
   }
-  return %HasLocalProperty(TO_OBJECT_INLINE(this), ToName(V));
+  return %HasOwnProperty(TO_OBJECT_INLINE(this), ToName(V));
 }
 
 
@@ -332,7 +332,7 @@
     var names = CallTrap0(handler, "keys", DerivedKeysTrap);
     return ToNameArray(names, "keys", false);
   }
-  return %LocalKeys(obj);
+  return %OwnKeys(obj);
 }
 
 
@@ -1025,7 +1025,7 @@
     var s = ToName(obj[index]);
     // TODO(rossberg): adjust once there is a story for symbols vs proxies.
     if (IS_SYMBOL(s) && !includeSymbols) continue;
-    if (%HasLocalProperty(names, s)) {
+    if (%HasOwnProperty(names, s)) {
       throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]);
     }
     array[index] = s;
@@ -1045,13 +1045,13 @@
 
   // Find all the indexed properties.
 
-  // Only get the local element names if we want to include string keys.
+  // Only get own element names if we want to include string keys.
   if (!symbolsOnly) {
-    var localElementNames = %GetLocalElementNames(obj);
-    for (var i = 0; i < localElementNames.length; ++i) {
-      localElementNames[i] = %_NumberToString(localElementNames[i]);
+    var ownElementNames = %GetOwnElementNames(obj);
+    for (var i = 0; i < ownElementNames.length; ++i) {
+      ownElementNames[i] = %_NumberToString(ownElementNames[i]);
     }
-    nameArrays.push(localElementNames);
+    nameArrays.push(ownElementNames);
 
     // Get names for indexed interceptor properties.
     var interceptorInfo = %GetInterceptorInfo(obj);
@@ -1065,8 +1065,8 @@
 
   // Find all the named properties.
 
-  // Get the local property names.
-  nameArrays.push(%GetLocalPropertyNames(obj, filter));
+  // Get own property names.
+  nameArrays.push(%GetOwnPropertyNames(obj, filter));
 
   // Get names for named interceptor properties if any.
   if ((interceptorInfo & 2) != 0) {
@@ -1156,7 +1156,7 @@
       {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0};
     for (var i = 0; i < names.length; i++) {
       var N = names[i];
-      if (!(%HasLocalProperty(standardNames, N))) {
+      if (!(%HasOwnProperty(standardNames, N))) {
         var attr = GetOwnPropertyJS(attributes, N);
         DefineOwnProperty(descObj, N, attr, true);
       }
@@ -1176,7 +1176,7 @@
 function GetOwnEnumerablePropertyNames(properties) {
   var names = new InternalArray();
   for (var key in properties) {
-    if (%HasLocalProperty(properties, key)) {
+    if (%HasOwnProperty(properties, key)) {
       names.push(key);
     }
   }
diff --git a/src/version.cc b/src/version.cc
index f917194..cd81ed7 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     27
-#define BUILD_NUMBER      10
+#define BUILD_NUMBER      11
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 0e53eb3..a63288f 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -2228,16 +2228,17 @@
 }
 
 
-void CallFunctionStub::Generate(MacroAssembler* masm) {
+static void CallFunctionNoFeedback(MacroAssembler* masm,
+                                   int argc, bool needs_checks,
+                                   bool call_as_method) {
   // rdi : the function to call
 
   // wrap_and_call can only be true if we are compiling a monomorphic method.
   Isolate* isolate = masm->isolate();
   Label slow, non_function, wrap, cont;
-  int argc = argc_;
   StackArgumentsAccessor args(rsp, argc);
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Check that the function really is a JavaScript function.
     __ JumpIfSmi(rdi, &non_function);
 
@@ -2249,15 +2250,15 @@
   // Fast-case: Just invoke the function.
   ParameterCount actual(argc);
 
-  if (CallAsMethod()) {
-    if (NeedsChecks()) {
+  if (call_as_method) {
+    if (needs_checks) {
       EmitContinueIfStrictOrNative(masm, &cont);
     }
 
     // Load the receiver from the stack.
     __ movp(rax, args.GetReceiverOperand());
 
-    if (NeedsChecks()) {
+    if (needs_checks) {
       __ JumpIfSmi(rax, &wrap);
 
       __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
@@ -2271,19 +2272,24 @@
 
   __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
 
-  if (NeedsChecks()) {
+  if (needs_checks) {
     // Slow-case: Non-function called.
     __ bind(&slow);
     EmitSlowCase(isolate, masm, &args, argc, &non_function);
   }
 
-  if (CallAsMethod()) {
+  if (call_as_method) {
     __ bind(&wrap);
     EmitWrapCase(masm, &args, &cont);
   }
 }
 
 
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+}
+
+
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // rax : number of arguments
   // rbx : feedback vector
@@ -2358,6 +2364,54 @@
 }
 
 
+void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
+  // rdi - function
+  // rbx - feedback vector
+  // rdx - slot id (as integer)
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
+  __ cmpq(rdi, rcx);
+  __ j(not_equal, miss);
+
+  __ movq(rax, Immediate(arg_count()));
+  __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
+                            FixedArray::kHeaderSize));
+
+  // Verify that ecx contains an AllocationSite
+  __ AssertUndefinedOrAllocationSite(rbx);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+}
+
+
+void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
+  // rdi - function
+  // rbx - feedback vector
+  // rdx - slot id
+  Label miss;
+
+  __ SmiToInteger32(rdx, rdx);
+
+  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
+    Generate_MonomorphicArray(masm, &miss);
+  } else {
+    // So far there is only one customer for our custom feedback scheme.
+    UNREACHABLE();
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm,
+                         arg_count(),
+                         true,
+                         CallAsMethod());
+
+  // Unreachable.
+  __ int3();
+}
+
+
 void CallICStub::Generate(MacroAssembler* masm) {
   // rdi - function
   // rbx - vector
@@ -2372,6 +2426,11 @@
 
   EmitLoadTypeFeedbackVector(masm, rbx);
 
+  if (state_.stub_type() != CallIC::DEFAULT) {
+    Generate_CustomFeedbackCall(masm);
+    return;
+  }
+
   // The checks. First, does rdi match the recorded monomorphic target?
   __ SmiToInteger32(rdx, rdx);
   __ cmpq(rdi, FieldOperand(rbx, rdx, times_pointer_size,
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index 6e0e05f..29e176f 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -146,7 +146,7 @@
   // jumping to the target address intended by the caller and that was
   // overwritten by the address of DebugBreakXXX.
   ExternalReference after_break_target =
-      ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate());
+      ExternalReference::debug_after_break_target_address(masm->isolate());
   __ Move(kScratchRegister, after_break_target);
   __ Jump(Operand(kScratchRegister, 0));
 }
@@ -285,8 +285,8 @@
 
 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
   ExternalReference restarter_frame_function_slot =
-      ExternalReference(Debug_Address::RestarterFrameFunctionPointer(),
-                        masm->isolate());
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
   __ Move(rax, restarter_frame_function_slot);
   __ movp(Operand(rax, 0), Immediate(0));
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 1d1da3d..8a5f09a 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3024,15 +3024,11 @@
 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
   ElementsKind elements_kind = instr->elements_kind();
   LOperand* key = instr->key();
-  int base_offset = instr->is_fixed_typed_array()
-    ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-    : 0;
   Operand operand(BuildFastArrayOperand(
       instr->elements(),
       key,
       elements_kind,
-      base_offset,
-      instr->additional_index()));
+      instr->base_offset()));
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS) {
@@ -3098,14 +3094,11 @@
   XMMRegister result(ToDoubleRegister(instr->result()));
   LOperand* key = instr->key();
   if (instr->hydrogen()->RequiresHoleCheck()) {
-    int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
-        sizeof(kHoleNanLower32);
     Operand hole_check_operand = BuildFastArrayOperand(
         instr->elements(),
         key,
         FAST_DOUBLE_ELEMENTS,
-        offset,
-        instr->additional_index());
+        instr->base_offset() + sizeof(kHoleNanLower32));
     __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
     DeoptimizeIf(equal, instr->environment());
   }
@@ -3114,8 +3107,7 @@
       instr->elements(),
       key,
       FAST_DOUBLE_ELEMENTS,
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
-      instr->additional_index());
+      instr->base_offset());
   __ movsd(result, double_load_operand);
 }
 
@@ -3125,8 +3117,8 @@
   Register result = ToRegister(instr->result());
   LOperand* key = instr->key();
   bool requires_hole_check = hinstr->RequiresHoleCheck();
-  int offset = FixedArray::kHeaderSize - kHeapObjectTag;
   Representation representation = hinstr->representation();
+  int offset = instr->base_offset();
 
   if (representation.IsInteger32() && SmiValuesAre32Bits() &&
       hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
@@ -3137,8 +3129,7 @@
               BuildFastArrayOperand(instr->elements(),
                                     key,
                                     FAST_ELEMENTS,
-                                    offset,
-                                    instr->additional_index()),
+                                    offset),
               Representation::Smi());
       __ AssertSmi(scratch);
     }
@@ -3152,8 +3143,7 @@
           BuildFastArrayOperand(instr->elements(),
                                 key,
                                 FAST_ELEMENTS,
-                                offset,
-                                instr->additional_index()),
+                                offset),
           representation);
 
   // Check for the hole value.
@@ -3184,8 +3174,7 @@
     LOperand* elements_pointer,
     LOperand* key,
     ElementsKind elements_kind,
-    uint32_t offset,
-    uint32_t additional_index) {
+    uint32_t offset) {
   Register elements_pointer_reg = ToRegister(elements_pointer);
   int shift_size = ElementsKindToShiftSize(elements_kind);
   if (key->IsConstantOperand()) {
@@ -3194,14 +3183,13 @@
       Abort(kArrayIndexConstantValueTooBig);
     }
     return Operand(elements_pointer_reg,
-                   ((constant_value + additional_index) << shift_size)
-                       + offset);
+                   (constant_value << shift_size) + offset);
   } else {
     ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
     return Operand(elements_pointer_reg,
                    ToRegister(key),
                    scale_factor,
-                   offset + (additional_index << shift_size));
+                   offset);
   }
 }
 
@@ -4184,15 +4172,11 @@
 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
   ElementsKind elements_kind = instr->elements_kind();
   LOperand* key = instr->key();
-  int base_offset = instr->is_fixed_typed_array()
-    ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
-    : 0;
   Operand operand(BuildFastArrayOperand(
       instr->elements(),
       key,
       elements_kind,
-      base_offset,
-      instr->additional_index()));
+      instr->base_offset()));
 
   if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
       elements_kind == FLOAT32_ELEMENTS) {
@@ -4264,8 +4248,7 @@
       instr->elements(),
       key,
       FAST_DOUBLE_ELEMENTS,
-      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
-      instr->additional_index());
+      instr->base_offset());
 
   __ movsd(double_store_operand, value);
 }
@@ -4274,7 +4257,7 @@
 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
   HStoreKeyed* hinstr = instr->hydrogen();
   LOperand* key = instr->key();
-  int offset = FixedArray::kHeaderSize - kHeapObjectTag;
+  int offset = instr->base_offset();
   Representation representation = hinstr->value()->representation();
 
   if (representation.IsInteger32() && SmiValuesAre32Bits()) {
@@ -4286,8 +4269,7 @@
               BuildFastArrayOperand(instr->elements(),
                                     key,
                                     FAST_ELEMENTS,
-                                    offset,
-                                    instr->additional_index()),
+                                    offset),
               Representation::Smi());
       __ AssertSmi(scratch);
     }
@@ -4301,9 +4283,7 @@
       BuildFastArrayOperand(instr->elements(),
                             key,
                             FAST_ELEMENTS,
-                            offset,
-                            instr->additional_index());
-
+                            offset);
   if (instr->value()->IsRegister()) {
     __ Store(operand, ToRegister(instr->value()), representation);
   } else {
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 686dc85..0879b95 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -225,8 +225,7 @@
       LOperand* elements_pointer,
       LOperand* key,
       ElementsKind elements_kind,
-      uint32_t offset,
-      uint32_t additional_index = 0);
+      uint32_t base_offset);
 
   Operand BuildSeqStringOperand(Register string,
                                 LOperand* index,
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index cbade8a..ec677ee 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -371,7 +371,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d]", additional_index());
+    stream->Add(" + %d]", base_offset());
   } else {
     stream->Add("]");
   }
@@ -383,7 +383,7 @@
   stream->Add("[");
   key()->PrintTo(stream);
   if (hydrogen()->IsDehoisted()) {
-    stream->Add(" + %d] <-", additional_index());
+    stream->Add(" + %d] <-", base_offset());
   } else {
     stream->Add("] <- ");
   }
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 86121f6..e3db375 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1628,7 +1628,7 @@
   LOperand* elements() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
   ElementsKind elements_kind() const {
     return hydrogen()->elements_kind();
   }
@@ -2184,7 +2184,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
-  uint32_t additional_index() const { return hydrogen()->index_offset(); }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
 
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 1292628..e655749 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -205,7 +205,7 @@
             },
             {
               'dependencies': [
-                '../../tools/gyp/v8.gyp:v8_nosnapshot.<(v8_target_arch)',
+                '../../tools/gyp/v8.gyp:v8_nosnapshot',
               ],
             }],
           ],
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1d790a1..e2f7462 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -10282,7 +10282,7 @@
 
 
 // Getting property names of an object with a prototype chain that
-// triggers dictionary elements in GetLocalPropertyNames() shouldn't
+// triggers dictionary elements in GetOwnPropertyNames() shouldn't
 // crash the runtime.
 THREADED_TEST(Regress91517) {
   i::FLAG_allow_natives_syntax = true;
@@ -10321,11 +10321,11 @@
   CHECK(o3->SetPrototype(o2));
   CHECK(o2->SetPrototype(o1));
 
-  // Call the runtime version of GetLocalPropertyNames() on the natively
+  // Call the runtime version of GetOwnPropertyNames() on the natively
   // created object through JavaScript.
   context->Global()->Set(v8_str("obj"), o4);
   // PROPERTY_ATTRIBUTES_NONE = 0
-  CompileRun("var names = %GetLocalPropertyNames(obj, 0);");
+  CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
 
   ExpectInt32("names.length", 1006);
   ExpectTrue("names.indexOf(\"baz\") >= 0");
@@ -10376,12 +10376,12 @@
   o1->SetHiddenValue(
       v8_str("h1"), v8::Integer::New(context->GetIsolate(), 2013));
 
-  // Call the runtime version of GetLocalPropertyNames() on
+  // Call the runtime version of GetOwnPropertyNames() on
   // the natively created object through JavaScript.
   context->Global()->Set(v8_str("obj"), o2);
   context->Global()->Set(v8_str("sym"), sym);
   // PROPERTY_ATTRIBUTES_NONE = 0
-  CompileRun("var names = %GetLocalPropertyNames(obj, 0);");
+  CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
 
   ExpectInt32("names.length", 7);
   ExpectTrue("names.indexOf(\"foo\") >= 0");
@@ -13514,7 +13514,6 @@
 
 
 static int GetGlobalObjectsCount() {
-  CcTest::heap()->EnsureHeapIsIterable();
   int count = 0;
   i::HeapIterator it(CcTest::heap());
   for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
@@ -19252,7 +19251,7 @@
   ExpectUndefined("Object.prototype.__lookupGetter__.call("
                   "    other, \'x\')");
 
-  // HasLocalElement.
+  // HasOwnElement.
   ExpectFalse("Object.prototype.hasOwnProperty.call(other, \'0\')");
 
   CHECK_EQ(false, global0->HasRealIndexedProperty(0));
@@ -21686,13 +21685,13 @@
   CheckCorrectThrow("%IgnoreAttributesAndSetProperty(other, 'x', 'foo')");
   CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");
   CheckCorrectThrow("%DeleteProperty(other, '1', 0)");
-  CheckCorrectThrow("%HasLocalProperty(other, 'x')");
+  CheckCorrectThrow("%HasOwnProperty(other, 'x')");
   CheckCorrectThrow("%HasProperty(other, 'x')");
   CheckCorrectThrow("%HasElement(other, 1)");
   CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')");
   CheckCorrectThrow("%GetPropertyNames(other)");
   // PROPERTY_ATTRIBUTES_NONE = 0
-  CheckCorrectThrow("%GetLocalPropertyNames(other, 0)");
+  CheckCorrectThrow("%GetOwnPropertyNames(other, 0)");
   CheckCorrectThrow("%DefineOrRedefineAccessorProperty("
                         "other, 'x', null, null, 1)");
 
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 52e0fd6..ce422b5 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -587,6 +587,72 @@
 }
 
 
+static const char* hot_deopt_no_frame_entry_test_source =
+"function foo(a, b) {\n"
+"    try {\n"
+"      return a + b;\n"
+"    } catch (e) { }\n"
+"}\n"
+"function start(timeout) {\n"
+"  var start = Date.now();\n"
+"  do {\n"
+"    for (var i = 1; i < 1000; ++i) foo(1, i);\n"
+"    var duration = Date.now() - start;\n"
+"  } while (duration < timeout);\n"
+"  return duration;\n"
+"}\n";
+
+// Check that the profile tree for the script above will look like the
+// following:
+//
+// [Top down]:
+//  1062     0  (root) [-1]
+//  1054     0    start [-1]
+//  1054     1      foo [-1]
+//     2     2    (program) [-1]
+//     6     6    (garbage collector) [-1]
+//
+// The test checks no FP ranges are present in a deoptimized funcion.
+// If 'foo' has no ranges the samples falling into the prologue will miss the
+// 'start' function on the stack, so 'foo' will be attached to the (root).
+TEST(HotDeoptNoFrameEntry) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+  v8::Script::Compile(v8::String::NewFromUtf8(
+      env->GetIsolate(),
+      hot_deopt_no_frame_entry_test_source))->Run();
+  v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
+
+  int32_t profiling_interval_ms = 200;
+  v8::Handle<v8::Value> args[] = {
+    v8::Integer::New(env->GetIsolate(), profiling_interval_ms)
+  };
+  v8::CpuProfile* profile =
+      RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
+  function->Call(env->Global(), ARRAY_SIZE(args), args);
+
+  const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+
+  ScopedVector<v8::Handle<v8::String> > names(3);
+  names[0] = v8::String::NewFromUtf8(
+      env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName);
+  names[1] = v8::String::NewFromUtf8(env->GetIsolate(),
+                                     ProfileGenerator::kProgramEntryName);
+  names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start");
+  CheckChildrenNames(root, names);
+
+  const v8::CpuProfileNode* startNode =
+      GetChild(env->GetIsolate(), root, "start");
+  CHECK_EQ(1, startNode->GetChildrenCount());
+
+  GetChild(env->GetIsolate(), startNode, "foo");
+
+  profile->Delete();
+}
+
+
 TEST(CollectCpuProfileSamples) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index b369e83..9b1fd5d 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -275,7 +275,7 @@
   __ jmp(&L1);
   __ jmp(Operand(ebx, ecx, times_4, 10000));
   ExternalReference after_break_target =
-      ExternalReference(Debug_Address::AfterBreakTarget(), isolate);
+      ExternalReference::debug_after_break_target_address(isolate);
   __ jmp(Operand::StaticVariable(after_break_target));
   __ jmp(ic, RelocInfo::CODE_TARGET);
   __ nop();
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
index 3b1f8af..9a17dd1 100644
--- a/test/cctest/test-disasm-x64.cc
+++ b/test/cctest/test-disasm-x64.cc
@@ -261,7 +261,7 @@
   // TODO(mstarzinger): The following is protected.
   // __ jmp(Operand(rbx, rcx, times_4, 10000));
   ExternalReference after_break_target =
-      ExternalReference(Debug_Address::AfterBreakTarget(), isolate);
+      ExternalReference::debug_after_break_target_address(isolate);
   USE(after_break_target);
   __ jmp(ic, RelocInfo::CODE_TARGET);
   __ nop();
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index 0417ace..dbef127 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -471,6 +471,29 @@
 }
 
 
+TEST(HeapSnapshotSymbol) {
+  i::FLAG_harmony_symbols = true;
+
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+
+  CompileRun("a = Symbol('mySymbol');\n");
+  const v8::HeapSnapshot* snapshot =
+      heap_profiler->TakeHeapSnapshot(v8_str("Symbol"));
+  CHECK(ValidateSnapshot(snapshot));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  const v8::HeapGraphNode* a =
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "a");
+  CHECK_NE(NULL, a);
+  CHECK_EQ(a->GetType(), v8::HeapGraphNode::kSymbol);
+  CHECK_EQ(v8_str("symbol"), a->GetName());
+  const v8::HeapGraphNode* name =
+      GetProperty(a, v8::HeapGraphEdge::kInternal, "name");
+  CHECK_NE(NULL, name);
+  CHECK_EQ(v8_str("mySymbol"), name->GetName());
+}
+
 
 TEST(HeapSnapshotInternalReferences) {
   v8::Isolate* isolate = CcTest::isolate();
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 45ec1fc..f797ecc 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -209,7 +209,7 @@
 
   Handle<String> object_string = Handle<String>::cast(factory->Object_string());
   Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object());
-  CHECK(JSReceiver::HasLocalProperty(global, object_string));
+  CHECK(JSReceiver::HasOwnProperty(global, object_string));
 
   // Check ToString for oddballs
   CheckOddball(isolate, heap->true_value(), "true");
@@ -278,7 +278,7 @@
   heap->CollectGarbage(NEW_SPACE);
 
   // Function should be alive.
-  CHECK(JSReceiver::HasLocalProperty(global, name));
+  CHECK(JSReceiver::HasOwnProperty(global, name));
   // Check function is retained.
   Handle<Object> func_value =
       Object::GetProperty(global, name).ToHandleChecked();
@@ -297,7 +297,7 @@
   // After gc, it should survive.
   heap->CollectGarbage(NEW_SPACE);
 
-  CHECK(JSReceiver::HasLocalProperty(global, obj_name));
+  CHECK(JSReceiver::HasOwnProperty(global, obj_name));
   Handle<Object> obj =
       Object::GetProperty(global, obj_name).ToHandleChecked();
   CHECK(obj->IsJSObject());
@@ -655,55 +655,55 @@
   Handle<Smi> two(Smi::FromInt(2), isolate);
 
   // check for empty
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
+  CHECK(!JSReceiver::HasOwnProperty(obj, first));
 
   // add first
   JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
+  CHECK(JSReceiver::HasOwnProperty(obj, first));
 
   // delete first
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
+  CHECK(!JSReceiver::HasOwnProperty(obj, first));
 
   // add first and then second
   JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
   JSReceiver::SetProperty(obj, second, two, NONE, SLOPPY).Check();
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  CHECK(JSReceiver::HasOwnProperty(obj, first));
+  CHECK(JSReceiver::HasOwnProperty(obj, second));
 
   // delete first and then second
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  CHECK(JSReceiver::HasOwnProperty(obj, second));
   JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
-  CHECK(!JSReceiver::HasLocalProperty(obj, second));
+  CHECK(!JSReceiver::HasOwnProperty(obj, first));
+  CHECK(!JSReceiver::HasOwnProperty(obj, second));
 
   // add first and then second
   JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
   JSReceiver::SetProperty(obj, second, two, NONE, SLOPPY).Check();
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  CHECK(JSReceiver::HasOwnProperty(obj, first));
+  CHECK(JSReceiver::HasOwnProperty(obj, second));
 
   // delete second and then first
   JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
+  CHECK(JSReceiver::HasOwnProperty(obj, first));
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
-  CHECK(!JSReceiver::HasLocalProperty(obj, second));
+  CHECK(!JSReceiver::HasOwnProperty(obj, first));
+  CHECK(!JSReceiver::HasOwnProperty(obj, second));
 
   // check string and internalized string match
   const char* string1 = "fisk";
   Handle<String> s1 = factory->NewStringFromAsciiChecked(string1);
   JSReceiver::SetProperty(obj, s1, one, NONE, SLOPPY).Check();
   Handle<String> s1_string = factory->InternalizeUtf8String(string1);
-  CHECK(JSReceiver::HasLocalProperty(obj, s1_string));
+  CHECK(JSReceiver::HasOwnProperty(obj, s1_string));
 
   // check internalized string and string match
   const char* string2 = "fugl";
   Handle<String> s2_string = factory->InternalizeUtf8String(string2);
   JSReceiver::SetProperty(obj, s2_string, one, NONE, SLOPPY).Check();
   Handle<String> s2 = factory->NewStringFromAsciiChecked(string2);
-  CHECK(JSReceiver::HasLocalProperty(obj, s2));
+  CHECK(JSReceiver::HasOwnProperty(obj, s2));
 }
 
 
@@ -890,7 +890,6 @@
 static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) {
   // Count the number of objects found in the heap.
   int found_count = 0;
-  heap->EnsureHeapIsIterable();
   HeapIterator iterator(heap);
   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
     for (int i = 0; i < size; i++) {
@@ -1629,9 +1628,8 @@
 
 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
   CcTest::InitializeVM();
-  CcTest::heap()->EnsureHeapIsIterable();
-  intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects();
   HeapIterator iterator(CcTest::heap());
+  intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects();
   intptr_t size_of_objects_2 = 0;
   for (HeapObject* obj = iterator.next();
        obj != NULL;
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index 08b1c71..529bd242 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -166,7 +166,7 @@
 
   { HandleScope scope(isolate);
     Handle<String> func_name = factory->InternalizeUtf8String("theFunction");
-    CHECK(JSReceiver::HasLocalProperty(global, func_name));
+    CHECK(JSReceiver::HasOwnProperty(global, func_name));
     Handle<Object> func_value =
         Object::GetProperty(global, func_name).ToHandleChecked();
     CHECK(func_value->IsJSFunction());
@@ -184,7 +184,7 @@
 
   { HandleScope scope(isolate);
     Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
-    CHECK(JSReceiver::HasLocalProperty(global, obj_name));
+    CHECK(JSReceiver::HasOwnProperty(global, obj_name));
     Handle<Object> object =
         Object::GetProperty(global, obj_name).ToHandleChecked();
     CHECK(object->IsJSObject());
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc
index a7b346f..7c78932 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -616,7 +616,6 @@
 
 
 static int GetGlobalObjectsCount() {
-  CcTest::heap()->EnsureHeapIsIterable();
   int count = 0;
   i::HeapIterator it(CcTest::heap());
   for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 10c35c1..59ce2da 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -262,7 +262,7 @@
 // Test that the whole heap can be serialized.
 TEST(Serialize) {
   if (!Snapshot::HaveASnapshotToStartFrom()) {
-    Serializer::RequestEnable(CcTest::i_isolate());
+    CcTest::i_isolate()->enable_serializer();
     v8::V8::Initialize();
     Serialize();
   }
@@ -272,7 +272,7 @@
 // Test that heap serialization is non-destructive.
 TEST(SerializeTwice) {
   if (!Snapshot::HaveASnapshotToStartFrom()) {
-    Serializer::RequestEnable(CcTest::i_isolate());
+    CcTest::i_isolate()->enable_serializer();
     v8::V8::Initialize();
     Serialize();
     Serialize();
@@ -370,7 +370,7 @@
 TEST(PartialSerialization) {
   if (!Snapshot::HaveASnapshotToStartFrom()) {
     Isolate* isolate = CcTest::i_isolate();
-    Serializer::RequestEnable(isolate);
+    CcTest::i_isolate()->enable_serializer();
     v8::V8::Initialize();
     v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     Heap* heap = isolate->heap();
@@ -521,7 +521,7 @@
 TEST(ContextSerialization) {
   if (!Snapshot::HaveASnapshotToStartFrom()) {
     Isolate* isolate = CcTest::i_isolate();
-    Serializer::RequestEnable(isolate);
+    CcTest::i_isolate()->enable_serializer();
     v8::V8::Initialize();
     v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     Heap* heap = isolate->heap();
diff --git a/test/mjsunit/array-constructor-feedback.js b/test/mjsunit/array-constructor-feedback.js
index 45d5c58..9bc62e4 100644
--- a/test/mjsunit/array-constructor-feedback.js
+++ b/test/mjsunit/array-constructor-feedback.js
@@ -150,18 +150,11 @@
     a = bar(10);
     assertKind(elements_kind.fast, a);
     assertOptimized(bar);
-    // bar should deopt because the length is too large.
-    a = bar(100000);
-    assertUnoptimized(bar);
-    assertKind(elements_kind.dictionary, a);
-    // The allocation site now has feedback that means the array constructor
-    // will not be inlined.
-    %OptimizeFunctionOnNextCall(bar);
     a = bar(100000);
     assertKind(elements_kind.dictionary, a);
     assertOptimized(bar);
 
-    // If the argument isn't a smi, it bails out as well
+    // If the argument isn't a smi, things should still work.
     a = bar("oops");
     assertOptimized(bar);
     assertKind(elements_kind.fast, a);
@@ -176,12 +169,6 @@
     barn(1, 2, 3);
     assertOptimized(barn);
     a = barn(1, "oops", 3);
-    // The method should deopt, but learn from the failure to avoid inlining
-    // the array.
-    assertKind(elements_kind.fast, a);
-    assertUnoptimized(barn);
-    %OptimizeFunctionOnNextCall(barn);
-    a = barn(1, "oops", 3);
     assertOptimized(barn);
   })();
 
@@ -228,10 +215,8 @@
     assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
   })();
 
-  // Test: create array with packed feedback, then optimize/inline
-  // function. Verify that if we ask for a holey array then we deopt.
-  // Reoptimization will proceed with the correct feedback and we
-  // won't deopt anymore.
+  // Test: create array with packed feedback, then optimize function, which
+  // should deal with arguments that create holey arrays.
   (function() {
     function bar(len) { return new Array(len); }
     bar(0);
@@ -241,15 +226,16 @@
     assertOptimized(bar);
     assertFalse(isHoley(a));
     a = bar(1);  // ouch!
-    assertUnoptimized(bar);
-    assertTrue(isHoley(a));
-    // Try again
-    %OptimizeFunctionOnNextCall(bar);
-    a = bar(100);
     assertOptimized(bar);
     assertTrue(isHoley(a));
+    a = bar(100);
+    assertTrue(isHoley(a));
     a = bar(0);
     assertOptimized(bar);
-    assertTrue(isHoley(a));
+    // Crankshafted functions don't use mementos, so feedback still
+    // indicates a packed array is desired. (unless --nocrankshaft is in use).
+    if (4 != %GetOptimizationStatus(bar)) {
+      assertFalse(isHoley(a));
+    }
   })();
 }
diff --git a/test/mjsunit/array-feedback.js b/test/mjsunit/array-feedback.js
index 4129be1..cb91995 100644
--- a/test/mjsunit/array-feedback.js
+++ b/test/mjsunit/array-feedback.js
@@ -85,69 +85,69 @@
   // Verify that basic elements kind feedback works for non-constructor
   // array calls (as long as the call is made through an IC, and not
   // a CallStub).
-  // (function (){
-  //   function create0() {
-  //     return Array();
-  //   }
+  (function (){
+    function create0() {
+      return Array();
+    }
 
-  //   // Calls through ICs need warm up through uninitialized, then
-  //   // premonomorphic first.
-  //   create0();
-  //   create0();
-  //   a = create0();
-  //   assertKind(elements_kind.fast_smi_only, a);
-  //   a[0] = 3.5;
-  //   b = create0();
-  //   assertKind(elements_kind.fast_double, b);
+    // Calls through ICs need warm up through uninitialized, then
+    // premonomorphic first.
+    create0();
+    a = create0();
+    assertKind(elements_kind.fast_smi_only, a);
+    a[0] = 3.5;
+    b = create0();
+    assertKind(elements_kind.fast_double, b);
 
-  //   function create1(arg) {
-  //     return Array(arg);
-  //   }
+    function create1(arg) {
+      return Array(arg);
+    }
 
-  //   create1(0);
-  //   create1(0);
-  //   a = create1(0);
-  //   assertFalse(isHoley(a));
-  //   assertKind(elements_kind.fast_smi_only, a);
-  //   a[0] = "hello";
-  //   b = create1(10);
-  //   assertTrue(isHoley(b));
-  //   assertKind(elements_kind.fast, b);
+    create1(0);
+    create1(0);
+    a = create1(0);
+    assertFalse(isHoley(a));
+    assertKind(elements_kind.fast_smi_only, a);
+    a[0] = "hello";
+    b = create1(10);
+    assertTrue(isHoley(b));
+    assertKind(elements_kind.fast, b);
 
-  //   a = create1(100000);
-  //   assertKind(elements_kind.dictionary, a);
+    a = create1(100000);
+    assertKind(elements_kind.dictionary, a);
 
-  //   function create3(arg1, arg2, arg3) {
-  //     return Array(arg1, arg2, arg3);
-  //   }
+    function create3(arg1, arg2, arg3) {
+      return Array(arg1, arg2, arg3);
+    }
 
-  //   create3();
-  //   create3();
-  //   a = create3(1,2,3);
-  //   a[0] = 3.5;
-  //   b = create3(1,2,3);
-  //   assertKind(elements_kind.fast_double, b);
-  //   assertFalse(isHoley(b));
-  // })();
+    create3(1,2,3);
+    create3(1,2,3);
+    a = create3(1,2,3);
+    a[0] = 3.035;
+    assertKind(elements_kind.fast_double, a);
+    b = create3(1,2,3);
+    assertKind(elements_kind.fast_double, b);
+    assertFalse(isHoley(b));
+  })();
 
 
   // Verify that keyed calls work
-  // (function (){
-  //   function create0(name) {
-  //     return this[name]();
-  //   }
+  (function (){
+    function create0(name) {
+      return this[name]();
+    }
 
-  //   name = "Array";
-  //   create0(name);
-  //   create0(name);
-  //   a = create0(name);
-  //   a[0] = 3.5;
-  //   b = create0(name);
-  //   assertKind(elements_kind.fast_double, b);
-  // })();
+    name = "Array";
+    create0(name);
+    create0(name);
+    a = create0(name);
+    a[0] = 3.5;
+    b = create0(name);
+    assertKind(elements_kind.fast_double, b);
+  })();
 
 
-  // Verify that the IC can't be spoofed by patching
+  // Verify that crankshaft consumes type feedback.
   (function (){
     function create0() {
       return Array();
@@ -156,42 +156,41 @@
     create0();
     create0();
     a = create0();
-    assertKind(elements_kind.fast_smi_only, a);
-    var oldArray = this.Array;
-    this.Array = function() { return ["hi"]; };
+    a[0] = 3.5;
+    %OptimizeFunctionOnNextCall(create0);
+    create0();
+    create0();
     b = create0();
-    assertEquals(["hi"], b);
-    this.Array = oldArray;
+    assertKind(elements_kind.fast_double, b);
+    assertOptimized(create0);
+
+    function create1(arg) {
+      return Array(arg);
+    }
+
+    create1(8);
+    create1(8);
+    a = create1(8);
+    a[0] = 3.5;
+    %OptimizeFunctionOnNextCall(create1);
+    b = create1(8);
+    assertKind(elements_kind.fast_double, b);
+    assertOptimized(create1);
+
+    function createN(arg1, arg2, arg3) {
+      return Array(arg1, arg2, arg3);
+    }
+
+    createN(1, 2, 3);
+    createN(1, 2, 3);
+    a = createN(1, 2, 3);
+    a[0] = 3.5;
+    %OptimizeFunctionOnNextCall(createN);
+    b = createN(1, 2, 3);
+    assertKind(elements_kind.fast_double, b);
+    assertOptimized(createN);
   })();
 
-  // Verify that calls are still made through an IC after crankshaft,
-  // though the type information is reset.
-  // TODO(mvstanton): instead, consume the type feedback gathered up
-  // until crankshaft time.
-  // (function (){
-  //   function create0() {
-  //     return Array();
-  //   }
-
-  //   create0();
-  //   create0();
-  //   a = create0();
-  //   a[0] = 3.5;
-  //   %OptimizeFunctionOnNextCall(create0);
-  //   create0();
-  //   // This test only makes sense if crankshaft is allowed
-  //   if (4 != %GetOptimizationStatus(create0)) {
-  //     create0();
-  //     b = create0();
-  //     assertKind(elements_kind.fast_smi_only, b);
-  //     b[0] = 3.5;
-  //     c = create0();
-  //     assertKind(elements_kind.fast_double, c);
-  //     assertOptimized(create0);
-  //   }
-  // })();
-
-
   // Verify that cross context calls work
   (function (){
     var realmA = Realm.current();
diff --git a/test/mjsunit/array-push-unshift-read-only-length.js b/test/mjsunit/array-push-unshift-read-only-length.js
new file mode 100644
index 0000000..67aa397
--- /dev/null
+++ b/test/mjsunit/array-push-unshift-read-only-length.js
@@ -0,0 +1,107 @@
+// Copyright 2014 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.
+
+// Flags: --allow-natives-syntax
+
+function test(mode) {
+  var a = [];
+  Object.defineProperty(a, "length", { writable : false});
+
+  function check(f) {
+    try {
+      f(a);
+    } catch(e) { }
+    assertFalse(0 in a);
+    assertEquals(0, a.length);
+  }
+
+  function push(a) {
+    a.push(3);
+  }
+
+  if (mode == "fast properties") %ToFastProperties(a);
+
+  check(push);
+  check(push);
+  check(push);
+  %OptimizeFunctionOnNextCall(push);
+  check(push);
+
+  function unshift(a) {
+    a.unshift(3);
+  }
+
+  check(unshift);
+  check(unshift);
+  check(unshift);
+  %OptimizeFunctionOnNextCall(unshift);
+  check(unshift);
+}
+
+test("fast properties");
+
+test("normalized");
+
+var b = [];
+Object.defineProperty(b.__proto__, "0", {
+  set : function(v) {
+    b.x = v;
+    Object.defineProperty(b, "length", { writable : false });
+  },
+  get: function() {
+    return b.x;
+  }
+});
+
+b = [];
+try {
+  b.push(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [];
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [1, 2];
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+assertEquals(3, b[0]);
+assertEquals(4, b[1]);
+assertEquals(5, b[2]);
+assertEquals(1, b[3]);
+assertEquals(2, b[4]);
+assertEquals(5, b.length);
+
+b = [1, 2];
+
+Object.defineProperty(b.__proto__, "4", {
+  set : function(v) {
+    b.z = v;
+    Object.defineProperty(b, "length", { writable : false });
+  },
+  get: function() {
+    return b.z;
+  }
+});
+
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+
+// TODO(ulan): According to the ECMA-262 unshift should throw an exception
+// when moving b[0] to b[3] (see 15.4.4.13 step 6.d.ii). This is difficult
+// to do with our current implementation of SmartMove() in src/array.js and
+// it will regress performance. Uncomment the following line once acceptable
+// solution is found:
+// assertFalse(2 in b);
+// assertFalse(3 in b);
+// assertEquals(2, b.length);
diff --git a/test/mjsunit/harmony/generators-debug-liveedit.js b/test/mjsunit/harmony/generators-debug-liveedit.js
new file mode 100644
index 0000000..341ef48
--- /dev/null
+++ b/test/mjsunit/harmony/generators-debug-liveedit.js
@@ -0,0 +1,119 @@
+// Copyright 2014 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.
+
+// Flags: --expose-debug-as debug --harmony-generators
+
+var Debug = debug.Debug;
+var LiveEdit = Debug.LiveEdit;
+
+unique_id = 0;
+
+var Generator = (function*(){}).constructor;
+
+function assertIteratorResult(value, done, result) {
+  assertEquals({value: value, done: done}, result);
+}
+
+function MakeGenerator() {
+  // Prevents eval script caching.
+  unique_id++;
+  return Generator('callback',
+      "/* " + unique_id + "*/\n" +
+      "yield callback();\n" +
+      "return 'Cat';\n");
+}
+
+function MakeFunction() {
+  // Prevents eval script caching.
+  unique_id++;
+  return Function('callback',
+      "/* " + unique_id + "*/\n" +
+      "callback();\n" +
+      "return 'Cat';\n");
+}
+
+// First, try MakeGenerator with no perturbations.
+(function(){
+  var generator = MakeGenerator();
+  function callback() {};
+  var iter = generator(callback);
+  assertIteratorResult(undefined, false, iter.next());
+  assertIteratorResult("Cat", true, iter.next());
+})();
+
+function patch(fun, from, to) {
+  function debug() {
+    var log = new Array();
+    var script = Debug.findScript(fun);
+    var pos = script.source.indexOf(from);
+    try {
+      LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
+                                             log);
+    } finally {
+      print("Change log: " + JSON.stringify(log) + "\n");
+    }
+  }
+  Debug.ExecuteInDebugContext(debug, false);
+}
+
+// Try to edit a MakeGenerator while it's running, then again while it's
+// stopped.
+(function(){
+  var generator = MakeGenerator();
+
+  var gen_patch_attempted = false;
+  function attempt_gen_patch() {
+    assertFalse(gen_patch_attempted);
+    gen_patch_attempted = true;
+    assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
+                 LiveEdit.Failure);
+  };
+  var iter = generator(attempt_gen_patch);
+  assertIteratorResult(undefined, false, iter.next());
+  // Patch should not succeed because there is a live generator activation on
+  // the stack.
+  assertIteratorResult("Cat", true, iter.next());
+  assertTrue(gen_patch_attempted);
+
+  // At this point one iterator is live, but closed, so the patch will succeed.
+  patch(generator, "'Cat'", "'Capybara'");
+  iter = generator(function(){});
+  assertIteratorResult(undefined, false, iter.next());
+  // Patch successful.
+  assertIteratorResult("Capybara", true, iter.next());
+
+  // Patching will fail however when a live iterator is suspended.
+  iter = generator(function(){});
+  assertIteratorResult(undefined, false, iter.next());
+  assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
+               LiveEdit.Failure);
+  assertIteratorResult("Capybara", true, iter.next());
+
+  // Try to patch functions with activations inside and outside generator
+  // function activations.  We should succeed in the former case, but not in the
+  // latter.
+  var fun_outside = MakeFunction();
+  var fun_inside = MakeFunction();
+  var fun_patch_attempted = false;
+  var fun_patch_restarted = false;
+  function attempt_fun_patches() {
+    if (fun_patch_attempted) {
+      assertFalse(fun_patch_restarted);
+      fun_patch_restarted = true;
+      return;
+    }
+    fun_patch_attempted = true;
+    // Patching outside a generator activation must fail.
+    assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
+                 LiveEdit.Failure);
+    // Patching inside a generator activation may succeed.
+    patch(fun_inside, "'Cat'", "'Koala'");
+  }
+  iter = generator(function() { return fun_inside(attempt_fun_patches) });
+  assertEquals('Cat',
+               fun_outside(function () {
+                 assertIteratorResult('Koala', false, iter.next());
+                 assertTrue(fun_patch_restarted);
+               }));
+})();
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index e460e7c..2df8747 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -206,6 +206,7 @@
   'debug-liveedit-stack-padding': [SKIP],
   'debug-liveedit-restart-frame': [SKIP],
   'debug-liveedit-double-call': [SKIP],
+  'harmony/generators-debug-liveedit': [SKIP],
 
   # BUG(v8:3147). It works on other architectures by accident.
   'regress/regress-conditional-position': [FAIL],
@@ -302,6 +303,7 @@
   'debug-liveedit-stack-padding': [SKIP],
   'debug-liveedit-restart-frame': [SKIP],
   'debug-liveedit-double-call': [SKIP],
+  'harmony/generators-debug-liveedit': [SKIP],
 
   # Currently always deopt on minus zero
   'math-floor-of-div-minus-zero': [SKIP],
@@ -353,6 +355,7 @@
   'debug-liveedit-stack-padding': [SKIP],
   'debug-liveedit-restart-frame': [SKIP],
   'debug-liveedit-double-call': [SKIP],
+  'harmony/generators-debug-liveedit': [SKIP],
 
   # Currently always deopt on minus zero
   'math-floor-of-div-minus-zero': [SKIP],
@@ -373,6 +376,7 @@
   'debug-liveedit-stack-padding': [SKIP],
   'debug-liveedit-restart-frame': [SKIP],
   'debug-liveedit-double-call': [SKIP],
+  'harmony/generators-debug-liveedit': [SKIP],
 
   # NaCl builds have problems with this test since Pepper_28.
   # V8 Issue 2786
diff --git a/test/mjsunit/regress/regress-373283.js b/test/mjsunit/regress/regress-373283.js
new file mode 100644
index 0000000..20cee4d
--- /dev/null
+++ b/test/mjsunit/regress/regress-373283.js
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+// Flags:  --allow-natives-syntax --deopt-every-n-times=1
+
+function __f_0() {
+  var x = [];
+  x[21] = 1;
+  x[21] + 0;
+}
+
+for (var i = 0; i < 3; i++) __f_0();
+%OptimizeFunctionOnNextCall(__f_0);
+for (var i = 0; i < 10; i++) __f_0();
+%OptimizeFunctionOnNextCall(__f_0);
+__f_0();
+%GetScript("foo");
diff --git a/test/mjsunit/runtime-gen/getlocalelementnames.js b/test/mjsunit/runtime-gen/getownelementnames.js
similarity index 87%
rename from test/mjsunit/runtime-gen/getlocalelementnames.js
rename to test/mjsunit/runtime-gen/getownelementnames.js
index cf0447d..3f02cba 100644
--- a/test/mjsunit/runtime-gen/getlocalelementnames.js
+++ b/test/mjsunit/runtime-gen/getownelementnames.js
@@ -2,4 +2,4 @@
 // AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
 // Flags: --allow-natives-syntax --harmony
 var _obj = new Object();
-%GetLocalElementNames(_obj);
+%GetOwnElementNames(_obj);
diff --git a/test/mjsunit/runtime-gen/getlocalpropertynames.js b/test/mjsunit/runtime-gen/getownpropertynames.js
similarity index 83%
rename from test/mjsunit/runtime-gen/getlocalpropertynames.js
rename to test/mjsunit/runtime-gen/getownpropertynames.js
index 2a93868..f05268f 100644
--- a/test/mjsunit/runtime-gen/getlocalpropertynames.js
+++ b/test/mjsunit/runtime-gen/getownpropertynames.js
@@ -3,4 +3,4 @@
 // Flags: --allow-natives-syntax --harmony
 var _obj = new Object();
 var _filter_value = 1;
-%GetLocalPropertyNames(_obj, _filter_value);
+%GetOwnPropertyNames(_obj, _filter_value);
diff --git a/test/mjsunit/runtime-gen/haslocalproperty.js b/test/mjsunit/runtime-gen/hasownproperty.js
similarity index 86%
rename from test/mjsunit/runtime-gen/haslocalproperty.js
rename to test/mjsunit/runtime-gen/hasownproperty.js
index 066e6d1..7be0a65 100644
--- a/test/mjsunit/runtime-gen/haslocalproperty.js
+++ b/test/mjsunit/runtime-gen/hasownproperty.js
@@ -3,4 +3,4 @@
 // Flags: --allow-natives-syntax --harmony
 var _object = new Object();
 var _key = "name";
-%HasLocalProperty(_object, _key);
+%HasOwnProperty(_object, _key);
diff --git a/test/mjsunit/runtime-gen/localkeys.js b/test/mjsunit/runtime-gen/ownkeys.js
similarity index 89%
rename from test/mjsunit/runtime-gen/localkeys.js
rename to test/mjsunit/runtime-gen/ownkeys.js
index 0186177..7e4220d 100644
--- a/test/mjsunit/runtime-gen/localkeys.js
+++ b/test/mjsunit/runtime-gen/ownkeys.js
@@ -2,4 +2,4 @@
 // AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
 // Flags: --allow-natives-syntax --harmony
 var _raw_object = new Object();
-%LocalKeys(_raw_object);
+%OwnKeys(_raw_object);
diff --git a/test/mjsunit/tools/tickprocessor-test.default b/test/mjsunit/tools/tickprocessor-test.default
index 702f4bc..8ab17c3 100644
--- a/test/mjsunit/tools/tickprocessor-test.default
+++ b/test/mjsunit/tools/tickprocessor-test.default
@@ -16,7 +16,7 @@
  [C++]:
    ticks  total  nonlib   name
       2   15.4%   22.2%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
-      1    7.7%   11.1%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    7.7%   11.1%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1    7.7%   11.1%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
       1    7.7%   11.1%  exp
 
@@ -38,7 +38,7 @@
       2  100.0%    LazyCompile: exp native math.js:41
       2  100.0%      Script: exp.js
 
-      1    7.7%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    7.7%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1  100.0%    Script: exp.js
 
       1    7.7%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/test/mjsunit/tools/tickprocessor-test.ignore-unknown b/test/mjsunit/tools/tickprocessor-test.ignore-unknown
index 306d646..677da9c 100644
--- a/test/mjsunit/tools/tickprocessor-test.ignore-unknown
+++ b/test/mjsunit/tools/tickprocessor-test.ignore-unknown
@@ -12,7 +12,7 @@
  [C++]:
    ticks  total  nonlib   name
       2   18.2%   28.6%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
-      1    9.1%   14.3%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    9.1%   14.3%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1    9.1%   14.3%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
       1    9.1%   14.3%  exp
 
@@ -34,7 +34,7 @@
       2  100.0%    LazyCompile: exp native math.js:41
       2  100.0%      Script: exp.js
 
-      1    9.1%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    9.1%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1  100.0%    Script: exp.js
 
       1    9.1%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/test/mjsunit/tools/tickprocessor-test.separate-ic b/test/mjsunit/tools/tickprocessor-test.separate-ic
index 3a2041b..2d49f73 100644
--- a/test/mjsunit/tools/tickprocessor-test.separate-ic
+++ b/test/mjsunit/tools/tickprocessor-test.separate-ic
@@ -18,7 +18,7 @@
  [C++]:
    ticks  total  nonlib   name
       2   15.4%   22.2%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
-      1    7.7%   11.1%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    7.7%   11.1%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1    7.7%   11.1%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
       1    7.7%   11.1%  exp
 
@@ -40,7 +40,7 @@
       2  100.0%    LazyCompile: exp native math.js:41
       2  100.0%      Script: exp.js
 
-      1    7.7%  v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1    7.7%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
       1  100.0%    Script: exp.js
 
       1    7.7%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/test/mjsunit/tools/tickprocessor.js b/test/mjsunit/tools/tickprocessor.js
index 626929d..78a7c43 100644
--- a/test/mjsunit/tools/tickprocessor.js
+++ b/test/mjsunit/tools/tickprocessor.js
@@ -311,7 +311,7 @@
     name, startAddr, endAddr, symbolAdder) {
   var symbols = {
     'shell':
-        [['v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
+        [['v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
          ['v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)', 0x080f8210, 0x080f8800],
          ['v8::internal::Runtime_Math_exp(v8::internal::Arguments)', 0x08123b20, 0x08123b80]],
     '/lib32/libm-2.7.so':
diff --git a/test/webkit/fast/js/Object-defineProperty-expected.txt b/test/webkit/fast/js/Object-defineProperty-expected.txt
index 7a303f2..118f9dd 100644
--- a/test/webkit/fast/js/Object-defineProperty-expected.txt
+++ b/test/webkit/fast/js/Object-defineProperty-expected.txt
@@ -142,8 +142,8 @@
 PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false}), 'foo').writable is false
 PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: false}), 'foo').writable is false
 PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: true}), 'foo').writable is true
-FAIL var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; should be false. Was true.
-FAIL 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; should throw an exception. Was true.
+PASS var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; is false
+PASS 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; threw exception TypeError: Cannot assign to read only property 'length' of [object Array].
 PASS var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; is 42
 PASS 'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; threw exception TypeError: Cannot assign to read only property '0' of [object Array].
 PASS var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; is undefined.
diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py
index 96d4b35..d91986b 100755
--- a/tools/generate-runtime-tests.py
+++ b/tools/generate-runtime-tests.py
@@ -51,7 +51,7 @@
 EXPECTED_FUZZABLE_COUNT = 326
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
-EXPECTED_BUILTINS_COUNT = 824
+EXPECTED_BUILTINS_COUNT = 781
 
 
 # Don't call these at all.
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 1383a60..37b8650 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -46,16 +46,13 @@
           # The dependency on v8_base should come from a transitive
           # dependency however the Android toolchain requires libv8_base.a
           # to appear before libv8_snapshot.a so it's listed explicitly.
-          'dependencies': ['v8_base.<(v8_target_arch)', 'v8_snapshot'],
+          'dependencies': ['v8_base', 'v8_snapshot'],
         },
         {
           # The dependency on v8_base should come from a transitive
           # dependency however the Android toolchain requires libv8_base.a
           # to appear before libv8_snapshot.a so it's listed explicitly.
-          'dependencies': [
-            'v8_base.<(v8_target_arch)',
-            'v8_nosnapshot.<(v8_target_arch)',
-          ],
+          'dependencies': ['v8_base', 'v8_nosnapshot'],
         }],
         ['component=="shared_library"', {
           'type': '<(component)',
@@ -112,14 +109,14 @@
         ['want_separate_host_toolset==1', {
           'toolsets': ['host', 'target'],
           'dependencies': [
-            'mksnapshot.<(v8_target_arch)#host',
+            'mksnapshot#host',
             'js2c#host',
             'generate_trig_table#host',
           ],
         }, {
           'toolsets': ['target'],
           'dependencies': [
-            'mksnapshot.<(v8_target_arch)',
+            'mksnapshot',
             'js2c',
             'generate_trig_table',
           ],
@@ -138,7 +135,7 @@
         }],
       ],
       'dependencies': [
-        'v8_base.<(v8_target_arch)',
+        'v8_base',
       ],
       'include_dirs+': [
         '../../src',
@@ -153,7 +150,7 @@
         {
           'action_name': 'run_mksnapshot',
           'inputs': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot.<(v8_target_arch)<(EXECUTABLE_SUFFIX)',
+            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
           ],
           'outputs': [
             '<(INTERMEDIATE_DIR)/snapshot.cc',
@@ -178,10 +175,10 @@
       ],
     },
     {
-      'target_name': 'v8_nosnapshot.<(v8_target_arch)',
+      'target_name': 'v8_nosnapshot',
       'type': 'static_library',
       'dependencies': [
-        'v8_base.<(v8_target_arch)',
+        'v8_base',
       ],
       'include_dirs+': [
         '../../src',
@@ -235,7 +232,7 @@
       ]
     },
     {
-      'target_name': 'v8_base.<(v8_target_arch)',
+      'target_name': 'v8_base',
       'type': 'static_library',
       'dependencies': [
         'v8_libbase.<(v8_target_arch)',
@@ -1176,12 +1173,9 @@
         ]
     },
     {
-      'target_name': 'mksnapshot.<(v8_target_arch)',
+      'target_name': 'mksnapshot',
       'type': 'executable',
-      'dependencies': [
-        'v8_base.<(v8_target_arch)',
-        'v8_nosnapshot.<(v8_target_arch)',
-      ],
+      'dependencies': ['v8_base', 'v8_nosnapshot'],
       'include_dirs+': [
         '../../src',
       ],