Version 3.17.16

Stack trace API: poison stack frames below the first strict mode frame. (issue 2564)

Made Isolate::GetHeapStatistics robust against half-initialized isolates (Chromium issue 2591).

Finished implementation of ES6 symbols aka. private names (issue 2158).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@14137 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 64c0022..65663ba 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -477,14 +477,6 @@
 }
 
 
-#ifdef DEBUG
-void ImplementationUtilities::ZapHandleRange(i::Object** begin,
-                                             i::Object** end) {
-  i::HandleScope::ZapRange(begin, end);
-}
-#endif
-
-
 void V8::SetFlagsFromString(const char* str, int length) {
   i::FlagList::SetFlagsFromString(str, length);
 }
@@ -706,7 +698,7 @@
     i::HandleScope::DeleteExtensions(isolate_);
   }
 
-#ifdef DEBUG
+#ifdef ENABLE_EXTRA_CHECKS
   i::HandleScope::ZapRange(prev_next_, prev_limit_);
 #endif
 }
@@ -3197,7 +3189,7 @@
   i::Handle<i::Object> name(self->class_name(), isolate);
 
   // Native implementation of Object.prototype.toString (v8natives.js):
-  //   var c = %ClassOf(this);
+  //   var c = %_ClassOf(this);
   //   if (c === 'Arguments') c  = 'Object';
   //   return "[object " + c + "]";
 
@@ -5807,6 +5799,20 @@
 }
 
 
+HeapProfiler* Isolate::GetHeapProfiler() {
+  i::HeapProfiler* heap_profiler =
+      reinterpret_cast<i::Isolate*>(this)->heap_profiler();
+  return reinterpret_cast<HeapProfiler*>(heap_profiler);
+}
+
+
+CpuProfiler* Isolate::GetCpuProfiler() {
+  i::CpuProfiler* cpu_profiler =
+      reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
+  return reinterpret_cast<CpuProfiler*>(cpu_profiler);
+}
+
+
 void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
@@ -5979,6 +5985,14 @@
 
 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  if (!isolate->IsInitialized()) {
+    heap_statistics->total_heap_size_ = 0;
+    heap_statistics->total_heap_size_executable_ = 0;
+    heap_statistics->total_physical_size_ = 0;
+    heap_statistics->used_heap_size_ = 0;
+    heap_statistics->heap_size_limit_ = 0;
+    return;
+  }
   i::Heap* heap = isolate->heap();
   heap_statistics->total_heap_size_ = heap->CommittedMemory();
   heap_statistics->total_heap_size_executable_ =
@@ -6454,6 +6468,11 @@
 }
 
 
+unsigned CpuProfileNode::GetNodeId() const {
+  return reinterpret_cast<const i::ProfileNode*>(this)->id();
+}
+
+
 int CpuProfileNode::GetChildrenCount() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
@@ -6473,11 +6492,12 @@
 void CpuProfile::Delete() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::Delete");
-  i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
-  if (i::CpuProfiler::GetProfilesCount() == 0 &&
-      !i::CpuProfiler::HasDetachedProfiles()) {
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
+  if (profiler->GetProfilesCount() == 0 && !profiler->HasDetachedProfiles()) {
     // If this was the last profile, clean up all accessory data as well.
-    i::CpuProfiler::DeleteAllProfiles();
+    profiler->DeleteAllProfiles();
   }
 }
 
@@ -6506,10 +6526,28 @@
 }
 
 
+const CpuProfileNode* CpuProfile::GetSample(int index) const {
+  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
+  return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
+}
+
+
+int CpuProfile::GetSamplesCount() const {
+  return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
+}
+
+
 int CpuProfiler::GetProfilesCount() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
-  return i::CpuProfiler::GetProfilesCount();
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  return profiler->GetProfilesCount();
+}
+
+
+int CpuProfiler::GetProfileCount() {
+  return reinterpret_cast<i::CpuProfiler*>(this)->GetProfilesCount();
 }
 
 
@@ -6517,8 +6555,19 @@
                                           Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::GetProfile(
+      profiler->GetProfile(
+          security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
+          index));
+}
+
+
+const CpuProfile* CpuProfiler::GetCpuProfile(int index,
+                                             Handle<Value> security_token) {
+  return reinterpret_cast<const CpuProfile*>(
+      reinterpret_cast<i::CpuProfiler*>(this)->GetProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           index));
 }
@@ -6528,17 +6577,36 @@
                                            Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::FindProfile(
+      profiler->FindProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           uid));
 }
 
 
-void CpuProfiler::StartProfiling(Handle<String> title) {
+const CpuProfile* CpuProfiler::FindCpuProfile(unsigned uid,
+                                              Handle<Value> security_token) {
+  return reinterpret_cast<const CpuProfile*>(
+      reinterpret_cast<i::CpuProfiler*>(this)->FindProfile(
+          security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
+          uid));
+}
+
+
+void CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
-  i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->StartProfiling(*Utils::OpenHandle(*title), record_samples);
+}
+
+
+void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
+  reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
+      *Utils::OpenHandle(*title), record_samples);
 }
 
 
@@ -6546,8 +6614,19 @@
                                              Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::StopProfiling(
+      profiler->StopProfiling(
+          security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
+          *Utils::OpenHandle(*title)));
+}
+
+
+const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title,
+                                                Handle<Value> security_token) {
+  return reinterpret_cast<const CpuProfile*>(
+      reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           *Utils::OpenHandle(*title)));
 }
@@ -6556,7 +6635,14 @@
 void CpuProfiler::DeleteAllProfiles() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
-  i::CpuProfiler::DeleteAllProfiles();
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->DeleteAllProfiles();
+}
+
+
+void CpuProfiler::DeleteAllCpuProfiles() {
+  reinterpret_cast<i::CpuProfiler*>(this)->DeleteAllProfiles();
 }
 
 
@@ -6679,11 +6765,11 @@
 void HeapSnapshot::Delete() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
-  if (i::HeapProfiler::GetSnapshotsCount() > 1) {
+  if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
     ToInternal(this)->Delete();
   } else {
     // If this is the last snapshot, clean up all accessory data as well.
-    i::HeapProfiler::DeleteAllSnapshots();
+    isolate->heap_profiler()->DeleteAllSnapshots();
   }
 }
 
@@ -6691,7 +6777,7 @@
 HeapSnapshot::Type HeapSnapshot::GetType() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
-  return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
+  return kFull;
 }
 
 
@@ -6768,7 +6854,12 @@
 int HeapProfiler::GetSnapshotsCount() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
-  return i::HeapProfiler::GetSnapshotsCount();
+  return isolate->heap_profiler()->GetSnapshotsCount();
+}
+
+
+int HeapProfiler::GetSnapshotCount() {
+  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
 }
 
 
@@ -6776,7 +6867,13 @@
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
   return reinterpret_cast<const HeapSnapshot*>(
-      i::HeapProfiler::GetSnapshot(index));
+      isolate->heap_profiler()->GetSnapshot(index));
+}
+
+
+const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
+  return reinterpret_cast<const HeapSnapshot*>(
+      reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
 }
 
 
@@ -6784,7 +6881,13 @@
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
   return reinterpret_cast<const HeapSnapshot*>(
-      i::HeapProfiler::FindSnapshot(uid));
+      isolate->heap_profiler()->FindSnapshot(uid));
+}
+
+
+const HeapSnapshot* HeapProfiler::FindHeapSnapshot(unsigned uid) {
+  return reinterpret_cast<const HeapSnapshot*>(
+      reinterpret_cast<i::HeapProfiler*>(this)->FindSnapshot(uid));
 }
 
 
@@ -6792,7 +6895,13 @@
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotObjectId");
   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
-  return i::HeapProfiler::GetSnapshotObjectId(obj);
+  return isolate->heap_profiler()->GetSnapshotObjectId(obj);
+}
+
+
+SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(*value);
+  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
 }
 
 
@@ -6802,45 +6911,67 @@
                                                ObjectNameResolver* resolver) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
-  i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
-  switch (type) {
-    case HeapSnapshot::kFull:
-      internal_type = i::HeapSnapshot::kFull;
-      break;
-    default:
-      UNREACHABLE();
-  }
   return reinterpret_cast<const HeapSnapshot*>(
-      i::HeapProfiler::TakeSnapshot(
-          *Utils::OpenHandle(*title), internal_type, control, resolver));
+      isolate->heap_profiler()->TakeSnapshot(
+          *Utils::OpenHandle(*title), control, resolver));
+}
+
+
+const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
+    Handle<String> title,
+    ActivityControl* control,
+    ObjectNameResolver* resolver) {
+  return reinterpret_cast<const HeapSnapshot*>(
+      reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
+          *Utils::OpenHandle(*title), control, resolver));
 }
 
 
 void HeapProfiler::StartHeapObjectsTracking() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::StartHeapObjectsTracking");
-  i::HeapProfiler::StartHeapObjectsTracking();
+  isolate->heap_profiler()->StartHeapObjectsTracking();
+}
+
+
+void HeapProfiler::StartTrackingHeapObjects() {
+  reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking();
 }
 
 
 void HeapProfiler::StopHeapObjectsTracking() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::StopHeapObjectsTracking");
-  i::HeapProfiler::StopHeapObjectsTracking();
+  isolate->heap_profiler()->StopHeapObjectsTracking();
+}
+
+
+void HeapProfiler::StopTrackingHeapObjects() {
+  reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
 }
 
 
 SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::PushHeapObjectsStats");
-  return i::HeapProfiler::PushHeapObjectsStats(stream);
+  return isolate->heap_profiler()->PushHeapObjectsStats(stream);
+}
+
+
+SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
+  return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
 }
 
 
 void HeapProfiler::DeleteAllSnapshots() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
-  i::HeapProfiler::DeleteAllSnapshots();
+  isolate->heap_profiler()->DeleteAllSnapshots();
+}
+
+
+void HeapProfiler::DeleteAllHeapSnapshots() {
+  reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
 }
 
 
@@ -6851,6 +6982,13 @@
 }
 
 
+void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
+                                               WrapperInfoCallback callback) {
+  reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
+                                                               callback);
+}
+
+
 int HeapProfiler::GetPersistentHandleCount() {
   i::Isolate* isolate = i::Isolate::Current();
   return isolate->global_handles()->NumberOfGlobalHandles();
@@ -6858,7 +6996,13 @@
 
 
 size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
-  return i::HeapProfiler::GetMemorySizeUsedByProfiler();
+  return i::Isolate::Current()->heap_profiler()->GetMemorySizeUsedByProfiler();
+}
+
+
+size_t HeapProfiler::GetProfilerMemorySize() {
+  return reinterpret_cast<i::HeapProfiler*>(this)->
+      GetMemorySizeUsedByProfiler();
 }
 
 
@@ -7053,7 +7197,7 @@
   isolate_->UnlinkDeferredHandles(this);
 
   for (int i = 0; i < blocks_.length(); i++) {
-#ifdef DEBUG
+#ifdef ENABLE_EXTRA_CHECKS
     HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
 #endif
     isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
diff --git a/src/api.h b/src/api.h
index 8628b2a..d73646d 100644
--- a/src/api.h
+++ b/src/api.h
@@ -572,8 +572,8 @@
 #endif
 
     blocks_.RemoveLast();
-#ifdef DEBUG
-    v8::ImplementationUtilities::ZapHandleRange(block_start, block_limit);
+#ifdef ENABLE_EXTRA_CHECKS
+    internal::HandleScope::ZapRange(block_start, block_limit);
 #endif
     if (spare_ != NULL) {
       DeleteArray(spare_);
diff --git a/src/apiutils.h b/src/apiutils.h
index 71c0e1c..9831f08 100644
--- a/src/apiutils.h
+++ b/src/apiutils.h
@@ -67,10 +67,6 @@
   // Introduce an alias for the handle scope data to allow non-friends
   // to access the HandleScope data.
   typedef v8::HandleScope::Data HandleScopeData;
-
-#ifdef DEBUG
-  static void ZapHandleRange(internal::Object** begin, internal::Object** end);
-#endif
 };
 
 }  // namespace v8
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 2946b35..ebb9e12 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -221,13 +221,12 @@
   __ add(elements_array_end,
          elements_array_end,
          Operand(array_size, ASR, kSmiTagSize));
-  __ AllocateInNewSpace(
-      elements_array_end,
-      result,
-      scratch1,
-      scratch2,
-      gc_required,
-      static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
+  __ Allocate(elements_array_end,
+              result,
+              scratch1,
+              scratch2,
+              gc_required,
+              static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
@@ -874,7 +873,7 @@
       // r1: constructor function
       // r2: initial map
       __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
-      __ AllocateInNewSpace(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS);
+      __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS);
 
       // Allocated the JSObject, now initialize the fields. Map is set to
       // initial map and properties and elements are set to empty fixed array.
@@ -949,7 +948,7 @@
       // r4: JSObject
       // r5: start of next object
       __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize));
-      __ AllocateInNewSpace(
+      __ Allocate(
           r0,
           r5,
           r6,
@@ -1105,10 +1104,6 @@
     __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE);
     __ b(ge, &exit);
 
-    // Symbols are "objects".
-    __ CompareInstanceType(r1, r3, SYMBOL_TYPE);
-    __ b(eq, &exit);
-
     // Throw away the result of the constructor invocation and use the
     // on-stack receiver as the result.
     __ bind(&use_receiver);
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index b2b8d4b..d982f27 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -95,7 +95,7 @@
   // stack param count needs (constructor pointer, and single argument)
   descriptor->stack_parameter_count_ = &r0;
   descriptor->register_params_ = registers;
-  descriptor->extra_expression_stack_count_ = 1;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
       FUNCTION_ADDR(ArrayConstructor_StubFailure);
 }
@@ -2634,8 +2634,8 @@
                                       OverwriteMode mode) {
   Register left = r1;
   Register right = r0;
-  Register scratch1 = r7;
-  Register scratch2 = r9;
+  Register scratch1 = r6;
+  Register scratch2 = r7;
   Register scratch3 = r4;
 
   ASSERT(smi_operands || (not_numbers != NULL));
@@ -2650,7 +2650,7 @@
     __ JumpIfNotSmi(right, miss);
   }
 
-  Register heap_number_map = r6;
+  Register heap_number_map = r9;
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
 
   switch (op) {
@@ -4488,35 +4488,6 @@
 }
 
 
-void ArrayLengthStub::Generate(MacroAssembler* masm) {
-  Label miss;
-  Register receiver;
-  if (kind() == Code::KEYED_LOAD_IC) {
-    // ----------- S t a t e -------------
-    //  -- lr    : return address
-    //  -- r0    : key
-    //  -- r1    : receiver
-    // -----------------------------------
-    __ cmp(r0, Operand(masm->isolate()->factory()->length_string()));
-    __ b(ne, &miss);
-    receiver = r1;
-  } else {
-    ASSERT(kind() == Code::LOAD_IC);
-    // ----------- S t a t e -------------
-    //  -- r2    : name
-    //  -- lr    : return address
-    //  -- r0    : receiver
-    //  -- sp[0] : receiver
-    // -----------------------------------
-    receiver = r0;
-  }
-
-  StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss);
-  __ bind(&miss);
-  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
-}
-
-
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver;
@@ -4791,7 +4762,7 @@
   __ add(r9, r9, Operand(Heap::kArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
-  __ AllocateInNewSpace(r9, r0, r3, r4, &runtime, TAG_OBJECT);
+  __ Allocate(r9, r0, r3, r4, &runtime, TAG_OBJECT);
 
   // r0 = address of new object(s) (tagged)
   // r2 = argument count (tagged)
@@ -4967,13 +4938,8 @@
   __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(r1,
-                        r0,
-                        r2,
-                        r3,
-                        &runtime,
-                        static_cast<AllocationFlags>(TAG_OBJECT |
-                                                     SIZE_IN_WORDS));
+  __ Allocate(r1, r0, r2, r3, &runtime,
+              static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
 
   // Get the arguments boilerplate from the current native context.
   __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
@@ -5477,7 +5443,7 @@
       (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
   __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize));
   __ add(r2, r5, Operand(objects_size));
-  __ AllocateInNewSpace(
+  __ Allocate(
       r2,  // In: Size, in words.
       r0,  // Out: Start of allocation (tagged).
       r3,  // Scratch register.
@@ -7996,6 +7962,9 @@
   int parameter_count_offset =
       StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
   __ ldr(r1, MemOperand(fp, parameter_count_offset));
+  if (function_mode_ == JS_FUNCTION_STUB_MODE) {
+    __ add(r1, r1, Operand(1));
+  }
   masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
   __ mov(r1, Operand(r1, LSL, kPointerSizeLog2));
   __ add(sp, sp, r1);
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index b8f8f6d..1c82946 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -207,7 +207,7 @@
   // Use lr as a temporary register.
   __ mov(lr, Operand(r5, LSL, 2));
   __ add(lr, lr, Operand(FixedDoubleArray::kHeaderSize));
-  __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, DOUBLE_ALIGNMENT);
+  __ Allocate(lr, r6, r7, r9, &gc_required, DOUBLE_ALIGNMENT);
   // r6: destination FixedDoubleArray, not tagged as heap object.
 
   // Set destination FixedDoubleArray's length and map.
@@ -348,7 +348,7 @@
   // Allocate new FixedArray.
   __ mov(r0, Operand(FixedDoubleArray::kHeaderSize));
   __ add(r0, r0, Operand(r5, LSL, 1));
-  __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
+  __ Allocate(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
   // r6: destination FixedArray, not tagged as heap object
   // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex);
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 1df1649..6086645 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -2764,28 +2764,6 @@
 }
 
 
-void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  ASSERT(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  __ JumpIfSmi(r0, if_false);
-  __ CompareObjectType(r0, r1, r2, SYMBOL_TYPE);
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  Split(eq, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -4292,6 +4270,10 @@
     __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
     __ tst(r1, Operand(1 << Map::kIsUndetectable));
     Split(eq, if_true, if_false, fall_through);
+  } else if (check->Equals(isolate()->heap()->symbol_string())) {
+    __ JumpIfSmi(r0, if_false);
+    __ CompareObjectType(r0, r0, r1, SYMBOL_TYPE);
+    Split(eq, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->boolean_string())) {
     __ CompareRoot(r0, Heap::kTrueValueRootIndex);
     __ b(eq, if_true);
@@ -4324,10 +4306,6 @@
       __ CompareRoot(r0, Heap::kNullValueRootIndex);
       __ b(eq, if_true);
     }
-    if (FLAG_harmony_symbols) {
-      __ CompareObjectType(r0, r0, r1, SYMBOL_TYPE);
-      __ b(eq, if_true);
-    }
     // Check for JS objects => true.
     __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
     __ b(lt, if_false);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 38884ce..f2b65ef 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -871,6 +871,35 @@
   LInstruction* instr = current->CompileToLithium(this);
 
   if (instr != NULL) {
+#if DEBUG
+    // Make sure that the lithium instruction has either no fixed register
+    // constraints in temps or the result OR no uses that are only used at
+    // start. If this invariant doesn't hold, the register allocator can decide
+    // to insert a split of a range immediately before the instruction due to an
+    // already allocated register needing to be used for the instruction's fixed
+    // register constraint. In this case, The register allocator won't see an
+    // interference between the split child and the use-at-start (it would if
+    // the it was just a plain use), so it is free to move the split child into
+    // the same register that is used for the use-at-start.
+    // See https://code.google.com/p/chromium/issues/detail?id=201590
+    if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+      int fixed = 0;
+      int used_at_start = 0;
+      for (UseIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->IsUsedAtStart()) ++used_at_start;
+      }
+      if (instr->Output() != NULL) {
+        if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
+      }
+      for (TempIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->HasFixedPolicy()) ++fixed;
+      }
+      ASSERT(fixed == 0 || used_at_start == 0);
+    }
+#endif
+
     if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
       instr = AssignPointerMap(instr);
     }
@@ -1115,7 +1144,7 @@
     LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp);
     return DefineFixedDouble(result, d2);
   } else {
-    LOperand* input = UseRegisterAtStart(instr->value());
+    LOperand* input = UseRegister(instr->value());
 
     LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL;
     LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp);
@@ -1711,12 +1740,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
-  LOperand* array = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LJSArrayLength(array));
-}
-
-
 LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
     HFixedArrayBaseLength* instr) {
   LOperand* array = UseRegisterAtStart(instr->value());
@@ -1823,11 +1846,13 @@
       return AssignEnvironment(DefineAsRegister(res));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = UseRegisterAtStart(instr->value());
+      LOperand* value = NULL;
       LInstruction* res = NULL;
       if (instr->value()->type().IsSmi()) {
+        value = UseRegisterAtStart(instr->value());
         res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
+        value = UseRegister(instr->value());
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                       : NULL;
@@ -2205,7 +2230,7 @@
     LOperand* new_map_reg = TempRegister();
     LTransitionElementsKind* result =
         new(zone()) LTransitionElementsKind(object, new_map_reg, NULL);
-    return DefineSameAsFirst(result);
+    return result;
   } else if (FLAG_compiled_transitions) {
     LTransitionElementsKind* result =
         new(zone()) LTransitionElementsKind(object, NULL, NULL);
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index f49e8ce..207faf4 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -120,7 +120,6 @@
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
-  V(JSArrayLength)                              \
   V(Label)                                      \
   V(LazyBailout)                                \
   V(LoadContextSlot)                            \
@@ -1165,19 +1164,6 @@
 };
 
 
-class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LJSArrayLength(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  LOperand* value() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
-  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
-};
-
-
 class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LFixedArrayBaseLength(LOperand* value) {
@@ -2114,7 +2100,7 @@
 };
 
 
-class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
+class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> {
  public:
   LTransitionElementsKind(LOperand* object,
                           LOperand* new_map_temp,
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 8040791..7bb3535 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1918,13 +1918,6 @@
 }
 
 
-void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
-  Register result = ToRegister(instr->result());
-  Register array = ToRegister(instr->value());
-  __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
-}
-
-
 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
   Register result = ToRegister(instr->result());
   Register array = ToRegister(instr->value());
@@ -2301,6 +2294,12 @@
         __ bind(&not_string);
       }
 
+      if (expected.Contains(ToBooleanStub::SYMBOL)) {
+        // Symbol value -> true.
+        __ CompareInstanceType(map, ip, SYMBOL_TYPE);
+        __ b(eq, true_label);
+      }
+
       if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
         CpuFeatureScope scope(masm(), VFP2);
         // heap number -> false iff +0, -0, or NaN.
@@ -4897,10 +4896,11 @@
 
 // Convert unsigned integer with specified number of leading zeroes in binary
 // representation to IEEE 754 double.
-// Integer to convert is passed in register hiword.
+// Integer to convert is passed in register src.
 // Resulting double is returned in registers hiword:loword.
 // This functions does not work correctly for 0.
 static void GenerateUInt2Double(MacroAssembler* masm,
+                                Register src,
                                 Register hiword,
                                 Register loword,
                                 Register scratch,
@@ -4914,13 +4914,13 @@
       kBitsPerInt - mantissa_shift_for_hi_word;
   masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
   if (mantissa_shift_for_hi_word > 0) {
-    masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word));
+    masm->mov(loword, Operand(src, LSL, mantissa_shift_for_lo_word));
     masm->orr(hiword, scratch,
-              Operand(hiword, LSR, mantissa_shift_for_hi_word));
+              Operand(src, LSR, mantissa_shift_for_hi_word));
   } else {
     masm->mov(loword, Operand::Zero());
     masm->orr(hiword, scratch,
-              Operand(hiword, LSL, -mantissa_shift_for_hi_word));
+              Operand(src, LSL, -mantissa_shift_for_hi_word));
   }
 
   // If least significant bit of biased exponent was not 1 it was corrupted
@@ -4969,17 +4969,17 @@
       __ vmov(flt_scratch, src);
       __ vcvt_f64_u32(dbl_scratch, flt_scratch);
     } else {
-      Label no_leading_zero, done;
+      Label no_leading_zero, convert_done;
       __ tst(src, Operand(0x80000000));
       __ b(ne, &no_leading_zero);
 
       // Integer has one leading zeros.
-      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1);
-      __ b(&done);
+      GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1);
+      __ b(&convert_done);
 
       __ bind(&no_leading_zero);
-      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0);
-      __ b(&done);
+      GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0);
+      __ bind(&convert_done);
     }
   }
 
@@ -4996,10 +4996,18 @@
   // TODO(3095996): Put a valid pointer value in the stack slot where the result
   // register is stored, as this register is in the pointer map, but contains an
   // integer value.
+  if (!CpuFeatures::IsSupported(VFP2)) {
+    // Preserve sfpd_lo.
+    __ mov(r9, sfpd_lo);
+  }
   __ mov(ip, Operand::Zero());
   __ StoreToSafepointRegisterSlot(ip, dst);
   CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
   __ Move(dst, r0);
+  if (!CpuFeatures::IsSupported(VFP2)) {
+    // Restore sfpd_lo.
+    __ mov(sfpd_lo, r9);
+  }
   __ sub(dst, dst, Operand(kHeapObjectTag));
 
   // Done. Put the value in dbl_scratch into the value of the allocated heap
@@ -5671,12 +5679,12 @@
     __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
-    __ AllocateInNewSpace(size,
-                          result,
-                          scratch,
-                          scratch2,
-                          deferred->entry(),
-                          flags);
+    __ Allocate(size,
+                result,
+                scratch,
+                scratch2,
+                deferred->entry(),
+                flags);
   }
 
   __ bind(deferred->exit());
@@ -6074,6 +6082,11 @@
     __ tst(ip, Operand(1 << Map::kIsUndetectable));
     final_branch_condition = eq;
 
+  } else if (type_name->Equals(heap()->symbol_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ CompareObjectType(input, input, scratch, SYMBOL_TYPE);
+    final_branch_condition = eq;
+
   } else if (type_name->Equals(heap()->boolean_string())) {
     __ CompareRoot(input, Heap::kTrueValueRootIndex);
     __ b(eq, true_label);
@@ -6108,15 +6121,8 @@
       __ CompareRoot(input, Heap::kNullValueRootIndex);
       __ b(eq, true_label);
     }
-    if (FLAG_harmony_symbols) {
-      __ CompareObjectType(input, input, scratch, SYMBOL_TYPE);
-      __ b(eq, true_label);
-      __ CompareInstanceType(input, scratch,
-                             FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    } else {
-      __ CompareObjectType(input, input, scratch,
-                           FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    }
+    __ CompareObjectType(input, input, scratch,
+                         FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
     __ b(lt, false_label);
     __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
     __ b(gt, false_label);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index e0e77cf..bacf570 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -708,15 +708,14 @@
                           const MemOperand& src, Condition cond) {
   ASSERT(src.rm().is(no_reg));
   ASSERT(!dst1.is(lr));  // r14.
-  ASSERT_EQ(0, dst1.code() % 2);
-  ASSERT_EQ(dst1.code() + 1, dst2.code());
 
   // V8 does not use this addressing mode, so the fallback code
   // below doesn't support it yet.
   ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
 
   // Generate two ldr instructions if ldrd is not available.
-  if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) {
+  if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
+      (dst1.code() % 2 == 0) && (dst1.code() + 1 == dst2.code())) {
     CpuFeatureScope scope(this, ARMv7);
     ldrd(dst1, dst2, src, cond);
   } else {
@@ -750,15 +749,14 @@
                           const MemOperand& dst, Condition cond) {
   ASSERT(dst.rm().is(no_reg));
   ASSERT(!src1.is(lr));  // r14.
-  ASSERT_EQ(0, src1.code() % 2);
-  ASSERT_EQ(src1.code() + 1, src2.code());
 
   // V8 does not use this addressing mode, so the fallback code
   // below doesn't support it yet.
   ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
 
   // Generate two str instructions if strd is not available.
-  if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) {
+  if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() &&
+      (src1.code() % 2 == 0) && (src1.code() + 1 == src2.code())) {
     CpuFeatureScope scope(this, ARMv7);
     strd(src1, src2, dst, cond);
   } else {
@@ -1671,13 +1669,12 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(Register object_size,
-                                        Register result,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
+void MacroAssembler::Allocate(Register object_size,
+                              Register result,
+                              Register scratch1,
+                              Register scratch2,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1703,20 +1700,20 @@
   // The values must be adjacent in memory to allow the use of LDM.
   // Also, assert that the registers are numbered such that the values
   // are loaded in the correct order.
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
   intptr_t top =
-      reinterpret_cast<intptr_t>(new_space_allocation_top.address());
+      reinterpret_cast<intptr_t>(allocation_top.address());
   intptr_t limit =
-      reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
+      reinterpret_cast<intptr_t>(allocation_limit.address());
   ASSERT((limit - top) == kPointerSize);
   ASSERT(result.code() < ip.code());
 
   // Set up allocation top address.
   Register topaddr = scratch1;
-  mov(topaddr, Operand(new_space_allocation_top));
+  mov(topaddr, Operand(allocation_top));
 
   // This code stores a temporary value in ip. This is OK, as the code below
   // does not need ip for implicit literal generation.
@@ -1739,6 +1736,7 @@
   if ((flags & DOUBLE_ALIGNMENT) != 0) {
     // Align the next allocation. Storing the filler map without checking top is
     // always safe because the limit of the heap is always aligned.
+    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
     ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
     and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC);
     Label aligned;
@@ -1809,12 +1807,12 @@
   and_(scratch1, scratch1, Operand(~kObjectAlignmentMask));
 
   // Allocate two-byte string in new space.
-  AllocateInNewSpace(scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   InitializeNewString(result,
@@ -1840,12 +1838,12 @@
   and_(scratch1, scratch1, Operand(~kObjectAlignmentMask));
 
   // Allocate ASCII string in new space.
-  AllocateInNewSpace(scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   InitializeNewString(result,
@@ -2499,9 +2497,9 @@
 
 void MacroAssembler::ECMAConvertNumberToInt32(Register source,
                                               Register result,
-                                              Register scratch,
-                                              Register input_high,
                                               Register input_low,
+                                              Register input_high,
+                                              Register scratch,
                                               DwVfpRegister double_scratch1,
                                               DwVfpRegister double_scratch2) {
   if (CpuFeatures::IsSupported(VFP2)) {
@@ -2578,24 +2576,26 @@
 
   Ubfx(scratch, input_high,
        HeapNumber::kExponentShift, HeapNumber::kExponentBits);
-  // Load scratch with exponent - 1. This is faster than loading
-  // with exponent because Bias + 1 = 1024 which is an *ARM* immediate value.
-  sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
+  // Load scratch with exponent.
+  sub(scratch, scratch, Operand(HeapNumber::kExponentBias));
   // If exponent is negative, 0 < input < 1, the result is 0.
   // If exponent is greater than or equal to 84, the 32 less significant
   // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits),
   // the result is 0.
   // This test also catch Nan and infinities which also return 0.
-  // Compare exponent with 84 (compare exponent - 1 with 83).
-  cmp(scratch, Operand(83));
+  cmp(scratch, Operand(84));
   // We do an unsigned comparison so negative numbers are treated as big
   // positive number and the two tests above are done in one test.
   b(hs, &out_of_range);
 
-  // Load scratch with 20 - exponent (load with 19 - (exponent - 1)).
-  rsb(scratch, scratch, Operand(19), SetCC);
+  // Load scratch with 20 - exponent.
+  rsb(scratch, scratch, Operand(20), SetCC);
   b(mi, &both);
 
+  // Test 0 and -0.
+  bic(result, input_high, Operand(HeapNumber::kSignMask));
+  orr(result, result, Operand(input_low), SetCC);
+  b(eq, &done);
   // 0 <= exponent <= 20, shift only input_high.
   // Scratch contains: 20 - exponent.
   Ubfx(result, input_high,
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 5cbe995..958fcac 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -679,12 +679,12 @@
                 Label* gc_required,
                 AllocationFlags flags);
 
-  void AllocateInNewSpace(Register object_size,
-                          Register result,
-                          Register scratch1,
-                          Register scratch2,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(Register object_size,
+                Register result,
+                Register scratch1,
+                Register scratch2,
+                Label* gc_required,
+                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. The caller must make sure that no pointers
@@ -960,9 +960,9 @@
   // Exits with 'result' holding the answer.
   void ECMAConvertNumberToInt32(Register source,
                                 Register result,
-                                Register scratch,
-                                Register input_high,
                                 Register input_low,
+                                Register input_high,
+                                Register scratch,
                                 DwVfpRegister double_scratch1,
                                 DwVfpRegister double_scratch2);
 
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index b7bc839..2551e14 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -112,8 +112,8 @@
   ASSERT(msg != NULL);
 
   // Update this stop description.
-  if (isWatchedStop(code) && !watched_stops[code].desc) {
-    watched_stops[code].desc = msg;
+  if (isWatchedStop(code) && !watched_stops_[code].desc) {
+    watched_stops_[code].desc = msg;
   }
 
   if (strlen(msg) > 0) {
@@ -141,8 +141,8 @@
   char* msg = *reinterpret_cast<char**>(sim_->get_pc()
                                         + Instruction::kInstrSize);
   // Update this stop description.
-  if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) {
-    sim_->watched_stops[code].desc = msg;
+  if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
+    sim_->watched_stops_[code].desc = msg;
   }
   // Print the stop message and code if it is not the default code.
   if (code != kMaxStopCode) {
@@ -1880,14 +1880,14 @@
   ASSERT(code <= kMaxStopCode);
   // Unwatched stops are always enabled.
   return !isWatchedStop(code) ||
-    !(watched_stops[code].count & kStopDisabledBit);
+    !(watched_stops_[code].count & kStopDisabledBit);
 }
 
 
 void Simulator::EnableStop(uint32_t code) {
   ASSERT(isWatchedStop(code));
   if (!isEnabledStop(code)) {
-    watched_stops[code].count &= ~kStopDisabledBit;
+    watched_stops_[code].count &= ~kStopDisabledBit;
   }
 }
 
@@ -1895,7 +1895,7 @@
 void Simulator::DisableStop(uint32_t code) {
   ASSERT(isWatchedStop(code));
   if (isEnabledStop(code)) {
-    watched_stops[code].count |= kStopDisabledBit;
+    watched_stops_[code].count |= kStopDisabledBit;
   }
 }
 
@@ -1903,13 +1903,13 @@
 void Simulator::IncreaseStopCounter(uint32_t code) {
   ASSERT(code <= kMaxStopCode);
   ASSERT(isWatchedStop(code));
-  if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) {
+  if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
     PrintF("Stop counter for code %i has overflowed.\n"
            "Enabling this code and reseting the counter to 0.\n", code);
-    watched_stops[code].count = 0;
+    watched_stops_[code].count = 0;
     EnableStop(code);
   } else {
-    watched_stops[code].count++;
+    watched_stops_[code].count++;
   }
 }
 
@@ -1921,12 +1921,12 @@
     PrintF("Stop not watched.");
   } else {
     const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
-    int32_t count = watched_stops[code].count & ~kStopDisabledBit;
+    int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
     // Don't print the state of unused breakpoints.
     if (count != 0) {
-      if (watched_stops[code].desc) {
+      if (watched_stops_[code].desc) {
         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
-               code, code, state, count, watched_stops[code].desc);
+               code, code, state, count, watched_stops_[code].desc);
       } else {
         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
                code, code, state, count);
diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h
index 907a590..b918ecf 100644
--- a/src/arm/simulator-arm.h
+++ b/src/arm/simulator-arm.h
@@ -414,14 +414,14 @@
   static const uint32_t kStopDisabledBit = 1 << 31;
 
   // A stop is enabled, meaning the simulator will stop when meeting the
-  // instruction, if bit 31 of watched_stops[code].count is unset.
-  // The value watched_stops[code].count & ~(1 << 31) indicates how many times
+  // instruction, if bit 31 of watched_stops_[code].count is unset.
+  // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
   // the breakpoint was hit or gone through.
   struct StopCountAndDesc {
     uint32_t count;
     char* desc;
   };
-  StopCountAndDesc watched_stops[kNumOfWatchedStops];
+  StopCountAndDesc watched_stops_[kNumOfWatchedStops];
 };
 
 
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 3350c56..f2d45e1 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -423,7 +423,7 @@
 // registers have their original values.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Handle<JSObject> object,
-                                      int index,
+                                      LookupResult* lookup,
                                       Handle<Map> transition,
                                       Handle<Name> name,
                                       Register receiver_reg,
@@ -436,16 +436,6 @@
   // r0 : value
   Label exit;
 
-  LookupResult lookup(masm->isolate());
-  object->Lookup(*name, &lookup);
-  if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
-    // In sloppy mode, we could just return the value and be done. However, we
-    // might be in strict mode, where we have to throw. Since we cannot tell,
-    // go into slow case unconditionally.
-    __ jmp(miss_label);
-    return;
-  }
-
   // Check that the map of the object hasn't changed.
   CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
                                              : REQUIRE_EXACT_MAP;
@@ -460,8 +450,9 @@
   // Check that we are allowed to write this.
   if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
     JSObject* holder;
-    if (lookup.IsFound()) {
-      holder = lookup.holder();
+    // holder == object indicates that no property was found.
+    if (lookup->holder() != *object) {
+      holder = lookup->holder();
     } else {
       // Find the top object.
       holder = *object;
@@ -469,8 +460,19 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, miss_restore_name);
+    Register holder_reg = CheckPrototypes(
+        object, receiver_reg, Handle<JSObject>(holder), name_reg,
+        scratch1, scratch2, name, miss_restore_name);
+    // If no property was found, and the holder (the last object in the
+    // prototype chain) is in slow mode, we need to do a negative lookup on the
+    // holder.
+    if (lookup->holder() == *object &&
+        !holder->HasFastProperties() &&
+        !holder->IsJSGlobalProxy() &&
+        !holder->IsJSGlobalObject()) {
+      GenerateDictionaryNegativeLookup(
+          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    }
   }
 
   // Stub never generated for non-global objects that require access
@@ -492,6 +494,7 @@
     return;
   }
 
+  int index;
   if (!transition.is_null()) {
     // Update the map of the object.
     __ mov(scratch1, Operand(transition));
@@ -507,6 +510,10 @@
                         kDontSaveFPRegs,
                         OMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
+    index = transition->instance_descriptors()->GetFieldIndex(
+        transition->LastAdded());
+  } else {
+    index = lookup->GetFieldIndex().field_index();
   }
 
   // Adjust for the number of properties stored in the object. Even in the
@@ -2391,6 +2398,12 @@
       // Check that the object is a symbol.
       __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE);
       __ b(ne, &miss);
+      // Check that the maps starting from the prototype haven't changed.
+      GenerateDirectLoadGlobalFunctionPrototype(
+          masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss);
+      CheckPrototypes(
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+          r0, holder, r3, r1, r4, name, &miss);
       break;
 
     case NUMBER_CHECK: {
@@ -2982,7 +2995,7 @@
   __ cmp(r3, Operand(instance_size >> kPointerSizeLog2));
   __ Check(eq, "Instance size of initial map changed.");
 #endif
-  __ AllocateInNewSpace(r3, r4, r5, r6, &generic_stub_call, SIZE_IN_WORDS);
+  __ Allocate(r3, r4, r5, r6, &generic_stub_call, SIZE_IN_WORDS);
 
   // Allocated the JSObject, now initialize the fields. Map is set to initial
   // map and properties and elements are set to empty fixed array.
diff --git a/src/array.js b/src/array.js
index 7cf744b..936d008 100644
--- a/src/array.js
+++ b/src/array.js
@@ -38,22 +38,21 @@
 
 // Gets a sorted array of array keys.  Useful for operations on sparse
 // arrays.  Dupes have not been removed.
-function GetSortedArrayKeys(array, intervals) {
-  var length = intervals.length;
-  var keys = [];
-  for (var k = 0; k < length; k++) {
-    var key = intervals[k];
-    if (key < 0) {
-      var j = -1 - key;
-      var limit = j + intervals[++k];
-      for (; j < limit; j++) {
-        var e = array[j];
-        if (!IS_UNDEFINED(e) || j in array) {
-          keys.push(j);
-        }
+function GetSortedArrayKeys(array, indices) {
+  var keys = new InternalArray();
+  if (IS_NUMBER(indices)) {
+    // It's an interval
+    var limit = indices;
+    for (var i = 0; i < limit; ++i) {
+      var e = array[i];
+      if (!IS_UNDEFINED(e) || i in array) {
+        keys.push(i);
       }
-    } else {
-      // The case where key is undefined also ends here.
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
       if (!IS_UNDEFINED(key)) {
         var e = array[key];
         if (!IS_UNDEFINED(e) || key in array) {
@@ -61,8 +60,8 @@
         }
       }
     }
+    %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort);
   }
-  %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort);
   return keys;
 }
 
@@ -217,34 +216,21 @@
 // special array operations to handle sparse arrays in a sensible fashion.
 function SmartSlice(array, start_i, del_count, len, deleted_elements) {
   // Move deleted elements to a new array (the return value from splice).
-  // Intervals array can contain keys and intervals.  See comment in Concat.
-  var intervals = %GetArrayKeys(array, start_i + del_count);
-  var length = intervals.length;
-  for (var k = 0; k < length; k++) {
-    var key = intervals[k];
-    if (key < 0) {
-      var j = -1 - key;
-      var interval_limit = j + intervals[++k];
-      if (j < start_i) {
-        j = start_i;
+  var indices = %GetArrayKeys(array, start_i + del_count);
+  if (IS_NUMBER(indices)) {
+    var limit = indices;
+    for (var i = start_i; i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        deleted_elements[i - start_i] = current;
       }
-      for (; j < interval_limit; j++) {
-        // ECMA-262 15.4.4.12 line 10.  The spec could also be
-        // interpreted such that %HasLocalProperty would be the
-        // appropriate test.  We follow KJS in consulting the
-        // prototype.
-        var current = array[j];
-        if (!IS_UNDEFINED(current) || j in array) {
-          deleted_elements[j - start_i] = current;
-        }
-      }
-    } else {
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
       if (!IS_UNDEFINED(key)) {
         if (key >= start_i) {
-          // ECMA-262 15.4.4.12 line 10.  The spec could also be
-          // interpreted such that %HasLocalProperty would be the
-          // appropriate test.  We follow KJS in consulting the
-          // prototype.
           var current = array[key];
           if (!IS_UNDEFINED(current) || key in array) {
             deleted_elements[key - start_i] = current;
@@ -261,50 +247,32 @@
 function SmartMove(array, start_i, del_count, len, num_additional_args) {
   // Move data to new array.
   var new_array = new InternalArray(len - del_count + num_additional_args);
-  var intervals = %GetArrayKeys(array, len);
-  var length = intervals.length;
-  for (var k = 0; k < length; k++) {
-    var key = intervals[k];
-    if (key < 0) {
-      var j = -1 - key;
-      var interval_limit = j + intervals[++k];
-      while (j < start_i && j < interval_limit) {
-        // The spec could also be interpreted such that
-        // %HasLocalProperty would be the appropriate test.  We follow
-        // KJS in consulting the prototype.
-        var current = array[j];
-        if (!IS_UNDEFINED(current) || j in array) {
-          new_array[j] = current;
-        }
-        j++;
+  var indices = %GetArrayKeys(array, len);
+  if (IS_NUMBER(indices)) {
+    var limit = indices;
+    for (var i = 0; i < start_i && i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        new_array[i] = current;
       }
-      j = start_i + del_count;
-      while (j < interval_limit) {
-        // ECMA-262 15.4.4.12 lines 24 and 41.  The spec could also be
-        // interpreted such that %HasLocalProperty would be the
-        // appropriate test.  We follow KJS in consulting the
-        // prototype.
-        var current = array[j];
-        if (!IS_UNDEFINED(current) || j in array) {
-          new_array[j - del_count + num_additional_args] = current;
-        }
-        j++;
+    }
+    for (var i = start_i + del_count; i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        new_array[i - del_count + num_additional_args] = current;
       }
-    } else {
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
       if (!IS_UNDEFINED(key)) {
         if (key < start_i) {
-          // The spec could also be interpreted such that
-          // %HasLocalProperty would be the appropriate test.  We follow
-          // KJS in consulting the prototype.
           var current = array[key];
           if (!IS_UNDEFINED(current) || key in array) {
             new_array[key] = current;
           }
         } else if (key >= start_i + del_count) {
-          // ECMA-262 15.4.4.12 lines 24 and 41.  The spec could also
-          // be interpreted such that %HasLocalProperty would be the
-          // appropriate test.  We follow KJS in consulting the
-          // prototype.
           var current = array[key];
           if (!IS_UNDEFINED(current) || key in array) {
             new_array[key - del_count + num_additional_args] = current;
@@ -887,24 +855,22 @@
     var max = 0;
     for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, length);
-      if (indices.length > 0) {
-        if (indices[0] == -1) {
-          // It's an interval.
-          var proto_length = indices[1];
-          for (var i = 0; i < proto_length; i++) {
-            if (!obj.hasOwnProperty(i) && proto.hasOwnProperty(i)) {
-              obj[i] = proto[i];
-              if (i >= max) { max = i + 1; }
-            }
+      if (IS_NUMBER(indices)) {
+        // It's an interval.
+        var proto_length = indices;
+        for (var i = 0; i < proto_length; i++) {
+          if (!obj.hasOwnProperty(i) && proto.hasOwnProperty(i)) {
+            obj[i] = proto[i];
+            if (i >= max) { max = i + 1; }
           }
-        } else {
-          for (var i = 0; i < indices.length; i++) {
-            var index = indices[i];
-            if (!IS_UNDEFINED(index) &&
-                !obj.hasOwnProperty(index) && proto.hasOwnProperty(index)) {
-              obj[index] = proto[index];
-              if (index >= max) { max = index + 1; }
-            }
+        }
+      } else {
+        for (var i = 0; i < indices.length; i++) {
+          var index = indices[i];
+          if (!IS_UNDEFINED(index) &&
+              !obj.hasOwnProperty(index) && proto.hasOwnProperty(index)) {
+            obj[index] = proto[index];
+            if (index >= max) { max = index + 1; }
           }
         }
       }
@@ -918,22 +884,20 @@
   var ShadowPrototypeElements = function(obj, from, to) {
     for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, to);
-      if (indices.length > 0) {
-        if (indices[0] == -1) {
-          // It's an interval.
-          var proto_length = indices[1];
-          for (var i = from; i < proto_length; i++) {
-            if (proto.hasOwnProperty(i)) {
-              obj[i] = void 0;
-            }
+      if (IS_NUMBER(indices)) {
+        // It's an interval.
+        var proto_length = indices;
+        for (var i = from; i < proto_length; i++) {
+          if (proto.hasOwnProperty(i)) {
+            obj[i] = void 0;
           }
-        } else {
-          for (var i = 0; i < indices.length; i++) {
-            var index = indices[i];
-            if (!IS_UNDEFINED(index) && from <= index &&
-                proto.hasOwnProperty(index)) {
-              obj[index] = void 0;
-            }
+        }
+      } else {
+        for (var i = 0; i < indices.length; i++) {
+          var index = indices[i];
+          if (!IS_UNDEFINED(index) && from <= index &&
+              proto.hasOwnProperty(index)) {
+            obj[index] = void 0;
           }
         }
       }
@@ -1284,18 +1248,15 @@
   var min = index;
   var max = length;
   if (UseSparseVariant(this, length, IS_ARRAY(this))) {
-    var intervals = %GetArrayKeys(this, length);
-    if (intervals.length == 2 && intervals[0] < 0) {
-      // A single interval.
-      var intervalMin = -(intervals[0] + 1);
-      var intervalMax = intervalMin + intervals[1];
-      if (min < intervalMin) min = intervalMin;
-      max = intervalMax;  // Capped by length already.
+    var indices = %GetArrayKeys(this, length);
+    if (IS_NUMBER(indices)) {
+      // It's an interval.
+      max = indices;  // Capped by length already.
       // Fall through to loop below.
     } else {
-      if (intervals.length == 0) return -1;
+      if (indices.length == 0) return -1;
       // Get all the keys in sorted order.
-      var sortedKeys = GetSortedArrayKeys(this, intervals);
+      var sortedKeys = GetSortedArrayKeys(this, indices);
       var n = sortedKeys.length;
       var i = 0;
       while (i < n && sortedKeys[i] < index) i++;
@@ -1345,18 +1306,15 @@
   var min = 0;
   var max = index;
   if (UseSparseVariant(this, length, IS_ARRAY(this))) {
-    var intervals = %GetArrayKeys(this, index + 1);
-    if (intervals.length == 2 && intervals[0] < 0) {
-      // A single interval.
-      var intervalMin = -(intervals[0] + 1);
-      var intervalMax = intervalMin + intervals[1];
-      if (min < intervalMin) min = intervalMin;
-      max = intervalMax;  // Capped by index already.
+    var indices = %GetArrayKeys(this, index + 1);
+    if (IS_NUMBER(indices)) {
+      // It's an interval.
+      max = indices;  // Capped by index already.
       // Fall through to loop below.
     } else {
-      if (intervals.length == 0) return -1;
+      if (indices.length == 0) return -1;
       // Get all the keys in sorted order.
-      var sortedKeys = GetSortedArrayKeys(this, intervals);
+      var sortedKeys = GetSortedArrayKeys(this, indices);
       var i = sortedKeys.length - 1;
       while (i >= 0) {
         var key = sortedKeys[i];
diff --git a/src/ast.cc b/src/ast.cc
index a6984dd..7d7a5b2 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -414,12 +414,9 @@
   is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
   receiver_types_.Clear();
   if (key()->IsPropertyName()) {
-    ArrayLengthStub array_stub(Code::LOAD_IC);
     FunctionPrototypeStub proto_stub(Code::LOAD_IC);
     StringLengthStub string_stub(Code::LOAD_IC, false);
-    if (oracle->LoadIsStub(this, &array_stub)) {
-      is_array_length_ = true;
-    } else if (oracle->LoadIsStub(this, &string_stub)) {
+    if (oracle->LoadIsStub(this, &string_stub)) {
       is_string_length_ = true;
     } else if (oracle->LoadIsStub(this, &proto_stub)) {
       is_function_prototype_ = true;
@@ -1065,6 +1062,7 @@
 DONT_OPTIMIZE_NODE(ModulePath)
 DONT_OPTIMIZE_NODE(ModuleUrl)
 DONT_OPTIMIZE_NODE(ModuleStatement)
+DONT_OPTIMIZE_NODE(Yield)
 DONT_OPTIMIZE_NODE(WithStatement)
 DONT_OPTIMIZE_NODE(TryCatchStatement)
 DONT_OPTIMIZE_NODE(TryFinallyStatement)
diff --git a/src/ast.h b/src/ast.h
index 88cd696..dddfc83 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -102,6 +102,7 @@
   V(ObjectLiteral)                              \
   V(ArrayLiteral)                               \
   V(Assignment)                                 \
+  V(Yield)                                      \
   V(Throw)                                      \
   V(Property)                                   \
   V(Call)                                       \
@@ -119,6 +120,10 @@
   STATEMENT_NODE_LIST(V)                        \
   EXPRESSION_NODE_LIST(V)
 
+#ifdef WIN32
+#undef Yield
+#endif
+
 // Forward declarations
 class AstConstructionVisitor;
 template<class> class AstNodeFactory;
@@ -1488,7 +1493,6 @@
   virtual KeyedAccessStoreMode GetStoreMode() {
     return STANDARD_STORE;
   }
-  bool IsArrayLength() { return is_array_length_; }
   bool IsUninitialized() { return is_uninitialized_; }
   TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
 
@@ -1504,7 +1508,6 @@
         load_id_(GetNextId(isolate)),
         is_monomorphic_(false),
         is_uninitialized_(false),
-        is_array_length_(false),
         is_string_length_(false),
         is_string_access_(false),
         is_function_prototype_(false) { }
@@ -1518,7 +1521,6 @@
   SmallMapList receiver_types_;
   bool is_monomorphic_ : 1;
   bool is_uninitialized_ : 1;
-  bool is_array_length_ : 1;
   bool is_string_length_ : 1;
   bool is_string_access_ : 1;
   bool is_function_prototype_ : 1;
@@ -1956,6 +1958,31 @@
 };
 
 
+class Yield: public Expression {
+ public:
+  DECLARE_NODE_TYPE(Yield)
+
+  Expression* expression() const { return expression_; }
+  bool is_delegating_yield() const { return is_delegating_yield_; }
+  virtual int position() const { return pos_; }
+
+ protected:
+  Yield(Isolate* isolate,
+        Expression* expression,
+        bool is_delegating_yield,
+        int pos)
+      : Expression(isolate),
+        expression_(expression),
+        is_delegating_yield_(is_delegating_yield),
+        pos_(pos) { }
+
+ private:
+  Expression* expression_;
+  bool is_delegating_yield_;
+  int pos_;
+};
+
+
 class Throw: public Expression {
  public:
   DECLARE_NODE_TYPE(Throw)
@@ -1996,6 +2023,11 @@
     kNotParenthesized
   };
 
+  enum IsGeneratorFlag {
+    kIsGenerator,
+    kNotGenerator
+  };
+
   DECLARE_NODE_TYPE(FunctionLiteral)
 
   Handle<String> name() const { return name_; }
@@ -2056,6 +2088,10 @@
     bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized);
   }
 
+  bool is_generator() {
+    return IsGenerator::decode(bitfield_) == kIsGenerator;
+  }
+
   int ast_node_count() { return ast_properties_.node_count(); }
   AstProperties::Flags* flags() { return ast_properties_.flags(); }
   void set_ast_properties(AstProperties* ast_properties) {
@@ -2076,7 +2112,8 @@
                   Type type,
                   ParameterFlag has_duplicate_parameters,
                   IsFunctionFlag is_function,
-                  IsParenthesizedFlag is_parenthesized)
+                  IsParenthesizedFlag is_parenthesized,
+                  IsGeneratorFlag is_generator)
       : Expression(isolate),
         name_(name),
         scope_(scope),
@@ -2096,7 +2133,8 @@
         Pretenure::encode(false) |
         HasDuplicateParameters::encode(has_duplicate_parameters) |
         IsFunction::encode(is_function) |
-        IsParenthesized::encode(is_parenthesized);
+        IsParenthesized::encode(is_parenthesized) |
+        IsGenerator::encode(is_generator);
   }
 
  private:
@@ -2121,6 +2159,7 @@
   class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
   class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
   class IsParenthesized: public BitField<IsParenthesizedFlag, 6, 1> {};
+  class IsGenerator: public BitField<IsGeneratorFlag, 7, 1> {};
 };
 
 
@@ -2919,6 +2958,12 @@
     VISIT_AND_RETURN(Assignment, assign)
   }
 
+  Yield* NewYield(Expression* expression, bool is_delegating_yield, int pos) {
+    Yield* yield =
+        new(zone_) Yield(isolate_, expression, is_delegating_yield, pos);
+    VISIT_AND_RETURN(Yield, yield)
+  }
+
   Throw* NewThrow(Expression* exception, int pos) {
     Throw* t = new(zone_) Throw(isolate_, exception, pos);
     VISIT_AND_RETURN(Throw, t)
@@ -2937,13 +2982,14 @@
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
       FunctionLiteral::Type type,
       FunctionLiteral::IsFunctionFlag is_function,
-      FunctionLiteral::IsParenthesizedFlag is_parenthesized) {
+      FunctionLiteral::IsParenthesizedFlag is_parenthesized,
+      FunctionLiteral::IsGeneratorFlag is_generator) {
     FunctionLiteral* lit = new(zone_) FunctionLiteral(
         isolate_, name, scope, body,
         materialized_literal_count, expected_property_count, handler_count,
         has_only_simple_this_property_assignments, this_property_assignments,
         parameter_count, type, has_duplicate_parameters, is_function,
-        is_parenthesized);
+        is_parenthesized, is_generator);
     // Top-level literal doesn't count for the AST's properties.
     if (is_function == FunctionLiteral::kIsFunction) {
       visitor_.VisitFunctionLiteral(lit);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index ce58a86..f57a1f6 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1280,7 +1280,17 @@
   Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
 
   // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
-  // longer need to live behind a flag, so functions get added to the snapshot.
+  // longer need to live behind flags, so functions get added to the snapshot.
+
+  if (FLAG_harmony_symbols) {
+    // --- S y m b o l ---
+    Handle<JSFunction> symbol_fun =
+        InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
+                        isolate()->initial_object_prototype(),
+                        Builtins::kIllegal, true);
+    native_context()->set_symbol_function(*symbol_fun);
+  }
+
   if (FLAG_harmony_collections) {
     {  // -- S e t
       Handle<JSObject> prototype =
@@ -1301,6 +1311,16 @@
                       prototype, Builtins::kIllegal, true);
     }
   }
+
+  if (FLAG_harmony_typed_arrays) {
+    { // -- A r r a y B u f f e r
+      Handle<JSObject> prototype =
+          factory()->NewJSObject(isolate()->object_function(), TENURED);
+      InstallFunction(global, "__ArrayBuffer", JS_ARRAY_BUFFER_TYPE,
+                      JSArrayBuffer::kSize, prototype,
+                      Builtins::kIllegal, true);
+    }
+  }
 }
 
 
@@ -1436,9 +1456,6 @@
 }
 
 void Genesis::InstallExperimentalNativeFunctions() {
-  if (FLAG_harmony_symbols) {
-    INSTALL_NATIVE(JSObject, "SymbolDelegate", symbol_delegate);
-  }
   if (FLAG_harmony_proxies) {
     INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
     INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
@@ -1911,6 +1928,11 @@
                "native object-observe.js") == 0) {
       if (!CompileExperimentalBuiltin(isolate(), i)) return false;
     }
+    if (FLAG_harmony_typed_arrays &&
+        strcmp(ExperimentalNatives::GetScriptName(i).start(),
+               "native typedarray.js") == 0) {
+      if (!CompileExperimentalBuiltin(isolate(), i)) return false;
+    }
   }
 
   InstallExperimentalNativeFunctions();
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 0a8b9d5..ee903ae 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -129,7 +129,8 @@
   if (descriptor_->stack_parameter_count_ != NULL) {
     ASSERT(descriptor_->environment_length() == (param_count + 1));
     stack_parameter_count = new(zone) HParameter(param_count,
-        HParameter::REGISTER_PARAMETER);
+                                                 HParameter::REGISTER_PARAMETER,
+                                                 Representation::Integer32());
     // it's essential to bind this value to the environment in case of deopt
     start_environment->Bind(param_count, stack_parameter_count);
     AddInstruction(stack_parameter_count);
@@ -147,13 +148,26 @@
   AddSimulate(BailoutId::StubEntry());
 
   HValue* return_value = BuildCodeStub();
+
+  // We might have extra expressions to pop from the stack in addition to the
+  // arguments above
+  HInstruction* stack_pop_count = stack_parameter_count;
+  if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
+    HInstruction* amount = graph()->GetConstant1();
+    stack_pop_count = AddInstruction(
+        HAdd::New(zone, context_, stack_parameter_count, amount));
+    stack_pop_count->ChangeRepresentation(Representation::Integer32());
+    stack_pop_count->ClearFlag(HValue::kCanOverflow);
+  }
+
   HReturn* hreturn_instruction = new(zone) HReturn(return_value,
                                                    context_,
-                                                   stack_parameter_count);
+                                                   stack_pop_count);
   current_block()->Finish(hreturn_instruction);
   return true;
 }
 
+
 template <class Stub>
 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
  public:
@@ -273,9 +287,8 @@
   AddInstruction(new(zone) HTrapAllocationMemento(js_array));
 
   HInstruction* array_length =
-      AddInstruction(new(zone) HJSArrayLength(js_array,
-                                              js_array,
-                                              HType::Smi()));
+      AddInstruction(HLoadNamedField::NewArrayLength(
+            zone, js_array, js_array, HType::Smi()));
 
   ElementsKind to_kind = casted_stub()->to_kind();
   BuildNewSpaceArrayCheck(array_length, to_kind);
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 95bc1e9..eff0f7f 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -510,6 +510,7 @@
   if (Contains(SMI)) stream->Add("Smi");
   if (Contains(SPEC_OBJECT)) stream->Add("SpecObject");
   if (Contains(STRING)) stream->Add("String");
+  if (Contains(SYMBOL)) stream->Add("Symbol");
   if (Contains(HEAP_NUMBER)) stream->Add("HeapNumber");
 }
 
@@ -549,6 +550,9 @@
     Add(STRING);
     return !object->IsUndetectableObject() &&
         String::cast(*object)->length() != 0;
+  } else if (object->IsSymbol()) {
+    Add(SYMBOL);
+    return true;
   } else if (object->IsHeapNumber()) {
     ASSERT(!object->IsUndetectableObject());
     Add(HEAP_NUMBER);
@@ -565,6 +569,7 @@
 bool ToBooleanStub::Types::NeedsMap() const {
   return Contains(ToBooleanStub::SPEC_OBJECT)
       || Contains(ToBooleanStub::STRING)
+      || Contains(ToBooleanStub::SYMBOL)
       || Contains(ToBooleanStub::HEAP_NUMBER);
 }
 
@@ -614,10 +619,8 @@
 
 
 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
-  int i = 0;
-  for (; i <= StubFailureTrampolineStub::kMaxExtraExpressionStackCount; ++i) {
-    StubFailureTrampolineStub(i).GetCode(isolate);
-  }
+  StubFailureTrampolineStub(NOT_JS_FUNCTION_STUB_MODE).GetCode(isolate);
+  StubFailureTrampolineStub(JS_FUNCTION_STUB_MODE).GetCode(isolate);
 }
 
 
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 6e95780..99ff515 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -47,7 +47,6 @@
   V(Compare)                             \
   V(CompareIC)                           \
   V(MathPow)                             \
-  V(ArrayLength)                         \
   V(StringLength)                        \
   V(FunctionPrototype)                   \
   V(StoreArrayLength)                    \
@@ -259,15 +258,17 @@
 };
 
 
+enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
+
 struct CodeStubInterfaceDescriptor {
   CodeStubInterfaceDescriptor()
       : register_param_count_(-1),
         stack_parameter_count_(NULL),
-        extra_expression_stack_count_(0),
+        function_mode_(NOT_JS_FUNCTION_STUB_MODE),
         register_params_(NULL) { }
   int register_param_count_;
   const Register* stack_parameter_count_;
-  int extra_expression_stack_count_;
+  StubFunctionMode function_mode_;
   Register* register_params_;
   Address deoptimization_handler_;
 
@@ -597,16 +598,6 @@
 };
 
 
-class ArrayLengthStub: public ICStub {
- public:
-  explicit ArrayLengthStub(Code::Kind kind) : ICStub(kind) { }
-  virtual void Generate(MacroAssembler* masm);
-
- private:
-  virtual CodeStub::Major MajorKey() { return ArrayLength; }
-};
-
-
 class FunctionPrototypeStub: public ICStub {
  public:
   explicit FunctionPrototypeStub(Code::Kind kind) : ICStub(kind) { }
@@ -1488,6 +1479,7 @@
     SMI,
     SPEC_OBJECT,
     STRING,
+    SYMBOL,
     HEAP_NUMBER,
     NUMBER_OF_TYPES
   };
@@ -1611,10 +1603,8 @@
 
 class StubFailureTrampolineStub : public PlatformCodeStub {
  public:
-  static const int kMaxExtraExpressionStackCount = 1;
-
-  explicit StubFailureTrampolineStub(int extra_expression_stack_count)
-      : extra_expression_stack_count_(extra_expression_stack_count) {}
+  explicit StubFailureTrampolineStub(StubFunctionMode function_mode)
+      : function_mode_(function_mode) {}
 
   virtual bool IsPregenerated() { return true; }
 
@@ -1622,11 +1612,11 @@
 
  private:
   Major MajorKey() { return StubFailureTrampoline; }
-  int MinorKey() { return extra_expression_stack_count_; }
+  int MinorKey() { return static_cast<int>(function_mode_); }
 
   void Generate(MacroAssembler* masm);
 
-  int extra_expression_stack_count_;
+  StubFunctionMode function_mode_;
 
   DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub);
 };
diff --git a/src/codegen.cc b/src/codegen.cc
index 508e221..90ab2b5 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -171,7 +171,8 @@
 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
   ASSERT(type != NULL);
   Isolate* isolate = Isolate::Current();
-  if (!isolate->logger()->is_logging() && !CpuProfiler::is_profiling(isolate)) {
+  if (!isolate->logger()->is_logging() &&
+      !isolate->cpu_profiler()->is_profiling()) {
     return false;
   }
   Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
diff --git a/src/compiler.cc b/src/compiler.cc
index 21ea25f..6f9b901 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1121,6 +1121,7 @@
   function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
   function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
   function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
+  function_info->set_is_generator(lit->is_generator());
 }
 
 
@@ -1134,7 +1135,7 @@
   // script name and line number. Check explicitly whether logging is
   // enabled as finding the line number is not free.
   if (info->isolate()->logger()->is_logging_code_events() ||
-      CpuProfiler::is_profiling(info->isolate())) {
+      info->isolate()->cpu_profiler()->is_profiling()) {
     Handle<Script> script = info->script();
     Handle<Code> code = info->code();
     if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
diff --git a/src/contexts.h b/src/contexts.h
index cd7ed6a..a0ba2f7 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -103,6 +103,7 @@
   V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
   V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
   V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
+  V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
   V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
   V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
   V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
@@ -156,7 +157,6 @@
   V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
   V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
     error_message_for_code_gen_from_strings) \
-  V(SYMBOL_DELEGATE_INDEX, JSObject, symbol_delegate) \
   V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
     to_complete_property_descriptor) \
   V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
@@ -251,6 +251,7 @@
     NUMBER_FUNCTION_INDEX,
     STRING_FUNCTION_INDEX,
     STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
+    SYMBOL_FUNCTION_INDEX,
     OBJECT_FUNCTION_INDEX,
     INTERNAL_ARRAY_FUNCTION_INDEX,
     ARRAY_FUNCTION_INDEX,
@@ -287,7 +288,6 @@
     EMBEDDER_DATA_INDEX,
     ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
     ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
-    SYMBOL_DELEGATE_INDEX,
     TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
     DERIVED_HAS_TRAP_INDEX,
     DERIVED_GET_TRAP_INDEX,
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 15edc1e..7979eb4 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -258,109 +258,66 @@
 }
 
 
-void CpuProfiler::StartProfiling(const char* title) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
-}
-
-
-void CpuProfiler::StartProfiling(String* title) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(const char* title) {
-  Isolate* isolate = Isolate::Current();
-  return is_profiling(isolate) ?
-      isolate->cpu_profiler()->StopCollectingProfile(title) : NULL;
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
-  Isolate* isolate = Isolate::Current();
-  return is_profiling(isolate) ?
-      isolate->cpu_profiler()->StopCollectingProfile(
-          security_token, title) : NULL;
-}
-
-
 int CpuProfiler::GetProfilesCount() {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
   // The count of profiles doesn't depend on a security token.
-  return Isolate::Current()->cpu_profiler()->profiles_->Profiles(
-      TokenEnumerator::kNoSecurityToken)->length();
+  return profiles_->Profiles(TokenEnumerator::kNoSecurityToken)->length();
 }
 
 
 CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  const int token = profiler->token_enumerator_->GetTokenId(security_token);
-  return profiler->profiles_->Profiles(token)->at(index);
+  const int token = token_enumerator_->GetTokenId(security_token);
+  return profiles_->Profiles(token)->at(index);
 }
 
 
 CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  const int token = profiler->token_enumerator_->GetTokenId(security_token);
-  return profiler->profiles_->GetProfile(token, uid);
+  const int token = token_enumerator_->GetTokenId(security_token);
+  return profiles_->GetProfile(token, uid);
 }
 
 
-TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) {
-  if (CpuProfiler::is_profiling(isolate)) {
-    return isolate->cpu_profiler()->processor_->TickSampleEvent();
-  } else {
-    return NULL;
-  }
+TickSample* CpuProfiler::TickSampleEvent() {
+  if (is_profiling_) return processor_->TickSampleEvent();
+  return NULL;
 }
 
 
 void CpuProfiler::DeleteAllProfiles() {
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate->cpu_profiler() != NULL);
-  if (is_profiling(isolate)) {
-    isolate->cpu_profiler()->StopProcessor();
-  }
-  isolate->cpu_profiler()->ResetProfiles();
+  if (is_profiling_) StopProcessor();
+  ResetProfiles();
 }
 
 
 void CpuProfiler::DeleteProfile(CpuProfile* profile) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->profiles_->RemoveProfile(profile);
+  profiles_->RemoveProfile(profile);
   delete profile;
 }
 
 
 bool CpuProfiler::HasDetachedProfiles() {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  return Isolate::Current()->cpu_profiler()->profiles_->HasDetachedProfiles();
+  return profiles_->HasDetachedProfiles();
 }
 
 
 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, const char* comment) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag, comment, code->address(), code->ExecutableSize());
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, Name* name) {
-  Isolate* isolate = Isolate::Current();
-  isolate->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       name,
-      isolate->heap()->empty_string(),
+      isolate_->heap()->empty_string(),
       v8::CpuProfileNode::kNoLineNumberInfo,
       code->address(),
       code->ExecutableSize(),
@@ -372,11 +329,10 @@
                                   Code* code,
                                   SharedFunctionInfo* shared,
                                   Name* name) {
-  Isolate* isolate = Isolate::Current();
-  isolate->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       name,
-      isolate->heap()->empty_string(),
+      isolate_->heap()->empty_string(),
       v8::CpuProfileNode::kNoLineNumberInfo,
       code->address(),
       code->ExecutableSize(),
@@ -388,7 +344,7 @@
                                   Code* code,
                                   SharedFunctionInfo* shared,
                                   String* source, int line) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       shared->DebugName(),
       source,
@@ -401,7 +357,7 @@
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, int args_count) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       args_count,
       code->address(),
@@ -410,7 +366,7 @@
 
 
 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeMoveEvent(from, to);
+  processor_->CodeMoveEvent(from, to);
 }
 
 
@@ -419,19 +375,18 @@
 
 
 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  profiler->processor_->SharedFunctionInfoMoveEvent(from, to);
+  processor_->SharedFunctionInfoMoveEvent(from, to);
 }
 
 
 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, "get ", name, entry_point);
 }
 
 
 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
-  Isolate::Current()->cpu_profiler()->processor_->RegExpCodeCreateEvent(
+  processor_->RegExpCodeCreateEvent(
       Logger::REG_EXP_TAG,
       "RegExp: ",
       source,
@@ -441,13 +396,14 @@
 
 
 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, "set ", name, entry_point);
 }
 
 
-CpuProfiler::CpuProfiler()
-    : profiles_(new CpuProfilesCollection()),
+CpuProfiler::CpuProfiler(Isolate* isolate)
+    : isolate_(isolate),
+      profiles_(new CpuProfilesCollection()),
       next_profile_uid_(1),
       token_enumerator_(new TokenEnumerator()),
       generator_(NULL),
@@ -468,43 +424,41 @@
   profiles_ = new CpuProfilesCollection();
 }
 
-void CpuProfiler::StartCollectingProfile(const char* title) {
-  if (profiles_->StartProfiling(title, next_profile_uid_++)) {
+void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
+  if (profiles_->StartProfiling(title, next_profile_uid_++, record_samples)) {
     StartProcessorIfNotStarted();
   }
   processor_->AddCurrentStack();
 }
 
 
-void CpuProfiler::StartCollectingProfile(String* title) {
-  StartCollectingProfile(profiles_->GetName(title));
+void CpuProfiler::StartProfiling(String* title, bool record_samples) {
+  StartProfiling(profiles_->GetName(title), record_samples);
 }
 
 
 void CpuProfiler::StartProcessorIfNotStarted() {
   if (processor_ == NULL) {
-    Isolate* isolate = Isolate::Current();
-
     // Disable logging when using the new implementation.
-    saved_logging_nesting_ = isolate->logger()->logging_nesting_;
-    isolate->logger()->logging_nesting_ = 0;
+    saved_logging_nesting_ = isolate_->logger()->logging_nesting_;
+    isolate_->logger()->logging_nesting_ = 0;
     generator_ = new ProfileGenerator(profiles_);
     processor_ = new ProfilerEventsProcessor(generator_);
     is_profiling_ = true;
     processor_->Start();
     // Enumerate stuff we already have in the heap.
-    if (isolate->heap()->HasBeenSetUp()) {
+    if (isolate_->heap()->HasBeenSetUp()) {
       if (!FLAG_prof_browser_mode) {
         bool saved_log_code_flag = FLAG_log_code;
         FLAG_log_code = true;
-        isolate->logger()->LogCodeObjects();
+        isolate_->logger()->LogCodeObjects();
         FLAG_log_code = saved_log_code_flag;
       }
-      isolate->logger()->LogCompiledFunctions();
-      isolate->logger()->LogAccessorCallbacks();
+      isolate_->logger()->LogCompiledFunctions();
+      isolate_->logger()->LogAccessorCallbacks();
     }
     // Enable stack sampling.
-    Sampler* sampler = reinterpret_cast<Sampler*>(isolate->logger()->ticker_);
+    Sampler* sampler = reinterpret_cast<Sampler*>(isolate_->logger()->ticker_);
     if (!sampler->IsActive()) {
       sampler->Start();
       need_to_stop_sampler_ = true;
@@ -514,7 +468,8 @@
 }
 
 
-CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
+CpuProfile* CpuProfiler::StopProfiling(const char* title) {
+  if (!is_profiling_) return NULL;
   const double actual_sampling_rate = generator_->actual_sampling_rate();
   StopProcessorIfLastProfile(title);
   CpuProfile* result =
@@ -528,8 +483,8 @@
 }
 
 
-CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
-                                               String* title) {
+CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
+  if (!is_profiling_) return NULL;
   const double actual_sampling_rate = generator_->actual_sampling_rate();
   const char* profile_title = profiles_->GetName(title);
   StopProcessorIfLastProfile(profile_title);
@@ -544,7 +499,7 @@
 
 
 void CpuProfiler::StopProcessor() {
-  Logger* logger = Isolate::Current()->logger();
+  Logger* logger = isolate_->logger();
   Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
   sampler->DecreaseProfilingDepth();
   if (need_to_stop_sampler_) {
@@ -562,20 +517,4 @@
 }
 
 
-void CpuProfiler::SetUp() {
-  Isolate* isolate = Isolate::Current();
-  if (isolate->cpu_profiler() == NULL) {
-    isolate->set_cpu_profiler(new CpuProfiler());
-  }
-}
-
-
-void CpuProfiler::TearDown() {
-  Isolate* isolate = Isolate::Current();
-  if (isolate->cpu_profiler() != NULL) {
-    delete isolate->cpu_profiler();
-  }
-  isolate->set_cpu_profiler(NULL);
-}
-
 } }  // namespace v8::internal
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 3dc766b..89d9c81 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -184,84 +184,71 @@
   unsigned enqueue_order_;
 };
 
-} }  // namespace v8::internal
 
-
-#define PROFILE(isolate, Call)                                \
-  LOG_CODE_EVENT(isolate, Call);                              \
-  do {                                                        \
-    if (v8::internal::CpuProfiler::is_profiling(isolate)) {   \
-      v8::internal::CpuProfiler::Call;                        \
-    }                                                         \
+#define PROFILE(IsolateGetter, Call)                                   \
+  do {                                                                 \
+    Isolate* cpu_profiler_isolate = (IsolateGetter);                   \
+    LOG_CODE_EVENT(cpu_profiler_isolate, Call);                        \
+    CpuProfiler* cpu_profiler = cpu_profiler_isolate->cpu_profiler();  \
+    if (cpu_profiler->is_profiling()) {                                \
+      cpu_profiler->Call;                                              \
+    }                                                                  \
   } while (false)
 
 
-namespace v8 {
-namespace internal {
-
-
-// TODO(isolates): isolatify this class.
 class CpuProfiler {
  public:
-  static void SetUp();
-  static void TearDown();
+  explicit CpuProfiler(Isolate* isolate);
+  ~CpuProfiler();
 
-  static void StartProfiling(const char* title);
-  static void StartProfiling(String* title);
-  static CpuProfile* StopProfiling(const char* title);
-  static CpuProfile* StopProfiling(Object* security_token, String* title);
-  static int GetProfilesCount();
-  static CpuProfile* GetProfile(Object* security_token, int index);
-  static CpuProfile* FindProfile(Object* security_token, unsigned uid);
-  static void DeleteAllProfiles();
-  static void DeleteProfile(CpuProfile* profile);
-  static bool HasDetachedProfiles();
+  void StartProfiling(const char* title, bool record_samples = false);
+  void StartProfiling(String* title, bool record_samples);
+  CpuProfile* StopProfiling(const char* title);
+  CpuProfile* StopProfiling(Object* security_token, String* title);
+  int GetProfilesCount();
+  CpuProfile* GetProfile(Object* security_token, int index);
+  CpuProfile* FindProfile(Object* security_token, unsigned uid);
+  void DeleteAllProfiles();
+  void DeleteProfile(CpuProfile* profile);
+  bool HasDetachedProfiles();
 
   // Invoked from stack sampler (thread or signal handler.)
-  static TickSample* TickSampleEvent(Isolate* isolate);
+  TickSample* TickSampleEvent();
 
   // Must be called via PROFILE macro, otherwise will crash when
   // profiling is not enabled.
-  static void CallbackEvent(Name* name, Address entry_point);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, const char* comment);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, Name* name);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code,
+  void CallbackEvent(Name* name, Address entry_point);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, const char* comment);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, Name* name);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code,
                               SharedFunctionInfo* shared,
                               Name* name);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code,
-                              SharedFunctionInfo* shared,
-                              String* source, int line);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, int args_count);
-  static void CodeMovingGCEvent() {}
-  static void CodeMoveEvent(Address from, Address to);
-  static void CodeDeleteEvent(Address from);
-  static void GetterCallbackEvent(Name* name, Address entry_point);
-  static void RegExpCodeCreateEvent(Code* code, String* source);
-  static void SetterCallbackEvent(Name* name, Address entry_point);
-  static void SharedFunctionInfoMoveEvent(Address from, Address to);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code,
+                       SharedFunctionInfo* shared,
+                       String* source, int line);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, int args_count);
+  void CodeMovingGCEvent() {}
+  void CodeMoveEvent(Address from, Address to);
+  void CodeDeleteEvent(Address from);
+  void GetterCallbackEvent(Name* name, Address entry_point);
+  void RegExpCodeCreateEvent(Code* code, String* source);
+  void SetterCallbackEvent(Name* name, Address entry_point);
+  void SharedFunctionInfoMoveEvent(Address from, Address to);
 
-  static INLINE(bool is_profiling(Isolate* isolate)) {
-    CpuProfiler* profiler = isolate->cpu_profiler();
-    return profiler != NULL && profiler->is_profiling_;
-  }
+  INLINE(bool is_profiling() const) { return is_profiling_; }
 
  private:
-  CpuProfiler();
-  ~CpuProfiler();
-  void StartCollectingProfile(const char* title);
-  void StartCollectingProfile(String* title);
   void StartProcessorIfNotStarted();
-  CpuProfile* StopCollectingProfile(const char* title);
-  CpuProfile* StopCollectingProfile(Object* security_token, String* title);
   void StopProcessorIfLastProfile(const char* title);
   void StopProcessor();
   void ResetProfiles();
 
+  Isolate* isolate_;
   CpuProfilesCollection* profiles_;
   unsigned next_profile_uid_;
   TokenEnumerator* token_enumerator_;
diff --git a/src/d8.cc b/src/d8.cc
index 805a0cf..b57e390 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -227,11 +227,13 @@
           }
 #if !defined(V8_SHARED)
         } else {
+          v8::TryCatch try_catch;
           Context::Scope context_scope(utility_context_);
           Handle<Object> global = utility_context_->Global();
           Handle<Value> fun = global->Get(String::New("Stringify"));
           Handle<Value> argv[1] = { result };
           Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
+          if (try_catch.HasCaught()) return true;
           v8::String::Utf8Value str(s);
           fwrite(*str, sizeof(**str), str.length(), stdout);
           printf("\n");
@@ -905,12 +907,6 @@
 }
 
 
-Handle<Value> Shell::Yield(const Arguments& args) {
-  v8::Unlocker unlocker(args.GetIsolate());
-  return Undefined(args.GetIsolate());
-}
-
-
 Handle<Value> Shell::Quit(const Arguments& args) {
   int exit_code = args[0]->Int32Value();
   OnExit();
diff --git a/src/d8.h b/src/d8.h
index 621ac74..2789c07 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -298,13 +298,8 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 #endif  // V8_SHARED
 
-#ifdef WIN32
-#undef Yield
-#endif
-
   static Handle<Value> Print(const Arguments& args);
   static Handle<Value> Write(const Arguments& args);
-  static Handle<Value> Yield(const Arguments& args);
   static Handle<Value> Quit(const Arguments& args);
   static Handle<Value> Version(const Arguments& args);
   static Handle<Value> EnableProfiler(const Arguments& args);
diff --git a/src/d8.js b/src/d8.js
index 1ff0ce8..df10461 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -2214,7 +2214,8 @@
       return x.toString();
     case "string":
       return "\"" + x.toString() + "\"";
-    // TODO(rossberg): add symbol case
+    case "symbol":
+      return "Symbol(" + (x.name ? Stringify(x.name, depth) : "") + ")"
     case "object":
       if (x === null) return "null";
       if (x.constructor && x.constructor.name === "Array") {
diff --git a/src/debug.cc b/src/debug.cc
index 7a876e7..91af9cc 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3761,8 +3761,8 @@
 
 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
     : Thread("v8:MsgDispHelpr"),
-      sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
-      already_signalled_(false) {
+      isolate_(isolate), sem_(OS::CreateSemaphore(0)),
+      mutex_(OS::CreateMutex()), already_signalled_(false) {
 }
 
 
@@ -3785,7 +3785,6 @@
 
 
 void MessageDispatchHelperThread::Run() {
-  Isolate* isolate = Isolate::Current();
   while (true) {
     sem_->Wait();
     {
@@ -3793,8 +3792,8 @@
       already_signalled_ = false;
     }
     {
-      Locker locker(reinterpret_cast<v8::Isolate*>(isolate));
-      isolate->debugger()->CallMessageDispatchHandler();
+      Locker locker(reinterpret_cast<v8::Isolate*>(isolate_));
+      isolate_->debugger()->CallMessageDispatchHandler();
     }
   }
 }
diff --git a/src/debug.h b/src/debug.h
index c7f0681..459073f 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1041,6 +1041,7 @@
  private:
   void Run();
 
+  Isolate* isolate_;
   Semaphore* const sem_;
   Mutex* const mutex_;
   bool already_signalled_;
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 8a07afe..601faf7 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1280,29 +1280,37 @@
   }
 
   intptr_t caller_arg_count = 0;
-  if (descriptor->stack_parameter_count_ != NULL) {
-    caller_arg_count =
-        input_->GetRegister(descriptor->stack_parameter_count_->code());
-  }
+  bool arg_count_known = descriptor->stack_parameter_count_ == NULL;
 
   // Build the Arguments object for the caller's parameters and a pointer to it.
   output_frame_offset -= kPointerSize;
-  value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
-      (caller_arg_count - 1) * kPointerSize;
-  output_frame->SetFrameSlot(output_frame_offset, value);
+  int args_arguments_offset = output_frame_offset;
+  intptr_t the_hole = reinterpret_cast<intptr_t>(
+      isolate_->heap()->the_hole_value());
+  if (arg_count_known) {
+    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
+        (caller_arg_count - 1) * kPointerSize;
+  } else {
+    value = the_hole;
+  }
+
+  output_frame->SetFrameSlot(args_arguments_offset, value);
   if (trace_) {
     PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-           V8PRIxPTR " ; args.arguments\n",
-           top_address + output_frame_offset, output_frame_offset, value);
+           V8PRIxPTR " ; args.arguments %s\n",
+           top_address + args_arguments_offset, args_arguments_offset, value,
+           arg_count_known ? "" : "(the hole)");
   }
 
   output_frame_offset -= kPointerSize;
-  value = caller_arg_count;
-  output_frame->SetFrameSlot(output_frame_offset, value);
+  int length_frame_offset = output_frame_offset;
+  value = arg_count_known ? caller_arg_count : the_hole;
+  output_frame->SetFrameSlot(length_frame_offset, value);
   if (trace_) {
     PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-           V8PRIxPTR " ; args.length\n",
-           top_address + output_frame_offset, output_frame_offset, value);
+           V8PRIxPTR " ; args.length %s\n",
+           top_address + length_frame_offset, length_frame_offset, value,
+           arg_count_known ? "" : "(the hole)");
   }
 
   output_frame_offset -= kPointerSize;
@@ -1321,6 +1329,20 @@
     DoTranslateCommand(iterator, 0, output_frame_offset);
   }
 
+  if (!arg_count_known) {
+    DoTranslateCommand(iterator, 0, length_frame_offset,
+                       TRANSLATED_VALUE_IS_NATIVE);
+    caller_arg_count = output_frame->GetFrameSlot(length_frame_offset);
+    value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
+        (caller_arg_count - 1) * kPointerSize;
+    output_frame->SetFrameSlot(args_arguments_offset, value);
+    if (trace_) {
+      PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+             V8PRIxPTR " ; args.arguments\n",
+             top_address + args_arguments_offset, args_arguments_offset, value);
+    }
+  }
+
   ASSERT(0 == output_frame_offset);
 
   // Copy the double registers from the input into the output frame.
@@ -1331,8 +1353,9 @@
 
   // Compute this frame's PC, state, and continuation.
   Code* trampoline = NULL;
-  int extra = descriptor->extra_expression_stack_count_;
-  StubFailureTrampolineStub(extra).FindCodeInCache(&trampoline, isolate_);
+  StubFunctionMode function_mode = descriptor->function_mode_;
+  StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
+                                                           isolate_);
   ASSERT(trampoline != NULL);
   output_frame->SetPc(reinterpret_cast<intptr_t>(
       trampoline->instruction_start()));
@@ -1476,12 +1499,25 @@
 #endif
 
 
+static const char* TraceValueType(bool is_smi, bool is_native) {
+  if (is_native) {
+    return "native";
+  } else if (is_smi) {
+    return "smi";
+  }
+
+  return "heap number";
+}
+
+
 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
-                                     int frame_index,
-                                     unsigned output_offset) {
+    int frame_index,
+    unsigned output_offset,
+    DeoptimizerTranslatedValueType value_type) {
   disasm::NameConverter converter;
   // A GC-safe temporary placeholder that we can put in the output frame.
   const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
+  bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE;
 
   // Ignore commands marked as duplicate and act on the first non-duplicate.
   Translation::Opcode opcode =
@@ -1524,7 +1560,9 @@
     case Translation::INT32_REGISTER: {
       int input_reg = iterator->Next();
       intptr_t value = input_->GetRegister(input_reg);
-      bool is_smi = Smi::IsValid(value);
+      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
+          Smi::IsValid(value);
+
       if (trace_) {
         PrintF(
             "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
@@ -1532,15 +1570,18 @@
             output_offset,
             value,
             converter.NameOfCPURegister(input_reg),
-            is_smi ? "smi" : "heap number");
+            TraceValueType(is_smi, is_native));
       }
       if (is_smi) {
         intptr_t tagged_value =
             reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
+        output_[frame_index]->SetFrameSlot(output_offset, value);
       } else {
         // We save the untagged value on the side and store a GC-safe
         // temporary placeholder in the frame.
+        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
                        static_cast<double>(static_cast<int32_t>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
@@ -1551,7 +1592,8 @@
     case Translation::UINT32_REGISTER: {
       int input_reg = iterator->Next();
       uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
-      bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
+          (value <= static_cast<uintptr_t>(Smi::kMaxValue));
       if (trace_) {
         PrintF(
             "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
@@ -1560,15 +1602,18 @@
             output_offset,
             value,
             converter.NameOfCPURegister(input_reg),
-            is_smi ? "smi" : "heap number");
+            TraceValueType(is_smi, is_native));
       }
       if (is_smi) {
         intptr_t tagged_value =
             reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
+        output_[frame_index]->SetFrameSlot(output_offset, value);
       } else {
         // We save the untagged value on the side and store a GC-safe
         // temporary placeholder in the frame.
+        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
                        static_cast<double>(static_cast<uint32_t>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
@@ -1617,7 +1662,8 @@
       unsigned input_offset =
           input_->GetOffsetFromSlotIndex(input_slot_index);
       intptr_t value = input_->GetFrameSlot(input_offset);
-      bool is_smi = Smi::IsValid(value);
+      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
+          Smi::IsValid(value);
       if (trace_) {
         PrintF("    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
@@ -1625,15 +1671,18 @@
                output_offset,
                value,
                input_offset,
-               is_smi ? "smi" : "heap number");
+               TraceValueType(is_smi, is_native));
       }
       if (is_smi) {
         intptr_t tagged_value =
             reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
+        output_[frame_index]->SetFrameSlot(output_offset, value);
       } else {
         // We save the untagged value on the side and store a GC-safe
         // temporary placeholder in the frame.
+        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
                        static_cast<double>(static_cast<int32_t>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
@@ -1647,7 +1696,8 @@
           input_->GetOffsetFromSlotIndex(input_slot_index);
       uintptr_t value =
           static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
-      bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
+      bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
+          (value <= static_cast<uintptr_t>(Smi::kMaxValue));
       if (trace_) {
         PrintF("    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
@@ -1655,15 +1705,18 @@
                output_offset,
                value,
                input_offset,
-               is_smi ? "smi" : "heap number");
+               TraceValueType(is_smi, is_native));
       }
       if (is_smi) {
         intptr_t tagged_value =
             reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
+      } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
+        output_[frame_index]->SetFrameSlot(output_offset, value);
       } else {
         // We save the untagged value on the side and store a GC-safe
         // temporary placeholder in the frame.
+        ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
                        static_cast<double>(static_cast<uint32_t>(value)));
         output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
@@ -2130,7 +2183,8 @@
   ASSERT(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
          desc.instr_size);
   chunk->CommitArea(desc.instr_size);
-  CopyBytes(chunk->area_start(), desc.buffer, desc.instr_size);
+  CopyBytes(chunk->area_start(), desc.buffer,
+      static_cast<size_t>(desc.instr_size));
   CPU::FlushICache(chunk->area_start(), desc.instr_size);
 
   if (type == EAGER) {
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index db0cc0b..895ed66 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -356,9 +356,17 @@
                                   bool is_setter_stub_frame);
   void DoComputeCompiledStubFrame(TranslationIterator* iterator,
                                   int frame_index);
+
+  enum DeoptimizerTranslatedValueType {
+    TRANSLATED_VALUE_IS_NATIVE,
+    TRANSLATED_VALUE_IS_TAGGED
+  };
+
   void DoTranslateCommand(TranslationIterator* iterator,
-                          int frame_index,
-                          unsigned output_offset);
+      int frame_index,
+      unsigned output_offset,
+      DeoptimizerTranslatedValueType value_type = TRANSLATED_VALUE_IS_TAGGED);
+
   // Translate a command for OSR.  Updates the input offset to be used for
   // the next command.  Returns false if translation of the command failed
   // (e.g., a number conversion failed) and may or may not have updated the
diff --git a/src/elements-kind.h b/src/elements-kind.h
index cb3bb9c..da15192 100644
--- a/src/elements-kind.h
+++ b/src/elements-kind.h
@@ -110,10 +110,15 @@
 }
 
 
+inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) {
+  return kind == EXTERNAL_DOUBLE_ELEMENTS ||
+      kind == EXTERNAL_FLOAT_ELEMENTS;
+}
+
+
 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
   return IsFastDoubleElementsKind(kind) ||
-      kind == EXTERNAL_DOUBLE_ELEMENTS ||
-      kind == EXTERNAL_FLOAT_ELEMENTS;
+      IsExternalFloatOrDoubleElementsKind(kind);
 }
 
 
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 06d114f..ea72168 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -148,6 +148,9 @@
             "enable harmony collections (sets, maps, and weak maps)")
 DEFINE_bool(harmony_observation, false,
             "enable harmony object observation (implies harmony collections")
+DEFINE_bool(harmony_typed_arrays, false,
+            "enable harmony typed arrays")
+DEFINE_bool(harmony_generators, false, "enable harmony generators")
 DEFINE_bool(harmony, false, "enable all harmony features (except typeof)")
 DEFINE_implication(harmony, harmony_scoping)
 DEFINE_implication(harmony, harmony_modules)
@@ -155,8 +158,10 @@
 DEFINE_implication(harmony, harmony_proxies)
 DEFINE_implication(harmony, harmony_collections)
 DEFINE_implication(harmony, harmony_observation)
+DEFINE_implication(harmony, harmony_generators)
 DEFINE_implication(harmony_modules, harmony_scoping)
 DEFINE_implication(harmony_observation, harmony_collections)
+DEFINE_implication(harmony, harmony_typed_arrays)
 
 // Flags for experimental implementation features.
 DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
diff --git a/src/frames.cc b/src/frames.cc
index ed407e7..aaf8c79 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -1311,18 +1311,19 @@
 
 
 Code* StubFailureTrampolineFrame::unchecked_code() const {
-  int i = 0;
-  for (; i <= StubFailureTrampolineStub::kMaxExtraExpressionStackCount; ++i) {
-    Code* trampoline;
-    StubFailureTrampolineStub(i).FindCodeInCache(&trampoline, isolate());
-    ASSERT(trampoline != NULL);
-    Address current_pc = pc();
-    Address code_start = trampoline->instruction_start();
-    Address code_end = code_start + trampoline->instruction_size();
-    if (code_start <= current_pc && current_pc < code_end) {
-      return trampoline;
-    }
+  Code* trampoline;
+  StubFailureTrampolineStub(NOT_JS_FUNCTION_STUB_MODE).
+      FindCodeInCache(&trampoline, isolate());
+  if (trampoline->contains(pc())) {
+    return trampoline;
   }
+
+  StubFailureTrampolineStub(JS_FUNCTION_STUB_MODE).
+      FindCodeInCache(&trampoline, isolate());
+  if (trampoline->contains(pc())) {
+    return trampoline;
+  }
+
   UNREACHABLE();
   return NULL;
 }
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index cb6f228..1c6a0b9 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -232,6 +232,12 @@
 }
 
 
+void BreakableStatementChecker::VisitYield(Yield* expr) {
+  // Yield is breakable if the expression is.
+  Visit(expr->expression());
+}
+
+
 void BreakableStatementChecker::VisitThrow(Throw* expr) {
   // Throw is breakable if the expression is.
   Visit(expr->exception());
@@ -1538,6 +1544,28 @@
 }
 
 
+void FullCodeGenerator::VisitYield(Yield* expr) {
+  if (expr->is_delegating_yield())
+    UNIMPLEMENTED();
+
+  Comment cmnt(masm_, "[ Yield");
+  VisitForAccumulatorValue(expr->expression());
+  // TODO(wingo): Assert that the operand stack depth is 0, at least while
+  // general yield expressions are unimplemented.
+
+  // TODO(wingo): What follows is as in VisitReturnStatement.  Replace it with a
+  // call to a builtin that will resume the generator.
+  NestedStatement* current = nesting_stack_;
+  int stack_depth = 0;
+  int context_length = 0;
+  while (current != NULL) {
+    current = current->Exit(&stack_depth, &context_length);
+  }
+  __ Drop(stack_depth);
+  EmitReturnSequence();
+}
+
+
 void FullCodeGenerator::VisitThrow(Throw* expr) {
   Comment cmnt(masm_, "[ Throw");
   VisitForStackValue(expr->exception());
diff --git a/src/handles-inl.h b/src/handles-inl.h
index fd60a35..b763c86 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -107,7 +107,7 @@
     current->limit = prev_limit_;
     DeleteExtensions(isolate_);
   }
-#ifdef DEBUG
+#ifdef ENABLE_EXTRA_CHECKS
   ZapRange(prev_next_, prev_limit_);
 #endif
 }
diff --git a/src/handles.cc b/src/handles.cc
index 2958d2c..b24a4cd 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -101,12 +101,14 @@
 }
 
 
+#ifdef ENABLE_EXTRA_CHECKS
 void HandleScope::ZapRange(Object** start, Object** end) {
   ASSERT(end - start <= kHandleBlockSize);
   for (Object** p = start; p != end; p++) {
     *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
   }
 }
+#endif
 
 
 Address HandleScope::current_level_address(Isolate* isolate) {
@@ -259,20 +261,6 @@
 }
 
 
-Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
-                                          Handle<Name> key,
-                                          Handle<Object> value,
-                                          PropertyAttributes attributes,
-                                          StrictModeFlag strict_mode) {
-  CALL_HEAP_FUNCTION(object->GetIsolate(),
-                     object->SetPropertyWithInterceptor(*key,
-                                                        *value,
-                                                        attributes,
-                                                        strict_mode),
-                     Object);
-}
-
-
 Handle<Object> GetProperty(Handle<JSReceiver> obj,
                            const char* name) {
   Isolate* isolate = obj->GetIsolate();
@@ -289,19 +277,6 @@
 }
 
 
-Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
-                                          Handle<JSObject> holder,
-                                          Handle<Name> name,
-                                          PropertyAttributes* attributes) {
-  Isolate* isolate = receiver->GetIsolate();
-  CALL_HEAP_FUNCTION(isolate,
-                     holder->GetPropertyWithInterceptor(*receiver,
-                                                        *name,
-                                                        attributes),
-                     Object);
-}
-
-
 Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) {
   const bool skip_hidden_prototypes = false;
   CALL_HEAP_FUNCTION(obj->GetIsolate(),
diff --git a/src/handles.h b/src/handles.h
index 3e408b7..c69713e 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -160,13 +160,14 @@
   // Extend the handle scope making room for more handles.
   static internal::Object** Extend(Isolate* isolate);
 
+#ifdef ENABLE_EXTRA_CHECKS
   // Zaps the handles in the half-open interval [start, end).
   static void ZapRange(internal::Object** start, internal::Object** end);
+#endif
 
-  friend class v8::internal::DeferredHandles;
   friend class v8::HandleScope;
+  friend class v8::internal::DeferredHandles;
   friend class v8::internal::HandleScopeImplementer;
-  friend class v8::ImplementationUtilities;
   friend class v8::internal::Isolate;
 };
 
@@ -232,11 +233,6 @@
                            Handle<Object> obj,
                            Handle<Object> key);
 
-Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
-                                          Handle<JSObject> holder,
-                                          Handle<String> name,
-                                          PropertyAttributes* attributes);
-
 Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value);
 
 Handle<Object> LookupSingleCharacterStringFromCode(Isolate* isolate,
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 9ed65d8..a15b8ef 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -399,7 +399,9 @@
   ASSERT(type != ODDBALL_TYPE);
   ASSERT(type != JS_GLOBAL_PROPERTY_CELL_TYPE);
 
-  if (type < FIRST_NONSTRING_TYPE) {
+  if (type <= LAST_NAME_TYPE) {
+    if (type == SYMBOL_TYPE) return OLD_POINTER_SPACE;
+    ASSERT(type < FIRST_NONSTRING_TYPE);
     // There are four string representations: sequential strings, external
     // strings, cons strings, and sliced strings.
     // Only the latter two contain non-map-word pointers to heap objects.
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index c9f1d50..5c1badf 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -44,72 +44,13 @@
 }
 
 
-void HeapProfiler::ResetSnapshots() {
+void HeapProfiler::DeleteAllSnapshots() {
   Heap* the_heap = heap();
   delete snapshots_;
   snapshots_ = new HeapSnapshotsCollection(the_heap);
 }
 
 
-void HeapProfiler::SetUp() {
-  Isolate* isolate = Isolate::Current();
-  if (isolate->heap_profiler() == NULL) {
-    isolate->set_heap_profiler(new HeapProfiler(isolate->heap()));
-  }
-}
-
-
-void HeapProfiler::TearDown() {
-  Isolate* isolate = Isolate::Current();
-  delete isolate->heap_profiler();
-  isolate->set_heap_profiler(NULL);
-}
-
-
-HeapSnapshot* HeapProfiler::TakeSnapshot(
-    const char* name,
-    int type,
-    v8::ActivityControl* control,
-    v8::HeapProfiler::ObjectNameResolver* resolver) {
-  ASSERT(Isolate::Current()->heap_profiler() != NULL);
-  return Isolate::Current()->heap_profiler()->TakeSnapshotImpl(name,
-                                                               type,
-                                                               control,
-                                                               resolver);
-}
-
-
-HeapSnapshot* HeapProfiler::TakeSnapshot(
-    String* name,
-    int type,
-    v8::ActivityControl* control,
-    v8::HeapProfiler::ObjectNameResolver* resolver) {
-  ASSERT(Isolate::Current()->heap_profiler() != NULL);
-  return Isolate::Current()->heap_profiler()->TakeSnapshotImpl(name,
-                                                               type,
-                                                               control,
-                                                               resolver);
-}
-
-
-void HeapProfiler::StartHeapObjectsTracking() {
-  ASSERT(Isolate::Current()->heap_profiler() != NULL);
-  Isolate::Current()->heap_profiler()->StartHeapObjectsTrackingImpl();
-}
-
-
-void HeapProfiler::StopHeapObjectsTracking() {
-  ASSERT(Isolate::Current()->heap_profiler() != NULL);
-  Isolate::Current()->heap_profiler()->StopHeapObjectsTrackingImpl();
-}
-
-
-SnapshotObjectId HeapProfiler::PushHeapObjectsStats(v8::OutputStream* stream) {
-  ASSERT(Isolate::Current()->heap_profiler() != NULL);
-  return Isolate::Current()->heap_profiler()->PushHeapObjectsStatsImpl(stream);
-}
-
-
 void HeapProfiler::DefineWrapperClass(
     uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback) {
   ASSERT(class_id != v8::HeapProfiler::kPersistentHandleNoClassId);
@@ -129,99 +70,69 @@
 }
 
 
-HeapSnapshot* HeapProfiler::TakeSnapshotImpl(
+HeapSnapshot* HeapProfiler::TakeSnapshot(
     const char* name,
-    int type,
     v8::ActivityControl* control,
     v8::HeapProfiler::ObjectNameResolver* resolver) {
-  HeapSnapshot::Type s_type = static_cast<HeapSnapshot::Type>(type);
-  HeapSnapshot* result =
-      snapshots_->NewSnapshot(s_type, name, next_snapshot_uid_++);
-  bool generation_completed = true;
-  switch (s_type) {
-    case HeapSnapshot::kFull: {
-      HeapSnapshotGenerator generator(result, control, resolver, heap());
-      generation_completed = generator.GenerateSnapshot();
-      break;
+  HeapSnapshot* result = snapshots_->NewSnapshot(name, next_snapshot_uid_++);
+  {
+    HeapSnapshotGenerator generator(result, control, resolver, heap());
+    if (!generator.GenerateSnapshot()) {
+      delete result;
+      result = NULL;
     }
-    default:
-      UNREACHABLE();
-  }
-  if (!generation_completed) {
-    delete result;
-    result = NULL;
   }
   snapshots_->SnapshotGenerationFinished(result);
   return result;
 }
 
 
-HeapSnapshot* HeapProfiler::TakeSnapshotImpl(
+HeapSnapshot* HeapProfiler::TakeSnapshot(
     String* name,
-    int type,
     v8::ActivityControl* control,
     v8::HeapProfiler::ObjectNameResolver* resolver) {
-  return TakeSnapshotImpl(snapshots_->names()->GetName(name), type, control,
-                          resolver);
+  return TakeSnapshot(snapshots_->names()->GetName(name), control, resolver);
 }
 
-void HeapProfiler::StartHeapObjectsTrackingImpl() {
+void HeapProfiler::StartHeapObjectsTracking() {
   snapshots_->StartHeapObjectsTracking();
 }
 
 
-SnapshotObjectId HeapProfiler::PushHeapObjectsStatsImpl(OutputStream* stream) {
+SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) {
   return snapshots_->PushHeapObjectsStats(stream);
 }
 
 
-void HeapProfiler::StopHeapObjectsTrackingImpl() {
+void HeapProfiler::StopHeapObjectsTracking() {
   snapshots_->StopHeapObjectsTracking();
 }
 
 
 size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  size_t size = profiler->snapshots_->GetUsedMemorySize();
-  return size;
+  return snapshots_->GetUsedMemorySize();
 }
 
 
 int HeapProfiler::GetSnapshotsCount() {
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  return profiler->snapshots_->snapshots()->length();
+  return snapshots_->snapshots()->length();
 }
 
 
 HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  return profiler->snapshots_->snapshots()->at(index);
+  return snapshots_->snapshots()->at(index);
 }
 
 
 HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  return profiler->snapshots_->GetSnapshot(uid);
+  return snapshots_->GetSnapshot(uid);
 }
 
 
 SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) {
   if (!obj->IsHeapObject())
     return v8::HeapProfiler::kUnknownObjectId;
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  return profiler->snapshots_->FindObjectId(HeapObject::cast(*obj)->address());
-}
-
-
-void HeapProfiler::DeleteAllSnapshots() {
-  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
-  ASSERT(profiler != NULL);
-  profiler->ResetSnapshots();
+  return snapshots_->FindObjectId(HeapObject::cast(*obj)->address());
 }
 
 
diff --git a/src/heap-profiler.h b/src/heap-profiler.h
index c8c94f5..3f3138d 100644
--- a/src/heap-profiler.h
+++ b/src/heap-profiler.h
@@ -46,30 +46,28 @@
 
 class HeapProfiler {
  public:
-  static void SetUp();
-  static void TearDown();
+  explicit HeapProfiler(Heap* heap);
+  ~HeapProfiler();
 
-  static size_t GetMemorySizeUsedByProfiler();
+  size_t GetMemorySizeUsedByProfiler();
 
-  static HeapSnapshot* TakeSnapshot(
+  HeapSnapshot* TakeSnapshot(
       const char* name,
-      int type,
       v8::ActivityControl* control,
       v8::HeapProfiler::ObjectNameResolver* resolver);
-  static HeapSnapshot* TakeSnapshot(
+  HeapSnapshot* TakeSnapshot(
       String* name,
-      int type,
       v8::ActivityControl* control,
       v8::HeapProfiler::ObjectNameResolver* resolver);
 
-  static void StartHeapObjectsTracking();
-  static void StopHeapObjectsTracking();
-  static SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
-  static int GetSnapshotsCount();
-  static HeapSnapshot* GetSnapshot(int index);
-  static HeapSnapshot* FindSnapshot(unsigned uid);
-  static SnapshotObjectId GetSnapshotObjectId(Handle<Object> obj);
-  static void DeleteAllSnapshots();
+  void StartHeapObjectsTracking();
+  void StopHeapObjectsTracking();
+  SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
+  int GetSnapshotsCount();
+  HeapSnapshot* GetSnapshot(int index);
+  HeapSnapshot* FindSnapshot(unsigned uid);
+  SnapshotObjectId GetSnapshotObjectId(Handle<Object> obj);
+  void DeleteAllSnapshots();
 
   void ObjectMoveEvent(Address from, Address to);
 
@@ -83,24 +81,6 @@
   }
 
  private:
-  explicit HeapProfiler(Heap* heap);
-  ~HeapProfiler();
-  HeapSnapshot* TakeSnapshotImpl(
-      const char* name,
-      int type,
-      v8::ActivityControl* control,
-      v8::HeapProfiler::ObjectNameResolver* resolver);
-  HeapSnapshot* TakeSnapshotImpl(
-      String* name,
-      int type,
-      v8::ActivityControl* control,
-      v8::HeapProfiler::ObjectNameResolver* resolver);
-  void ResetSnapshots();
-
-  void StartHeapObjectsTrackingImpl();
-  void StopHeapObjectsTrackingImpl();
-  SnapshotObjectId PushHeapObjectsStatsImpl(OutputStream* stream);
-
   Heap* heap() const { return snapshots_->heap(); }
 
   HeapSnapshotsCollection* snapshots_;
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 824e507..fb239aa 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -189,7 +189,7 @@
   static const int kExpectedHeapGraphEdgeSize = 12;
   static const int kExpectedHeapEntrySize = 24;
   static const int kExpectedHeapSnapshotsCollectionSize = 100;
-  static const int kExpectedHeapSnapshotSize = 136;
+  static const int kExpectedHeapSnapshotSize = 132;
   static const size_t kMaxSerializableSnapshotRawSize = 256 * MB;
 };
 
@@ -197,7 +197,7 @@
   static const int kExpectedHeapGraphEdgeSize = 24;
   static const int kExpectedHeapEntrySize = 32;
   static const int kExpectedHeapSnapshotsCollectionSize = 152;
-  static const int kExpectedHeapSnapshotSize = 168;
+  static const int kExpectedHeapSnapshotSize = 160;
   static const uint64_t kMaxSerializableSnapshotRawSize =
       static_cast<uint64_t>(6000) * MB;
 };
@@ -205,11 +205,9 @@
 }  // namespace
 
 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
-                           HeapSnapshot::Type type,
                            const char* title,
                            unsigned uid)
     : collection_(collection),
-      type_(type),
       title_(title),
       uid_(uid),
       root_index_(HeapEntry::kNoEntry),
@@ -599,11 +597,10 @@
 }
 
 
-HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(HeapSnapshot::Type type,
-                                                   const char* name,
+HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name,
                                                    unsigned uid) {
   is_tracking_objects_ = true;  // Start watching for heap objects moves.
-  return new HeapSnapshot(this, type, name, uid);
+  return new HeapSnapshot(this, name, uid);
 }
 
 
@@ -2410,7 +2407,6 @@
 
 HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() {
   HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(),
-                                          HeapSnapshot::kFull,
                                           snapshot_->title(),
                                           snapshot_->uid());
   result->AddRootEntry();
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index 08c2fe7..a4fcef7 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -157,18 +157,12 @@
 // HeapSnapshotGenerator fills in a HeapSnapshot.
 class HeapSnapshot {
  public:
-  enum Type {
-    kFull = v8::HeapSnapshot::kFull
-  };
-
   HeapSnapshot(HeapSnapshotsCollection* collection,
-               Type type,
                const char* title,
                unsigned uid);
   void Delete();
 
   HeapSnapshotsCollection* collection() { return collection_; }
-  Type type() { return type_; }
   const char* title() { return title_; }
   unsigned uid() { return uid_; }
   size_t RawSnapshotSize() const;
@@ -203,7 +197,6 @@
 
  private:
   HeapSnapshotsCollection* collection_;
-  Type type_;
   const char* title_;
   unsigned uid_;
   int root_index_;
@@ -305,8 +298,7 @@
   void StartHeapObjectsTracking() { is_tracking_objects_ = true; }
   void StopHeapObjectsTracking() { ids_.StopHeapObjectsTracking(); }
 
-  HeapSnapshot* NewSnapshot(
-      HeapSnapshot::Type type, const char* name, unsigned uid);
+  HeapSnapshot* NewSnapshot(const char* name, unsigned uid);
   void SnapshotGenerationFinished(HeapSnapshot* snapshot);
   List<HeapSnapshot*>* snapshots() { return &snapshots_; }
   HeapSnapshot* GetSnapshot(unsigned uid);
diff --git a/src/heap.cc b/src/heap.cc
index 949661d..fafcb64 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1779,6 +1779,10 @@
                     &ObjectEvacuationStrategy<POINTER_OBJECT>::
                         template VisitSpecialized<SlicedString::kSize>);
 
+    table_.Register(kVisitSymbol,
+                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
+                        template VisitSpecialized<Symbol::kSize>);
+
     table_.Register(kVisitSharedFunctionInfo,
                     &ObjectEvacuationStrategy<POINTER_OBJECT>::
                         template VisitSpecialized<SharedFunctionInfo::kSize>);
@@ -1854,7 +1858,7 @@
       HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
       Isolate* isolate = heap->isolate();
       if (isolate->logger()->is_logging_code_events() ||
-          CpuProfiler::is_profiling(isolate)) {
+          isolate->cpu_profiler()->is_profiling()) {
         if (target->IsSharedFunctionInfo()) {
           PROFILE(isolate, SharedFunctionInfoMoveEvent(
               source->address(), target->address()));
@@ -2110,7 +2114,7 @@
 void Heap::SelectScavengingVisitorsTable() {
   bool logging_and_profiling =
       isolate()->logger()->is_logging() ||
-      CpuProfiler::is_profiling(isolate()) ||
+      isolate()->cpu_profiler()->is_profiling() ||
       (isolate()->heap_profiler() != NULL &&
        isolate()->heap_profiler()->is_profiling());
 
@@ -3880,7 +3884,7 @@
   Address new_addr = reinterpret_cast<HeapObject*>(result)->address();
 
   // Copy header and instructions.
-  CopyBytes(new_addr, old_addr, static_cast<int>(relocation_offset));
+  CopyBytes(new_addr, old_addr, relocation_offset);
 
   Code* new_code = Code::cast(result);
   new_code->set_relocation_info(ByteArray::cast(reloc_info_array));
@@ -3888,7 +3892,7 @@
   // Copy patched rinfo.
   CopyBytes(new_code->relocation_start(),
             reloc_info.start(),
-            reloc_info.length());
+            static_cast<size_t>(reloc_info.length()));
 
   // Relocate the copy.
   ASSERT(!isolate_->code_range()->exists() ||
@@ -5424,13 +5428,13 @@
 }
 
 
-MaybeObject* Heap::AllocateSymbol(PretenureFlag pretenure) {
+MaybeObject* Heap::AllocateSymbol() {
   // Statically ensure that it is safe to allocate symbols in paged spaces.
   STATIC_ASSERT(Symbol::kSize <= Page::kNonCodeObjectAreaSize);
-  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
 
   Object* result;
-  MaybeObject* maybe = AllocateRaw(Symbol::kSize, space, OLD_DATA_SPACE);
+  MaybeObject* maybe =
+      AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE);
   if (!maybe->ToObject(&result)) return maybe;
 
   HeapObject::cast(result)->set_map_no_write_barrier(symbol_map());
@@ -5446,6 +5450,7 @@
 
   Symbol::cast(result)->set_hash_field(
       Name::kIsNotArrayIndexMask | (hash << Name::kHashShift));
+  Symbol::cast(result)->set_name(undefined_value());
 
   ASSERT(result->IsSymbol());
   return result;
@@ -7465,6 +7470,9 @@
     }
     name = internalized_string;
   }
+  // This cache is cleared only between mark compact passes, so we expect the
+  // cache to only contain old space names.
+  ASSERT(!HEAP->InNewSpace(name));
 
   int index = (Hash(map, name) & kHashMask);
   // After a GC there will be free slots, so we use them in order (this may
diff --git a/src/heap.h b/src/heap.h
index 90f2e60..8992e31 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -213,6 +213,8 @@
   V(prototype_string, "prototype")                                       \
   V(string_string, "string")                                             \
   V(String_string, "String")                                             \
+  V(symbol_string, "symbol")                                             \
+  V(Symbol_string, "Symbol")                                             \
   V(Date_string, "Date")                                                 \
   V(this_string, "this")                                                 \
   V(to_string_string, "toString")                                        \
@@ -220,6 +222,7 @@
   V(undefined_string, "undefined")                                       \
   V(value_of_string, "valueOf")                                          \
   V(stack_string, "stack")                                               \
+  V(toJSON_string, "toJSON")                                             \
   V(InitializeVarGlobal_string, "InitializeVarGlobal")                   \
   V(InitializeConstGlobal_string, "InitializeConstGlobal")               \
   V(KeyedLoadElementMonomorphic_string,                                  \
@@ -879,12 +882,11 @@
       void* external_pointer,
       PretenureFlag pretenure);
 
-  // Allocate a symbol.
+  // Allocate a symbol in old space.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
   // failed.
   // Please note this does not perform a garbage collection.
-  MUST_USE_RESULT MaybeObject* AllocateSymbol(
-      PretenureFlag pretenure = NOT_TENURED);
+  MUST_USE_RESULT MaybeObject* AllocateSymbol();
 
   // Allocate a tenured JS global property cell.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index fc80748..edbffc2 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1277,7 +1277,8 @@
       ToBooleanStub::UNDEFINED |
       ToBooleanStub::NULL_TYPE |
       ToBooleanStub::SPEC_OBJECT |
-      ToBooleanStub::STRING);
+      ToBooleanStub::STRING |
+      ToBooleanStub::SYMBOL);
   if (expected_input_types_.ContainsAnyOf(tagged_types)) {
     return Representation::Tagged();
   } else if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) {
@@ -1467,15 +1468,6 @@
 }
 
 
-void HJSArrayLength::PrintDataTo(StringStream* stream) {
-  value()->PrintNameTo(stream);
-  if (HasTypeCheck()) {
-    stream->Add(" ");
-    typecheck()->PrintNameTo(stream);
-  }
-}
-
-
 HValue* HUnaryMathOperation::Canonicalize() {
   if (op() == kMathFloor) {
     // If the input is integer32 then we replace the floor instruction
@@ -2415,6 +2407,10 @@
 void HLoadNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : "");
+  if (HasTypeCheck()) {
+    stream->Add(" ");
+    typecheck()->PrintNameTo(stream);
+  }
 }
 
 
@@ -2589,6 +2585,10 @@
     return false;
   }
 
+  if (IsExternalArrayElementsKind(elements_kind())) {
+    return false;
+  }
+
   if (hole_mode() == ALLOW_RETURN_HOLE) return true;
 
   if (IsFastDoubleElementsKind(elements_kind())) {
@@ -2611,6 +2611,10 @@
     return false;
   }
 
+  if (IsExternalArrayElementsKind(elements_kind())) {
+    return false;
+  }
+
   return !UsesMustHandleHole();
 }
 
@@ -3036,10 +3040,19 @@
   // If value is an integer or smi or comes from the result of a keyed load or
   // constant then it is either be a non-hole value or in the case of a constant
   // the hole is only being stored explicitly: no need for canonicalization.
-  if (value()->IsLoadKeyed() || value()->IsConstant()) {
+  //
+  // The exception to that is keyed loads from external float or double arrays:
+  // these can load arbitrary representation of NaN.
+
+  if (value()->IsConstant()) {
     return false;
   }
 
+  if (value()->IsLoadKeyed()) {
+    return IsExternalFloatOrDoubleElementsKind(
+        HLoadKeyed::cast(value())->elements_kind());
+  }
+
   if (value()->IsChange()) {
     if (HChange::cast(value())->from().IsInteger32()) {
       return false;
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index f741f29..ad03687 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -134,7 +134,6 @@
   V(IsStringAndBranch)                         \
   V(IsSmiAndBranch)                            \
   V(IsUndetectableAndBranch)                   \
-  V(JSArrayLength)                             \
   V(LeaveInlined)                              \
   V(LoadContextSlot)                           \
   V(LoadElements)                              \
@@ -2392,45 +2391,6 @@
 };
 
 
-class HJSArrayLength: public HTemplateInstruction<2> {
- public:
-  HJSArrayLength(HValue* value, HValue* typecheck,
-                 HType type = HType::Tagged()) {
-    set_type(type);
-    // The length of an array is stored as a tagged value in the array
-    // object. It is guaranteed to be 32 bit integer, but it can be
-    // represented as either a smi or heap number.
-    SetOperandAt(0, value);
-    SetOperandAt(1, typecheck != NULL ? typecheck : value);
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnArrayLengths);
-    SetGVNFlag(kDependsOnMaps);
-  }
-
-  virtual Representation RequiredInputRepresentation(int index) {
-    return Representation::Tagged();
-  }
-
-  virtual void PrintDataTo(StringStream* stream);
-
-  HValue* value() { return OperandAt(0); }
-  HValue* typecheck() {
-    ASSERT(HasTypeCheck());
-    return OperandAt(1);
-  }
-  bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
-
-  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
-
- protected:
-  virtual bool DataEquals(HValue* other_raw) { return true; }
-
- private:
-  virtual bool IsDeletable() const { return true; }
-};
-
-
 class HFixedArrayBaseLength: public HUnaryOperation {
  public:
   explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
@@ -4693,6 +4653,14 @@
     set_representation(Representation::Tagged());
   }
 
+  explicit HParameter(unsigned index,
+                      ParameterKind kind,
+                      Representation r)
+      : index_(index),
+        kind_(kind) {
+    set_representation(r);
+  }
+
   unsigned index() const { return index_; }
   ParameterKind kind() const { return kind_; }
 
@@ -5184,12 +5152,16 @@
 };
 
 
-class HLoadNamedField: public HUnaryOperation {
+class HLoadNamedField: public HTemplateInstruction<2> {
  public:
-  HLoadNamedField(HValue* object, bool is_in_object, int offset)
-      : HUnaryOperation(object),
-        is_in_object_(is_in_object),
+  HLoadNamedField(HValue* object, bool is_in_object, int offset,
+                  HValue* typecheck = NULL)
+      : is_in_object_(is_in_object),
         offset_(offset) {
+    ASSERT(object != NULL);
+    SetOperandAt(0, object);
+    SetOperandAt(1, typecheck != NULL ? typecheck : object);
+
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
     SetGVNFlag(kDependsOnMaps);
@@ -5200,7 +5172,24 @@
     }
   }
 
+  static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object,
+                                         HValue* typecheck,
+                                         HType type = HType::Tagged()) {
+    HLoadNamedField* result = new(zone) HLoadNamedField(
+        object, true, JSArray::kLengthOffset, typecheck);
+    result->set_type(type);
+    result->SetGVNFlag(kDependsOnArrayLengths);
+    result->ClearGVNFlag(kDependsOnInobjectFields);
+    return result;
+  }
+
   HValue* object() { return OperandAt(0); }
+  HValue* typecheck() {
+    ASSERT(HasTypeCheck());
+    return OperandAt(1);
+  }
+
+  bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
   bool is_in_object() const { return is_in_object_; }
   int offset() const { return offset_; }
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 8dbb5dd..abff7b7 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1165,8 +1165,8 @@
   }
   HInstruction* length = NULL;
   if (is_js_array) {
-    length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck,
-                                                     HType::Smi()));
+    length = AddInstruction(
+        HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi()));
   } else {
     length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
   }
@@ -4115,6 +4115,10 @@
 
 
 bool HOptimizedGraphBuilder::BuildGraph() {
+  if (info()->function()->is_generator()) {
+    Bailout("function is a generator");
+    return false;
+  }
   Scope* scope = info()->scope();
   if (scope->HasIllegalRedeclaration()) {
     Bailout("function with illegal redeclaration");
@@ -5083,19 +5087,7 @@
       typecheck->SetSuccessorAt(1, not_spec_object);
       current_block()->Finish(typecheck);
       if_spec_object->AddLeaveInlined(return_value, state);
-      if (!FLAG_harmony_symbols) {
-        not_spec_object->AddLeaveInlined(receiver, state);
-      } else {
-        HHasInstanceTypeAndBranch* symbolcheck =
-          new(zone()) HHasInstanceTypeAndBranch(return_value, SYMBOL_TYPE);
-        HBasicBlock* is_symbol = graph()->CreateBasicBlock();
-        HBasicBlock* not_symbol = graph()->CreateBasicBlock();
-        symbolcheck->SetSuccessorAt(0, is_symbol);
-        symbolcheck->SetSuccessorAt(1, not_symbol);
-        not_spec_object->Finish(symbolcheck);
-        is_symbol->AddLeaveInlined(return_value, state);
-        not_symbol->AddLeaveInlined(receiver, state);
-      }
+      not_spec_object->AddLeaveInlined(receiver, state);
     }
   } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
     // Return from an inlined setter call. The returned value is never used, the
@@ -6299,6 +6291,12 @@
 }
 
 
+void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
+  AddInstruction(new(zone()) HCheckNonSmi(object));
+  AddInstruction(new(zone()) HCheckMaps(object, map, zone()));
+}
+
+
 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
                                                          Handle<Map> map) {
   AddInstruction(new(zone()) HCheckNonSmi(object));
@@ -6410,15 +6408,40 @@
 }
 
 
-void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
+bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad(
     Property* expr,
     HValue* object,
     SmallMapList* types,
     Handle<String> name) {
+  if (!name->Equals(isolate()->heap()->length_string())) return false;
+
+  for (int i = 0; i < types->length(); i++) {
+    if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
+  }
+
+  AddInstruction(new(zone()) HCheckNonSmi(object));
+  HInstruction* typecheck =
+    AddInstruction(HCheckInstanceType::NewIsJSArray(object, zone()));
+  HInstruction* instr =
+    HLoadNamedField::NewArrayLength(zone(), object, typecheck);
+  instr->set_position(expr->position());
+  ast_context()->ReturnInstruction(instr, expr->id());
+  return true;
+}
+
+
+void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
+    HValue* object,
+    SmallMapList* types,
+    Handle<String> name) {
   int count = 0;
   int previous_field_offset = 0;
   bool previous_field_is_in_object = false;
   bool is_monomorphic_field = true;
+
+  if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
+    return;
+
   Handle<Map> map;
   LookupResult lookup(isolate());
   for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
@@ -6985,6 +7008,12 @@
 }
 
 
+void HOptimizedGraphBuilder::VisitYield(Yield* expr) {
+  // Generators are not optimized, so we should never get here.
+  UNREACHABLE();
+}
+
+
 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
@@ -7054,16 +7083,25 @@
     Handle<Map> map) {
   // Handle a load from a known field.
   ASSERT(!map->is_dictionary_map());
+
+  // Handle access to various length properties
+  if (name->Equals(isolate()->heap()->length_string())) {
+    if (map->instance_type() == JS_ARRAY_TYPE) {
+      AddCheckMapsWithTransitions(object, map);
+      return HLoadNamedField::NewArrayLength(zone(), object, object);
+    }
+  }
+
   LookupResult lookup(isolate());
   map->LookupDescriptor(NULL, *name, &lookup);
   if (lookup.IsField()) {
-    AddCheckMapsWithTransitions(object, map);
+    AddCheckMap(object, map);
     return BuildLoadNamedField(object, map, &lookup);
   }
 
   // Handle a load of a constant known function.
   if (lookup.IsConstantFunction()) {
-    AddCheckMapsWithTransitions(object, map);
+    AddCheckMap(object, map);
     Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
     return new(zone()) HConstant(function, Representation::Tagged());
   }
@@ -7074,7 +7112,7 @@
     Handle<JSObject> prototype(JSObject::cast(map->prototype()));
     Handle<JSObject> holder(lookup.holder());
     Handle<Map> holder_map(holder->map());
-    AddCheckMapsWithTransitions(object, map);
+    AddCheckMap(object, map);
     HInstruction* holder_value = AddInstruction(
         new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
     return BuildLoadNamedField(holder_value, holder_map, &lookup);
@@ -7085,7 +7123,7 @@
     Handle<JSObject> prototype(JSObject::cast(map->prototype()));
     Handle<JSObject> holder(lookup.holder());
     Handle<Map> holder_map(holder->map());
-    AddCheckMapsWithTransitions(object, map);
+    AddCheckMap(object, map);
     AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
     Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
     return new(zone()) HConstant(function, Representation::Tagged());
@@ -7343,8 +7381,9 @@
 
         set_current_block(if_jsarray);
         HInstruction* length;
-        length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck,
-                                                           HType::Smi()));
+        length = AddInstruction(
+            HLoadNamedField::NewArrayLength(zone(), object, typecheck,
+                                            HType::Smi()));
         checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
         access = AddInstruction(BuildFastElementAccess(
             elements, checked_key, val, elements_kind_branch,
@@ -7545,13 +7584,7 @@
   CHECK_ALIVE(VisitForValue(expr->obj()));
 
   HInstruction* instr = NULL;
-  if (expr->AsProperty()->IsArrayLength()) {
-    HValue* array = Pop();
-    AddInstruction(new(zone()) HCheckNonSmi(array));
-    HInstruction* mapcheck =
-        AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone()));
-    instr = new(zone()) HJSArrayLength(array, mapcheck);
-  } else if (expr->IsStringLength()) {
+  if (expr->IsStringLength()) {
     HValue* string = Pop();
     AddInstruction(new(zone()) HCheckNonSmi(string));
     AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
@@ -10080,16 +10113,6 @@
 }
 
 
-void HOptimizedGraphBuilder::GenerateIsSymbol(CallRuntime* call) {
-  ASSERT(call->arguments()->length() == 1);
-  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
-  HValue* value = Pop();
-  HHasInstanceTypeAndBranch* result =
-      new(zone()) HHasInstanceTypeAndBranch(value, SYMBOL_TYPE);
-  return ast_context()->ReturnControl(result, call->id());
-}
-
-
 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) {
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 6dea1a6..ef3679e 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1351,6 +1351,10 @@
                                        HValue* object,
                                        SmallMapList* types,
                                        Handle<String> name);
+  bool HandlePolymorphicArrayLengthLoad(Property* expr,
+                                        HValue* object,
+                                        SmallMapList* types,
+                                        Handle<String> name);
   void HandlePolymorphicStoreNamedField(Assignment* expr,
                                         HValue* object,
                                         HValue* value,
@@ -1425,6 +1429,8 @@
                                           Property* expr,
                                           Handle<Map> map);
 
+  void AddCheckMap(HValue* object, Handle<Map> map);
+
   void AddCheckMapsWithTransitions(HValue* object,
                                    Handle<Map> map);
 
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index afb1c03..e861db3 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -216,8 +216,7 @@
       // eax: initial map
       __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
       __ shl(edi, kPointerSizeLog2);
-      __ AllocateInNewSpace(
-          edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
+      __ Allocate(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
       // Allocated the JSObject, now initialize the fields.
       // eax: initial map
       // ebx: JSObject
@@ -280,15 +279,15 @@
       // ebx: JSObject
       // edi: start of next object (will be start of FixedArray)
       // edx: number of elements in properties array
-      __ AllocateInNewSpace(FixedArray::kHeaderSize,
-                            times_pointer_size,
-                            edx,
-                            REGISTER_VALUE_IS_INT32,
-                            edi,
-                            ecx,
-                            no_reg,
-                            &undo_allocation,
-                            RESULT_CONTAINS_TOP);
+      __ Allocate(FixedArray::kHeaderSize,
+                  times_pointer_size,
+                  edx,
+                  REGISTER_VALUE_IS_INT32,
+                  edi,
+                  ecx,
+                  no_reg,
+                  &undo_allocation,
+                  RESULT_CONTAINS_TOP);
 
       // Initialize the FixedArray.
       // ebx: JSObject
@@ -409,10 +408,6 @@
     __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
     __ j(above_equal, &exit);
 
-    // Symbols are "objects".
-    __ CmpInstanceType(ecx, SYMBOL_TYPE);
-    __ j(equal, &exit);
-
     // Throw away the result of the constructor invocation and use the
     // on-stack receiver as the result.
     __ bind(&use_receiver);
@@ -1129,15 +1124,15 @@
   // Allocate the JSArray object together with space for a FixedArray with the
   // requested elements.
   STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
-  __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
-                        times_pointer_size,
-                        array_size,
-                        REGISTER_VALUE_IS_SMI,
-                        result,
-                        elements_array_end,
-                        scratch,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSArray::kSize + FixedArray::kHeaderSize,
+              times_pointer_size,
+              array_size,
+              REGISTER_VALUE_IS_SMI,
+              result,
+              elements_array_end,
+              scratch,
+              gc_required,
+              TAG_OBJECT);
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index b30d519..9b77c50 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -100,7 +100,7 @@
   // stack param count needs (constructor pointer, and single argument)
   descriptor->stack_parameter_count_ = &eax;
   descriptor->register_params_ = registers;
-  descriptor->extra_expression_stack_count_ = 1;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
       FUNCTION_ADDR(ArrayConstructor_StubFailure);
 }
@@ -632,6 +632,14 @@
     __ bind(&not_string);
   }
 
+  if (types_.Contains(SYMBOL)) {
+    // Symbol value -> true.
+    Label not_symbol;
+    __ CmpInstanceType(map, SYMBOL_TYPE);
+    __ j(not_equal, &not_symbol, Label::kNear);
+    __ bind(&not_symbol);
+  }
+
   if (types_.Contains(HEAP_NUMBER)) {
     // heap number -> false iff +0, -0, or NaN.
     Label not_heap_number, false_result;
@@ -3296,25 +3304,6 @@
 }
 
 
-void ArrayLengthStub::Generate(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  if (kind() == Code::KEYED_LOAD_IC) {
-    __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
-    __ j(not_equal, &miss);
-  }
-
-  StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
-  __ bind(&miss);
-  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
-}
-
-
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- ecx    : name
@@ -3569,7 +3558,7 @@
   __ add(ebx, Immediate(Heap::kArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
-  __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
+  __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
 
   // eax = address of new object(s) (tagged)
   // ecx = argument count (tagged)
@@ -3767,7 +3756,7 @@
   __ add(ecx, Immediate(Heap::kArgumentsObjectSizeStrict));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
+  __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
 
   // Get the arguments boilerplate from the current native context.
   __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
@@ -4291,15 +4280,15 @@
   // Allocate RegExpResult followed by FixedArray with size in ebx.
   // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
   // Elements:  [Map][Length][..elements..]
-  __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
-                        times_pointer_size,
-                        ebx,  // In: Number of elements as a smi
-                        REGISTER_VALUE_IS_SMI,
-                        eax,  // Out: Start of allocation (tagged).
-                        ecx,  // Out: End of allocation.
-                        edx,  // Scratch register
-                        &slowcase,
-                        TAG_OBJECT);
+  __ Allocate(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+              times_pointer_size,
+              ebx,  // In: Number of elements as a smi
+              REGISTER_VALUE_IS_SMI,
+              eax,  // Out: Start of allocation (tagged).
+              ecx,  // Out: End of allocation.
+              edx,  // Scratch register
+              &slowcase,
+              TAG_OBJECT);
   // eax: Start of allocated area, object-tagged.
 
   // Set JSArray map to global.regexp_result_map().
@@ -4536,6 +4525,7 @@
 
   // Identical objects can be compared fast, but there are some tricky cases
   // for NaN and undefined.
+  Label generic_heap_number_comparison;
   {
     Label not_identical;
     __ cmp(eax, edx);
@@ -4552,12 +4542,11 @@
       __ bind(&check_for_nan);
     }
 
-    // Test for NaN. Sadly, we can't just compare to factory->nan_value(),
-    // so we do the second best thing - test it ourselves.
-    Label heap_number;
+    // Test for NaN. Compare heap numbers in a general way,
+    // to hanlde NaNs correctly.
     __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
            Immediate(masm->isolate()->factory()->heap_number_map()));
-    __ j(equal, &heap_number, Label::kNear);
+    __ j(equal, &generic_heap_number_comparison, Label::kNear);
     if (cc != equal) {
       // Call runtime on identical JSObjects.  Otherwise return equal.
       __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
@@ -4566,37 +4555,6 @@
     __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
     __ ret(0);
 
-    __ bind(&heap_number);
-    // It is a heap number, so return non-equal if it's NaN and equal if
-    // it's not NaN.
-    // The representation of NaN values has all exponent bits (52..62) set,
-    // and not all mantissa bits (0..51) clear.
-    // We only accept QNaNs, which have bit 51 set.
-    // Read top bits of double representation (second word of value).
-
-    // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
-    // all bits in the mask are set. We only need to check the word
-    // that contains the exponent and high bit of the mantissa.
-    STATIC_ASSERT(((kQuietNaNHighBitsMask << 1) & 0x80000000u) != 0);
-    __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
-    __ Set(eax, Immediate(0));
-    // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
-    // bits.
-    __ add(edx, edx);
-    __ cmp(edx, kQuietNaNHighBitsMask << 1);
-    if (cc == equal) {
-      STATIC_ASSERT(EQUAL != 1);
-      __ setcc(above_equal, eax);
-      __ ret(0);
-    } else {
-      Label nan;
-      __ j(above_equal, &nan, Label::kNear);
-      __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
-      __ ret(0);
-      __ bind(&nan);
-      __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
-      __ ret(0);
-    }
 
     __ bind(&not_identical);
   }
@@ -4676,6 +4634,7 @@
   // Generate the number comparison code.
   Label non_number_comparison;
   Label unordered;
+  __ bind(&generic_heap_number_comparison);
   if (CpuFeatures::IsSupported(SSE2)) {
     CpuFeatureScope use_sse2(masm, SSE2);
     CpuFeatureScope use_cmov(masm, CMOV);
@@ -7836,8 +7795,10 @@
   __ mov(ebx, MemOperand(ebp, parameter_count_offset));
   masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
   __ pop(ecx);
-  __ lea(esp, MemOperand(esp, ebx, times_pointer_size,
-                         extra_expression_stack_count_ * kPointerSize));
+  int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
+      ? kPointerSize
+      : 0;
+  __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset));
   __ jmp(ecx);  // Return to IC Miss stub, continuation still on stack.
 }
 
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 586ffef..550c83d 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -450,9 +450,8 @@
   // edi: length of source FixedArray (smi-tagged)
   AllocationFlags flags =
       static_cast<AllocationFlags>(TAG_OBJECT | DOUBLE_ALIGNMENT);
-  __ AllocateInNewSpace(FixedDoubleArray::kHeaderSize, times_8,
-                        edi, REGISTER_VALUE_IS_SMI,
-                        eax, ebx, no_reg, &gc_required, flags);
+  __ Allocate(FixedDoubleArray::kHeaderSize, times_8, edi,
+              REGISTER_VALUE_IS_SMI, eax, ebx, no_reg, &gc_required, flags);
 
   // eax: destination FixedDoubleArray
   // edi: number of elements
@@ -589,7 +588,7 @@
   // Allocate new FixedArray.
   // ebx: length of source FixedDoubleArray (smi-tagged)
   __ lea(edi, Operand(ebx, times_2, FixedArray::kHeaderSize));
-  __ AllocateInNewSpace(edi, eax, esi, no_reg, &gc_required, TAG_OBJECT);
+  __ Allocate(edi, eax, esi, no_reg, &gc_required, TAG_OBJECT);
 
   // eax: destination FixedArray
   // ebx: number of elements
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index ebc3a2b..efbdf13 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2567,7 +2567,6 @@
 
 
 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
-  // TODO(rossberg): incorporate symbols.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
 
@@ -2703,28 +2702,6 @@
 }
 
 
-void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  ASSERT(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  __ JumpIfSmi(eax, if_false);
-  __ CmpObjectType(eax, SYMBOL_TYPE, ebx);
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  Split(equal, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -4275,6 +4252,10 @@
     __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
               1 << Map::kIsUndetectable);
     Split(zero, if_true, if_false, fall_through);
+  } else if (check->Equals(isolate()->heap()->symbol_string())) {
+    __ JumpIfSmi(eax, if_false);
+    __ CmpObjectType(eax, SYMBOL_TYPE, edx);
+    Split(equal, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->boolean_string())) {
     __ cmp(eax, isolate()->factory()->true_value());
     __ j(equal, if_true);
@@ -4306,10 +4287,6 @@
       __ cmp(eax, isolate()->factory()->null_value());
       __ j(equal, if_true);
     }
-    if (FLAG_harmony_symbols) {
-      __ CmpObjectType(eax, SYMBOL_TYPE, edx);
-      __ j(equal, if_true);
-    }
     __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx);
     __ j(below, if_false);
     __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 205781b..4d23aef 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1740,13 +1740,6 @@
 }
 
 
-void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
-  Register result = ToRegister(instr->result());
-  Register array = ToRegister(instr->value());
-  __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
-}
-
-
 void LCodeGen::DoFixedArrayBaseLength(
     LFixedArrayBaseLength* instr) {
   Register result = ToRegister(instr->result());
@@ -2116,6 +2109,12 @@
         __ bind(&not_string);
       }
 
+      if (expected.Contains(ToBooleanStub::SYMBOL)) {
+        // Symbol value -> true.
+        __ CmpInstanceType(map, SYMBOL_TYPE);
+        __ j(equal, true_label);
+      }
+
       if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
         // heap number -> false iff +0, -0, or NaN.
         Label not_heap_number;
@@ -5566,7 +5565,7 @@
     __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
-    __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
+    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   }
 
   __ bind(deferred->exit());
@@ -5979,6 +5978,11 @@
               1 << Map::kIsUndetectable);
     final_branch_condition = zero;
 
+  } else if (type_name->Equals(heap()->symbol_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ CmpObjectType(input, SYMBOL_TYPE, input);
+    final_branch_condition = equal;
+
   } else if (type_name->Equals(heap()->boolean_string())) {
     __ cmp(input, factory()->true_value());
     __ j(equal, true_label);
@@ -6013,13 +6017,7 @@
       __ cmp(input, factory()->null_value());
       __ j(equal, true_label);
     }
-    if (FLAG_harmony_symbols) {
-      __ CmpObjectType(input, SYMBOL_TYPE, input);
-      __ j(equal, true_label);
-      __ CmpInstanceType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    } else {
-      __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
-    }
+    __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
     __ j(below, false_label);
     __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
     __ j(above, false_label);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index f2aec99..102515a 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -923,6 +923,35 @@
   LInstruction* instr = current->CompileToLithium(this);
 
   if (instr != NULL) {
+#if DEBUG
+    // Make sure that the lithium instruction has either no fixed register
+    // constraints in temps or the result OR no uses that are only used at
+    // start. If this invariant doesn't hold, the register allocator can decide
+    // to insert a split of a range immediately before the instruction due to an
+    // already allocated register needing to be used for the instruction's fixed
+    // register constraint. In this case, The register allocator won't see an
+    // interference between the split child and the use-at-start (it would if
+    // the it was just a plain use), so it is free to move the split child into
+    // the same register that is used for the use-at-start.
+    // See https://code.google.com/p/chromium/issues/detail?id=201590
+    if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+      int fixed = 0;
+      int used_at_start = 0;
+      for (UseIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->IsUsedAtStart()) ++used_at_start;
+      }
+      if (instr->Output() != NULL) {
+        if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
+      }
+      for (TempIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->HasFixedPolicy()) ++fixed;
+      }
+      ASSERT(fixed == 0 || used_at_start == 0);
+    }
+#endif
+
     if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
       instr = AssignPointerMap(instr);
     }
@@ -1182,16 +1211,20 @@
                                                                   input);
     return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
   } else {
-    LOperand* input = UseRegisterAtStart(instr->value());
     LOperand* context = UseAny(instr->context());  // Deferred use by MathAbs.
+    LOperand* input = NULL;
     if (op == kMathPowHalf) {
+      input = UseRegisterAtStart(instr->value());
       LOperand* temp = TempRegister();
       LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp);
       return DefineSameAsFirst(result);
     } else if (op == kMathRound) {
+      input = UseRegister(instr->value());
       LOperand* temp = FixedTemp(xmm4);
       LMathRound* result = new(zone()) LMathRound(context, input, temp);
       return AssignEnvironment(DefineAsRegister(result));
+    } else {
+      input = UseRegisterAtStart(instr->value());
     }
     LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(context,
                                                                   input);
@@ -1716,12 +1749,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
-  LOperand* array = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LJSArrayLength(array));
-}
-
-
 LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
     HFixedArrayBaseLength* instr) {
   LOperand* array = UseRegisterAtStart(instr->value());
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 0e36474..1c490bb 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -114,7 +114,6 @@
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
-  V(JSArrayLength)                              \
   V(Label)                                      \
   V(LazyBailout)                                \
   V(LoadContextSlot)                            \
@@ -1147,19 +1146,6 @@
 };
 
 
-class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LJSArrayLength(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  LOperand* value() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
-  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
-};
-
-
 class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LFixedArrayBaseLength(LOperand* value) {
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index debf64a..3d3dabc 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1332,18 +1332,16 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(
-    int header_size,
-    ScaleFactor element_size,
-    Register element_count,
-    RegisterValueType element_count_type,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    AllocationFlags flags) {
+void MacroAssembler::Allocate(int header_size,
+                              ScaleFactor element_size,
+                              Register element_count,
+                              RegisterValueType element_count_type,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & SIZE_IN_WORDS) == 0);
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1365,6 +1363,7 @@
   // Align the next allocation. Storing the filler map without checking top is
   // always safe because the limit of the heap is always aligned.
   if ((flags & DOUBLE_ALIGNMENT) != 0) {
+    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
     ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
     Label aligned;
     test(result, Immediate(kDoubleAlignmentMask));
@@ -1375,9 +1374,9 @@
     bind(&aligned);
   }
 
-  // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  // Calculate new top and bail out if space is exhausted.
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
 
   // We assume that element_count*element_size + header_size does not
   // overflow.
@@ -1394,7 +1393,7 @@
   lea(result_end, Operand(element_count, element_size, header_size));
   add(result_end, result);
   j(carry, gc_required);
-  cmp(result_end, Operand::StaticVariable(new_space_allocation_limit));
+  cmp(result_end, Operand::StaticVariable(allocation_limit));
   j(above, gc_required);
 
   if ((flags & TAG_OBJECT) != 0) {
@@ -1407,14 +1406,13 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(Register object_size,
-                                        Register result,
-                                        Register result_end,
-                                        Register scratch,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(Register object_size,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1436,6 +1434,7 @@
   // Align the next allocation. Storing the filler map without checking top is
   // always safe because the limit of the heap is always aligned.
   if ((flags & DOUBLE_ALIGNMENT) != 0) {
+    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
     ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
     Label aligned;
     test(result, Immediate(kDoubleAlignmentMask));
@@ -1446,15 +1445,16 @@
     bind(&aligned);
   }
 
-  // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  // Calculate new top and bail out if space is exhausted.
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
+
   if (!object_size.is(result_end)) {
     mov(result_end, object_size);
   }
   add(result_end, result);
   j(carry, gc_required);
-  cmp(result_end, Operand::StaticVariable(new_space_allocation_limit));
+  cmp(result_end, Operand::StaticVariable(allocation_limit));
   j(above, gc_required);
 
   // Tag result if requested.
@@ -1511,15 +1511,15 @@
   and_(scratch1, Immediate(~kObjectAlignmentMask));
 
   // Allocate two byte string in new space.
-  AllocateInNewSpace(SeqTwoByteString::kHeaderSize,
-                     times_1,
-                     scratch1,
-                     REGISTER_VALUE_IS_INT32,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SeqTwoByteString::kHeaderSize,
+           times_1,
+           scratch1,
+           REGISTER_VALUE_IS_INT32,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1547,15 +1547,15 @@
   and_(scratch1, Immediate(~kObjectAlignmentMask));
 
   // Allocate ASCII string in new space.
-  AllocateInNewSpace(SeqOneByteString::kHeaderSize,
-                     times_1,
-                     scratch1,
-                     REGISTER_VALUE_IS_INT32,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SeqOneByteString::kHeaderSize,
+           times_1,
+           scratch1,
+           REGISTER_VALUE_IS_INT32,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 8dd4120..b3dae73 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -582,22 +582,22 @@
                 Label* gc_required,
                 AllocationFlags flags);
 
-  void AllocateInNewSpace(int header_size,
-                          ScaleFactor element_size,
-                          Register element_count,
-                          RegisterValueType element_count_type,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(int header_size,
+                ScaleFactor element_size,
+                Register element_count,
+                RegisterValueType element_count_type,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
-  void AllocateInNewSpace(Register object_size,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(Register object_size,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. Make sure that no pointers are left to the
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index f7e795e..cb4b4a7 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -730,7 +730,7 @@
 // but may be destroyed if store is successful.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Handle<JSObject> object,
-                                      int index,
+                                      LookupResult* lookup,
                                       Handle<Map> transition,
                                       Handle<Name> name,
                                       Register receiver_reg,
@@ -740,16 +740,6 @@
                                       Register scratch2,
                                       Label* miss_label,
                                       Label* miss_restore_name) {
-  LookupResult lookup(masm->isolate());
-  object->Lookup(*name, &lookup);
-  if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
-    // In sloppy mode, we could just return the value and be done. However, we
-    // might be in strict mode, where we have to throw. Since we cannot tell,
-    // go into slow case unconditionally.
-    __ jmp(miss_label);
-    return;
-  }
-
   // Check that the map of the object hasn't changed.
   CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
                                              : REQUIRE_EXACT_MAP;
@@ -764,8 +754,9 @@
   // Check that we are allowed to write this.
   if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
     JSObject* holder;
-    if (lookup.IsFound()) {
-      holder = lookup.holder();
+    // holder == object indicates that no property was found.
+    if (lookup->holder() != *object) {
+      holder = lookup->holder();
     } else {
       // Find the top object.
       holder = *object;
@@ -774,8 +765,19 @@
       } while (holder->GetPrototype()->IsJSObject());
     }
     // We need an extra register, push
-    CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, miss_restore_name);
+    Register holder_reg = CheckPrototypes(
+        object, receiver_reg, Handle<JSObject>(holder), name_reg,
+        scratch1, scratch2, name, miss_restore_name);
+    // If no property was found, and the holder (the last object in the
+    // prototype chain) is in slow mode, we need to do a negative lookup on the
+    // holder.
+    if (lookup->holder() == *object &&
+        !holder->HasFastProperties() &&
+        !holder->IsJSGlobalProxy() &&
+        !holder->IsJSGlobalObject()) {
+      GenerateDictionaryNegativeLookup(
+          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    }
   }
 
   // Stub never generated for non-global objects that require access
@@ -799,6 +801,7 @@
     return;
   }
 
+  int index;
   if (!transition.is_null()) {
     // Update the map of the object.
     __ mov(scratch1, Immediate(transition));
@@ -813,8 +816,13 @@
                         kDontSaveFPRegs,
                         OMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
+    index = transition->instance_descriptors()->GetFieldIndex(
+        transition->LastAdded());
+  } else {
+    index = lookup->GetFieldIndex().field_index();
   }
 
+
   // Adjust for the number of properties stored in the object. Even in the
   // face of a transition we can use the old map here because the size of the
   // object and the number of in-object properties is not going to change.
@@ -2350,6 +2358,12 @@
       // Check that the object is a symbol.
       __ CmpObjectType(edx, SYMBOL_TYPE, eax);
       __ j(not_equal, &miss);
+      // Check that the maps starting from the prototype haven't changed.
+      GenerateDirectLoadGlobalFunctionPrototype(
+          masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss);
+      CheckPrototypes(
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+          eax, holder, ebx, edx, edi, name, &miss);
       break;
 
     case NUMBER_CHECK: {
diff --git a/src/ic-inl.h b/src/ic-inl.h
index 9439792..ca02183 100644
--- a/src/ic-inl.h
+++ b/src/ic-inl.h
@@ -109,7 +109,7 @@
   // If the object is a value, we use the prototype map for the cache.
   ASSERT(object->IsString() || object->IsSymbol() ||
          object->IsNumber() || object->IsBoolean());
-  return DELEGATE_MAP;
+  return PROTOTYPE_MAP;
 }
 
 
@@ -124,7 +124,7 @@
       !object->HasFastProperties() &&
       !object->IsJSGlobalProxy() &&
       !object->IsJSGlobalObject()) {
-    return DELEGATE_MAP;
+    return PROTOTYPE_MAP;
   }
   return OWN_MAP;
 }
@@ -133,7 +133,8 @@
 JSObject* IC::GetCodeCacheHolder(Isolate* isolate,
                                  Object* object,
                                  InlineCacheHolderFlag holder) {
-  Object* map_owner = holder == OWN_MAP ? object : object->GetDelegate(isolate);
+  Object* map_owner =
+      holder == OWN_MAP ? object : object->GetPrototype(isolate);
   ASSERT(map_owner->IsJSObject());
   return JSObject::cast(map_owner);
 }
diff --git a/src/ic.cc b/src/ic.cc
index 71f2c30..515c6f7 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -190,7 +190,7 @@
     // The stub was generated for JSObject but called for non-JSObject.
     // IC::GetCodeCacheHolder is not applicable.
     return false;
-  } else if (cache_holder == DELEGATE_MAP &&
+  } else if (cache_holder == PROTOTYPE_MAP &&
              receiver->GetPrototype(isolate)->IsNull()) {
     // IC::GetCodeCacheHolder is not applicable.
     return false;
@@ -857,28 +857,6 @@
       return Smi::FromInt(String::cast(*string)->length());
     }
 
-    // Use specialized code for getting the length of arrays.
-    if (object->IsJSArray() &&
-        name->Equals(isolate()->heap()->length_string())) {
-      Handle<Code> stub;
-      if (state == UNINITIALIZED) {
-        stub = pre_monomorphic_stub();
-      } else if (state == PREMONOMORPHIC) {
-        ArrayLengthStub array_length_stub(kind());
-        stub = array_length_stub.GetCode(isolate());
-      } else if (state != MEGAMORPHIC) {
-        ASSERT(state != GENERIC);
-        stub = megamorphic_stub();
-      }
-      if (!stub.is_null()) {
-        set_target(*stub);
-#ifdef DEBUG
-        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
-#endif
-      }
-      return JSArray::cast(*object)->length();
-    }
-
     // Use specialized code for getting prototype of functions.
     if (object->IsJSFunction() &&
         name->Equals(isolate()->heap()->prototype_string()) &&
@@ -1037,6 +1015,22 @@
 }
 
 
+bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
+  AssertNoAllocation no_allocation;
+
+  Map* current_map = target()->FindFirstMap();
+  ElementsKind receiver_elements_kind = receiver_map->elements_kind();
+  bool more_general_transition =
+      IsMoreGeneralElementsKindTransition(
+        current_map->elements_kind(), receiver_elements_kind);
+  Map* transitioned_map = more_general_transition
+      ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
+      : NULL;
+
+  return transitioned_map == receiver_map;
+}
+
+
 // Since GC may have been invoked, by the time PatchCache is called, |state| is
 // not necessarily equal to target()->state().
 void IC::PatchCache(State state,
@@ -1054,6 +1048,17 @@
       // Only move to megamorphic if the target changes.
       if (target() != *code) {
         if (target()->is_load_stub()) {
+          bool is_same_handler = false;
+          {
+            AssertNoAllocation no_allocation;
+            Code* old_handler = target()->FindFirstCode();
+            is_same_handler = old_handler == *code;
+          }
+          if (is_same_handler
+              && IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
+            UpdateMonomorphicIC(receiver, code, name);
+            break;
+          }
           if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) {
             break;
           }
@@ -1226,6 +1231,12 @@
         if (!holder->HasFastProperties()) break;
         return isolate()->stub_cache()->ComputeLoadViaGetter(
             name, receiver, holder, Handle<JSFunction>::cast(getter));
+      } else if (receiver->IsJSArray() &&
+          name->Equals(isolate()->heap()->length_string())) {
+        PropertyIndex lengthIndex =
+          PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
+        return isolate()->stub_cache()->ComputeLoadField(
+            name, receiver, holder, lengthIndex);
       }
       // TODO(dcarney): Handle correctly.
       if (callback->IsDeclaredAccessorInfo()) break;
@@ -1418,41 +1429,42 @@
 }
 
 
-static bool StoreICableLookup(LookupResult* lookup) {
-  // Bail out if we didn't find a result.
-  if (!lookup->IsFound()) return false;
-
-  // Bail out if inline caching is not allowed.
-  if (!lookup->IsCacheable()) return false;
-
-  // If the property is read-only, we leave the IC in its current state.
-  if (lookup->IsTransition()) {
-    return !lookup->GetTransitionDetails().IsReadOnly();
-  }
-  return !lookup->IsReadOnly();
-}
-
-
 static bool LookupForWrite(Handle<JSObject> receiver,
                            Handle<String> name,
                            LookupResult* lookup) {
-  receiver->LocalLookup(*name, lookup);
-  if (!lookup->IsFound()) {
-    receiver->map()->LookupTransition(*receiver, *name, lookup);
-  }
-  if (!StoreICableLookup(lookup)) {
-    // 2nd chance: There can be accessors somewhere in the prototype chain.
-    receiver->Lookup(*name, lookup);
-    return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup);
+  Handle<JSObject> holder = receiver;
+  receiver->Lookup(*name, lookup);
+  if (lookup->IsFound()) {
+    if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
+
+    if (lookup->holder() == *receiver) {
+      if (lookup->IsInterceptor() &&
+          receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
+        receiver->LocalLookupRealNamedProperty(*name, lookup);
+        return lookup->IsFound() &&
+            !lookup->IsReadOnly() &&
+            lookup->IsCacheable();
+      }
+      return true;
+    }
+
+    if (lookup->IsPropertyCallbacks()) return true;
+
+    // Currently normal holders in the prototype chain are not supported. They
+    // would require a runtime positive lookup and verification that the details
+    // have not changed.
+    if (lookup->IsInterceptor() || lookup->IsNormal()) return false;
+    holder = Handle<JSObject>(lookup->holder(), lookup->isolate());
   }
 
-  if (lookup->IsInterceptor() &&
-      receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
-    receiver->LocalLookupRealNamedProperty(*name, lookup);
-    return StoreICableLookup(lookup);
-  }
-
-  return true;
+  // While normally LookupTransition gets passed the receiver, in this case we
+  // pass the holder of the property that we overwrite. This keeps the holder in
+  // the LookupResult intact so we can later use it to generate a prototype
+  // chain check. This avoids a double lookup, but requires us to pass in the
+  // receiver when trying to fetch extra information from the transition.
+  receiver->map()->LookupTransition(*holder, *name, lookup);
+  return lookup->IsTransition() &&
+      !lookup->GetTransitionDetails(receiver->map()).IsReadOnly();
 }
 
 
@@ -1552,7 +1564,6 @@
                            Handle<String> name,
                            Handle<Object> value) {
   ASSERT(!receiver->IsJSGlobalProxy());
-  ASSERT(StoreICableLookup(lookup));
   ASSERT(lookup->IsFound());
 
   // These are not cacheable, so we never see such LookupResults here.
@@ -1575,8 +1586,7 @@
   switch (lookup->type()) {
     case FIELD:
       return isolate()->stub_cache()->ComputeStoreField(
-          name, receiver, lookup->GetFieldIndex().field_index(),
-          Handle<Map>::null(), strict_mode);
+          name, receiver, lookup, Handle<Map>::null(), strict_mode);
     case NORMAL:
       if (receiver->IsGlobalObject()) {
         // The stub generated for the global object picks the value directly
@@ -1588,7 +1598,7 @@
         return isolate()->stub_cache()->ComputeStoreGlobal(
             name, global, cell, strict_mode);
       }
-      if (!holder.is_identical_to(receiver)) break;
+      ASSERT(holder.is_identical_to(receiver));
       return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
     case CALLBACKS: {
       Handle<Object> callback(lookup->GetCallbackObject(), isolate());
@@ -1623,7 +1633,10 @@
     case CONSTANT_FUNCTION:
       break;
     case TRANSITION: {
-      Handle<Map> transition(lookup->GetTransitionTarget(), isolate());
+      // Explicitly pass in the receiver map since LookupForWrite may have
+      // stored something else than the receiver in the holder.
+      Handle<Map> transition(
+          lookup->GetTransitionTarget(receiver->map()), isolate());
       int descriptor = transition->LastAdded();
 
       DescriptorArray* target_descriptors = transition->instance_descriptors();
@@ -1631,9 +1644,8 @@
 
       if (details.type() != FIELD || details.attributes() != NONE) break;
 
-      int field_index = target_descriptors->GetFieldIndex(descriptor);
       return isolate()->stub_cache()->ComputeStoreField(
-          name, receiver, field_index, transition, strict_mode);
+          name, receiver, lookup, transition, strict_mode);
     }
     case NONEXISTENT:
     case HANDLER:
@@ -1704,16 +1716,7 @@
       transitioned_receiver_map =
           ComputeTransitionedMap(receiver, store_mode);
     }
-    ElementsKind transitioned_kind =
-        transitioned_receiver_map->elements_kind();
-    bool more_general_transition =
-        IsMoreGeneralElementsKindTransition(
-            previous_receiver_map->elements_kind(),
-            transitioned_kind);
-    Map* transitioned_previous_map = more_general_transition
-        ? previous_receiver_map->LookupElementsTransitionMap(transitioned_kind)
-        : NULL;
-    if (transitioned_previous_map == *transitioned_receiver_map) {
+    if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) {
       // Element family is the same, use the "worst" case map.
       store_mode = GetNonTransitioningStoreMode(store_mode);
       return isolate()->stub_cache()->ComputeKeyedStoreElement(
@@ -1984,19 +1987,20 @@
   switch (lookup->type()) {
     case FIELD:
       return isolate()->stub_cache()->ComputeKeyedStoreField(
-          name, receiver, lookup->GetFieldIndex().field_index(),
-          Handle<Map>::null(), strict_mode);
+          name, receiver, lookup, Handle<Map>::null(), strict_mode);
     case TRANSITION: {
-      Handle<Map> transition(lookup->GetTransitionTarget(), isolate());
+      // Explicitly pass in the receiver map since LookupForWrite may have
+      // stored something else than the receiver in the holder.
+      Handle<Map> transition(
+          lookup->GetTransitionTarget(receiver->map()), isolate());
       int descriptor = transition->LastAdded();
 
       DescriptorArray* target_descriptors = transition->instance_descriptors();
       PropertyDetails details = target_descriptors->GetDetails(descriptor);
 
       if (details.type() == FIELD && details.attributes() == NONE) {
-        int field_index = target_descriptors->GetFieldIndex(descriptor);
         return isolate()->stub_cache()->ComputeKeyedStoreField(
-            name, receiver, field_index, transition, strict_mode);
+            name, receiver, lookup, transition, strict_mode);
       }
       // fall through.
     }
diff --git a/src/ic.h b/src/ic.h
index 2b8f378..55b5661 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -176,6 +176,7 @@
                            Handle<String> name,
                            Handle<Code> code);
   void CopyICToMegamorphicCache(Handle<String> name);
+  bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map);
   void PatchCache(State state,
                   StrictModeFlag strict_mode,
                   Handle<JSObject> receiver,
diff --git a/src/interpreter-irregexp.cc b/src/interpreter-irregexp.cc
index 5abeb5a..e678e6c 100644
--- a/src/interpreter-irregexp.cc
+++ b/src/interpreter-irregexp.cc
@@ -73,9 +73,15 @@
     unsigned int old_char = subject[from++];
     unsigned int new_char = subject[current++];
     if (old_char == new_char) continue;
-    if (old_char - 'A' <= 'Z' - 'A') old_char |= 0x20;
-    if (new_char - 'A' <= 'Z' - 'A') new_char |= 0x20;
+    // Convert both characters to lower case.
+    old_char |= 0x20;
+    new_char |= 0x20;
     if (old_char != new_char) return false;
+    // Not letters in the ASCII range and Latin-1 range.
+    if (!(old_char - 'a' <= 'z' - 'a') &&
+        !(old_char - 224 <= 254 - 224 && old_char != 247)) {
+      return false;
+    }
   }
   return true;
 }
diff --git a/src/isolate.cc b/src/isolate.cc
index 632ecdc..0415519 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -612,13 +612,16 @@
   limit = Max(limit, 0);  // Ensure that limit is not negative.
   int initial_size = Min(limit, 10);
   Handle<FixedArray> elements =
-      factory()->NewFixedArrayWithHoles(initial_size * 4);
+      factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
 
   // If the caller parameter is a function we skip frames until we're
   // under it before starting to collect.
   bool seen_caller = !caller->IsJSFunction();
-  int cursor = 0;
+  // First element is reserved to store the number of non-strict frames.
+  int cursor = 1;
   int frames_seen = 0;
+  int non_strict_frames = 0;
+  bool encountered_strict_function = false;
   for (StackFrameIterator iter(this);
        !iter.done() && frames_seen < limit;
        iter.Advance()) {
@@ -646,6 +649,17 @@
         Handle<JSFunction> fun = frames[i].function();
         Handle<Code> code = frames[i].code();
         Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
+        // The stack trace API should not expose receivers and function
+        // objects on frames deeper than the top-most one with a strict
+        // mode function.  The number of non-strict frames is stored as
+        // first element in the result array.
+        if (!encountered_strict_function) {
+          if (!fun->shared()->is_classic_mode()) {
+            encountered_strict_function = true;
+          } else {
+            non_strict_frames++;
+          }
+        }
         elements->set(cursor++, *recv);
         elements->set(cursor++, *fun);
         elements->set(cursor++, *code);
@@ -653,6 +667,7 @@
       }
     }
   }
+  elements->set(0, Smi::FromInt(non_strict_frames));
   Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
   result->set_length(Smi::FromInt(cursor));
   return result;
@@ -1678,6 +1693,8 @@
       date_cache_(NULL),
       code_stub_interface_descriptors_(NULL),
       context_exit_happened_(false),
+      cpu_profiler_(NULL),
+      heap_profiler_(NULL),
       deferred_handles_head_(NULL),
       optimizing_compiler_thread_(this),
       marking_thread_(NULL),
@@ -1809,8 +1826,11 @@
     preallocated_message_space_ = NULL;
     PreallocatedMemoryThreadStop();
 
-    HeapProfiler::TearDown();
-    CpuProfiler::TearDown();
+    delete heap_profiler_;
+    heap_profiler_ = NULL;
+    delete cpu_profiler_;
+    cpu_profiler_ = NULL;
+
     if (runtime_profiler_ != NULL) {
       runtime_profiler_->TearDown();
       delete runtime_profiler_;
@@ -2039,8 +2059,8 @@
   // Enable logging before setting up the heap
   logger_->SetUp();
 
-  CpuProfiler::SetUp();
-  HeapProfiler::SetUp();
+  cpu_profiler_ = new CpuProfiler(this);
+  heap_profiler_ = new HeapProfiler(heap());
 
   // Initialize other runtime facilities
 #if defined(USE_SIMULATOR)
diff --git a/src/isolate.h b/src/isolate.h
index d6770cc..f7a81d3 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -357,9 +357,6 @@
   V(FunctionInfoListener*, active_function_info_listener, NULL)                \
   /* State for Relocatable. */                                                 \
   V(Relocatable*, relocatable_top, NULL)                                       \
-  /* State for CodeEntry in profile-generator. */                              \
-  V(CodeGenerator*, current_code_generator, NULL)                              \
-  V(bool, jump_target_compiling_deferred_code, false)                          \
   V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
   V(Object*, string_stream_current_security_token, NULL)                       \
   /* TODO(isolates): Release this on destruction? */                           \
@@ -371,8 +368,6 @@
   V(unsigned, ast_node_count, 0)                                               \
   /* SafeStackFrameIterator activations count. */                              \
   V(int, safe_stack_iterator_counter, 0)                                       \
-  V(CpuProfiler*, cpu_profiler, NULL)                                          \
-  V(HeapProfiler*, heap_profiler, NULL)                                        \
   V(bool, observer_delivery_pending, false)                                    \
   V(HStatistics*, hstatistics, NULL)                                           \
   V(HTracer*, htracer, NULL)                                                   \
@@ -979,6 +974,9 @@
   inline bool IsDebuggerActive();
   inline bool DebuggerHasBreakPoints();
 
+  CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
+  HeapProfiler* heap_profiler() const { return heap_profiler_; }
+
 #ifdef DEBUG
   HistogramInfo* heap_histograms() { return heap_histograms_; }
 
@@ -1314,6 +1312,8 @@
   Debugger* debugger_;
   Debug* debug_;
 #endif
+  CpuProfiler* cpu_profiler_;
+  HeapProfiler* heap_profiler_;
 
 #define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
   type name##_;
diff --git a/src/json-parser.h b/src/json-parser.h
index 28ef8b3..ac34c59 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -291,6 +291,7 @@
 // Parse a JSON object. Position must be right at '{'.
 template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
+  HandleScope scope(isolate());
   Handle<JSObject> json_object =
       factory()->NewJSObject(object_constructor(), pretenure_);
   ASSERT_EQ(c0_, '{');
@@ -358,12 +359,13 @@
     }
   }
   AdvanceSkipWhitespace();
-  return json_object;
+  return scope.CloseAndEscape(json_object);
 }
 
 // Parse a JSON array. Position must be right at '['.
 template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
+  HandleScope scope(isolate());
   ZoneScope zone_scope(zone(), DELETE_ON_EXIT);
   ZoneList<Handle<Object> > elements(4, zone());
   ASSERT_EQ(c0_, '[');
@@ -386,8 +388,9 @@
   for (int i = 0, n = elements.length(); i < n; i++) {
     fast_elements->set(i, *elements[i]);
   }
-  return factory()->NewJSArrayWithElements(
+  Handle<Object> json_array = factory()->NewJSArrayWithElements(
       fast_elements, FAST_ELEMENTS, pretenure_);
+  return scope.CloseAndEscape(json_array);
 }
 
 
@@ -501,10 +504,10 @@
   int count = end - start;
   int max_length = count + source_length_ - position_;
   int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
-  Handle<StringType> seq_str =
+  Handle<StringType> seq_string =
       NewRawString<StringType>(factory(), length, pretenure_);
   // Copy prefix into seq_str.
-  SinkChar* dest = seq_str->GetChars();
+  SinkChar* dest = seq_string->GetChars();
   String::WriteToFlat(*prefix, dest, start, end);
 
   while (c0_ != '"') {
@@ -512,7 +515,7 @@
     if (c0_ < 0x20) return Handle<String>::null();
     if (count >= length) {
       // We need to create a longer sequential string for the result.
-      return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count);
+      return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count);
     }
     if (c0_ != '\\') {
       // If the sink can contain UC16 characters, or source_ contains only
@@ -522,11 +525,11 @@
       if (sizeof(SinkChar) == kUC16Size ||
           seq_ascii ||
           c0_ <= String::kMaxOneByteCharCode) {
-        SeqStringSet(seq_str, count++, c0_);
+        SeqStringSet(seq_string, count++, c0_);
         Advance();
       } else {
         // StringType is SeqOneByteString and we just read a non-ASCII char.
-        return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count);
+        return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count);
       }
     } else {
       Advance();  // Advance past the \.
@@ -534,22 +537,22 @@
         case '"':
         case '\\':
         case '/':
-          SeqStringSet(seq_str, count++, c0_);
+          SeqStringSet(seq_string, count++, c0_);
           break;
         case 'b':
-          SeqStringSet(seq_str, count++, '\x08');
+          SeqStringSet(seq_string, count++, '\x08');
           break;
         case 'f':
-          SeqStringSet(seq_str, count++, '\x0c');
+          SeqStringSet(seq_string, count++, '\x0c');
           break;
         case 'n':
-          SeqStringSet(seq_str, count++, '\x0a');
+          SeqStringSet(seq_string, count++, '\x0a');
           break;
         case 'r':
-          SeqStringSet(seq_str, count++, '\x0d');
+          SeqStringSet(seq_string, count++, '\x0d');
           break;
         case 't':
-          SeqStringSet(seq_str, count++, '\x09');
+          SeqStringSet(seq_string, count++, '\x09');
           break;
         case 'u': {
           uc32 value = 0;
@@ -563,13 +566,13 @@
           }
           if (sizeof(SinkChar) == kUC16Size ||
               value <= String::kMaxOneByteCharCode) {
-            SeqStringSet(seq_str, count++, value);
+            SeqStringSet(seq_string, count++, value);
             break;
           } else {
             // StringType is SeqOneByteString and we just read a non-ASCII char.
             position_ -= 6;  // Rewind position_ to \ in \uxxxx.
             Advance();
-            return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str,
+            return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string,
                                                               0,
                                                               count);
           }
@@ -580,23 +583,13 @@
       Advance();
     }
   }
-  // Shrink seq_string length to count.
-  if (isolate()->heap()->InNewSpace(*seq_str)) {
-    isolate()->heap()->new_space()->
-        template ShrinkStringAtAllocationBoundary<StringType>(
-            *seq_str, count);
-  } else {
-    int string_size = StringType::SizeFor(count);
-    int allocated_string_size = StringType::SizeFor(length);
-    int delta = allocated_string_size - string_size;
-    Address start_filler_object = seq_str->address() + string_size;
-    seq_str->set_length(count);
-    isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
-  }
+
   ASSERT_EQ('"', c0_);
   // Advance past the last '"'.
   AdvanceSkipWhitespace();
-  return seq_str;
+
+  // Shrink seq_string length to count and return.
+  return SeqString::Truncate(seq_string, count);
 }
 
 
@@ -623,8 +616,8 @@
         int beg_pos = position_;
         position_ = position;
         return SlowScanJsonString<SeqOneByteString, uint8_t>(source_,
-                                                            beg_pos,
-                                                            position_);
+                                                             beg_pos,
+                                                             position_);
       }
       if (c0 < 0x20) return Handle<String>::null();
       if (static_cast<uint32_t>(c0) >
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index ad9ef3d..bcdd64c 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -41,6 +41,9 @@
 
   MaybeObject* Stringify(Handle<Object> object);
 
+  INLINE(static MaybeObject* StringifyString(Isolate* isolate,
+                                             Handle<String> object));
+
  private:
   static const int kInitialPartLength = 32;
   static const int kMaxPartLength = 16 * 1024;
@@ -52,7 +55,7 @@
 
   void ChangeEncoding();
 
-  void ShrinkCurrentPart();
+  INLINE(void ShrinkCurrentPart());
 
   template <bool is_ascii, typename Char>
   INLINE(void Append_(Char c));
@@ -84,6 +87,11 @@
                           bool deferred_comma,
                           bool deferred_key);
 
+  template <typename ResultType, typename Char>
+  INLINE(static MaybeObject* StringifyString_(Isolate* isolate,
+                                              Vector<Char> vector,
+                                              Handle<String> result));
+
   // Entry point to serialize the object.
   INLINE(Result SerializeObject(Handle<Object> obj)) {
     return Serialize_<false>(obj, false, factory_->empty_string());
@@ -135,18 +143,18 @@
   void SerializeString(Handle<String> object);
 
   template <typename SrcChar, typename DestChar>
-  INLINE(void SerializeStringUnchecked_(const SrcChar* src,
-                                        DestChar* dest,
-                                        int length));
+  INLINE(static int SerializeStringUnchecked_(const SrcChar* src,
+                                              DestChar* dest,
+                                              int length));
 
   template <bool is_ascii, typename Char>
   INLINE(void SerializeString_(Handle<String> string));
 
   template <typename Char>
-  INLINE(bool DoNotEscape(Char c));
+  INLINE(static bool DoNotEscape(Char c));
 
   template <typename Char>
-  INLINE(Vector<const Char> GetCharVector(Handle<String> string));
+  INLINE(static Vector<const Char> GetCharVector(Handle<String> string));
 
   Result StackPush(Handle<Object> object);
   void StackPop();
@@ -244,15 +252,15 @@
     "\370\0      \371\0      \372\0      \373\0      "
     "\374\0      \375\0      \376\0      \377\0      ";
 
+
 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
     : isolate_(isolate), current_index_(0), is_ascii_(true) {
   factory_ = isolate_->factory();
   accumulator_store_ = Handle<JSValue>::cast(
                            factory_->ToObject(factory_->empty_string()));
   part_length_ = kInitialPartLength;
-  current_part_ = factory_->NewRawOneByteString(kInitialPartLength);
-  tojson_string_ =
-      factory_->InternalizeOneByteString(STATIC_ASCII_VECTOR("toJSON"));
+  current_part_ = factory_->NewRawOneByteString(part_length_);
+  tojson_string_ = factory_->toJSON_string();
   stack_ = factory_->NewJSArray(8);
 }
 
@@ -275,6 +283,51 @@
 }
 
 
+MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
+                                                   Handle<String> object) {
+  static const int kJsonQuoteWorstCaseBlowup = 6;
+  static const int kSpaceForQuotes = 2;
+  int worst_case_length =
+      object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
+
+  if (worst_case_length > 32 * KB) {  // Slow path if too large.
+    BasicJsonStringifier stringifier(isolate);
+    return stringifier.Stringify(object);
+  }
+
+  FlattenString(object);
+  String::FlatContent flat = object->GetFlatContent();
+  if (flat.IsAscii()) {
+    return StringifyString_<SeqOneByteString>(
+        isolate,
+        flat.ToOneByteVector(),
+        isolate->factory()->NewRawOneByteString(worst_case_length));
+  } else {
+    ASSERT(flat.IsTwoByte());
+    return StringifyString_<SeqTwoByteString>(
+        isolate,
+        flat.ToUC16Vector(),
+        isolate->factory()->NewRawTwoByteString(worst_case_length));
+  }
+}
+
+
+template <typename ResultType, typename Char>
+MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
+                                                    Vector<Char> vector,
+                                                    Handle<String> result) {
+  AssertNoAllocation no_allocation;
+  int final_size = 0;
+  ResultType* dest = ResultType::cast(*result);
+  dest->Set(final_size++, '\"');
+  final_size += SerializeStringUnchecked_(vector.start(),
+                                          dest->GetChars() + 1,
+                                          vector.length());
+  dest->Set(final_size++, '\"');
+  return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
+}
+
+
 template <bool is_ascii, typename Char>
 void BasicJsonStringifier::Append_(Char c) {
   if (is_ascii) {
@@ -638,8 +691,8 @@
 
 void BasicJsonStringifier::ShrinkCurrentPart() {
   ASSERT(current_index_ < part_length_);
-  current_part_ = Handle<String>(
-      SeqString::cast(*current_part_)->Truncate(current_index_), isolate_);
+  current_part_ = SeqString::Truncate(Handle<SeqString>::cast(current_part_),
+                                      current_index_);
 }
 
 
@@ -667,10 +720,9 @@
 
 
 template <typename SrcChar, typename DestChar>
-void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
-                                                     DestChar* dest,
-                                                     int length) {
-  dest += current_index_;
+int BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
+                                                    DestChar* dest,
+                                                    int length) {
   DestChar* dest_start = dest;
 
   // Assert that uc16 character is not truncated down to 8 bit.
@@ -688,7 +740,7 @@
     }
   }
 
-  current_index_ += static_cast<int>(dest - dest_start);
+  return static_cast<int>(dest - dest_start);
 }
 
 
@@ -705,14 +757,14 @@
     AssertNoAllocation no_allocation;
     Vector<const Char> vector = GetCharVector<Char>(string);
     if (is_ascii) {
-      SerializeStringUnchecked_(
+      current_index_ += SerializeStringUnchecked_(
           vector.start(),
-          SeqOneByteString::cast(*current_part_)->GetChars(),
+          SeqOneByteString::cast(*current_part_)->GetChars() + current_index_,
           length);
     } else {
-      SerializeStringUnchecked_(
+      current_index_ += SerializeStringUnchecked_(
           vector.start(),
-          SeqTwoByteString::cast(*current_part_)->GetChars(),
+          SeqTwoByteString::cast(*current_part_)->GetChars() + current_index_,
           length);
     }
   } else {
diff --git a/src/log.cc b/src/log.cc
index 4ec981c..9438537 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -644,7 +644,17 @@
         String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     ApiEvent("api,check-security,\"%s\"\n", *str);
   } else if (key->IsSymbol()) {
-    ApiEvent("api,check-security,symbol(hash %x)\n", Symbol::cast(key)->Hash());
+    Symbol* symbol = Symbol::cast(key);
+    if (symbol->name()->IsUndefined()) {
+      ApiEvent("api,check-security,symbol(hash %x)\n",
+               Symbol::cast(key)->Hash());
+    } else {
+      SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
+          DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+      ApiEvent("api,check-security,symbol(\"%s\" hash %x)\n",
+               *str,
+               Symbol::cast(key)->Hash());
+    }
   } else if (key->IsUndefined()) {
     ApiEvent("api,check-security,undefined\n");
   } else {
@@ -833,8 +843,16 @@
         String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
   } else {
-    uint32_t hash = Symbol::cast(name)->Hash();
-    ApiEvent("api,%s,\"%s\",symbol(hash %x)\n", tag, *class_name, hash);
+    Symbol* symbol = Symbol::cast(name);
+    uint32_t hash = symbol->Hash();
+    if (symbol->name()->IsUndefined()) {
+      ApiEvent("api,%s,\"%s\",symbol(hash %x)\n", tag, *class_name, hash);
+    } else {
+      SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
+          DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+      ApiEvent("api,%s,\"%s\",symbol(\"%s\" hash %x)\n",
+               tag, *class_name, *str, hash);
+    }
   }
 }
 
@@ -902,7 +920,14 @@
         String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     msg.Append(",1,\"%s%s\"", prefix, *str);
   } else {
-    msg.Append(",1,symbol(hash %x)", prefix, Name::cast(name)->Hash());
+    Symbol* symbol = Symbol::cast(name);
+    if (symbol->name()->IsUndefined()) {
+      msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash());
+    } else {
+      SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
+          DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+      msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash());
+    }
   }
   msg.Append('\n');
   msg.WriteToLogFile();
@@ -978,8 +1003,15 @@
     if (name->IsString()) {
       name_buffer_->AppendString(String::cast(name));
     } else {
-      name_buffer_->AppendBytes("symbol(hash ");
-      name_buffer_->AppendHex(Name::cast(name)->Hash());
+      Symbol* symbol = Symbol::cast(name);
+      name_buffer_->AppendBytes("symbol(");
+      if (!symbol->name()->IsUndefined()) {
+        name_buffer_->AppendBytes("\"");
+        name_buffer_->AppendString(String::cast(symbol->name()));
+        name_buffer_->AppendBytes("\" ");
+      }
+      name_buffer_->AppendBytes("hash ");
+      name_buffer_->AppendHex(symbol->Hash());
       name_buffer_->AppendByte(')');
     }
   }
@@ -1006,7 +1038,14 @@
     msg.AppendDetailed(String::cast(name), false);
     msg.Append('"');
   } else {
-    msg.Append("symbol(hash %x)", Name::cast(name)->Hash());
+    Symbol* symbol = Symbol::cast(name);
+    msg.Append("symbol(");
+    if (!symbol->name()->IsUndefined()) {
+      msg.Append("\"");
+      msg.AppendDetailed(String::cast(symbol->name()), false);
+      msg.Append("\" ");
+    }
+    msg.Append("hash %x)", symbol->Hash());
   }
   msg.Append('\n');
   msg.WriteToLogFile();
@@ -1036,8 +1075,15 @@
     if (name->IsString()) {
       name_buffer_->AppendString(String::cast(name));
     } else {
-      name_buffer_->AppendBytes("symbol(hash ");
-      name_buffer_->AppendHex(Name::cast(name)->Hash());
+      Symbol* symbol = Symbol::cast(name);
+      name_buffer_->AppendBytes("symbol(");
+      if (!symbol->name()->IsUndefined()) {
+        name_buffer_->AppendBytes("\"");
+        name_buffer_->AppendString(String::cast(symbol->name()));
+        name_buffer_->AppendBytes("\" ");
+      }
+      name_buffer_->AppendBytes("hash ");
+      name_buffer_->AppendHex(symbol->Hash());
       name_buffer_->AppendByte(')');
     }
   }
@@ -1073,7 +1119,14 @@
         String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     msg.Append("\"%s\"", *str);
   } else {
-    msg.Append("symbol(hash %x)", Name::cast(name)->Hash());
+    Symbol* symbol = Symbol::cast(name);
+    msg.Append("symbol(");
+    if (!symbol->name()->IsUndefined()) {
+      msg.Append("\"");
+      msg.AppendDetailed(String::cast(symbol->name()), false);
+      msg.Append("\" ");
+    }
+    msg.Append("hash %x)", symbol->Hash());
   }
   msg.Append(',');
   msg.AppendAddress(shared->address());
@@ -1138,7 +1191,14 @@
        String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     msg.Append("%s", *sourcestr);
   } else {
-    msg.Append("symbol(hash %x)", Name::cast(source)->Hash());
+    Symbol* symbol = Symbol::cast(source);
+    msg.Append("symbol(");
+    if (!symbol->name()->IsUndefined()) {
+      msg.Append("\"");
+      msg.AppendDetailed(String::cast(symbol->name()), false);
+      msg.Append("\" ");
+    }
+    msg.Append("hash %x)", symbol->Hash());
   }
   msg.Append(":%d\",", line);
   msg.AppendAddress(shared->address());
@@ -1358,7 +1418,14 @@
     msg.Append(String::cast(name));
     msg.Append('"');
   } else {
-    msg.Append("symbol(hash %x)", Name::cast(name)->Hash());
+    Symbol* symbol = Symbol::cast(name);
+    msg.Append("symbol(");
+    if (!symbol->name()->IsUndefined()) {
+      msg.Append("\"");
+      msg.AppendDetailed(String::cast(symbol->name()), false);
+      msg.Append("\" ");
+    }
+    msg.Append("hash %x)", symbol->Hash());
   }
   msg.Append('\n');
   msg.WriteToLogFile();
@@ -1615,7 +1682,7 @@
         tag = Logger::KEYED_CALL_IC_TAG;
         break;
     }
-    PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description));
+    PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
   }
 }
 
@@ -1719,20 +1786,20 @@
       Handle<String> script_name(String::cast(script->name()));
       int line_num = GetScriptLineNumber(script, shared->start_position());
       if (line_num > 0) {
-        PROFILE(ISOLATE,
+        PROFILE(isolate_,
                 CodeCreateEvent(
                     Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
                     *code, *shared,
                     *script_name, line_num + 1));
       } else {
         // Can't distinguish eval and script here, so always use Script.
-        PROFILE(ISOLATE,
+        PROFILE(isolate_,
                 CodeCreateEvent(
                     Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
                     *code, *shared, *script_name));
       }
     } else {
-      PROFILE(ISOLATE,
+      PROFILE(isolate_,
               CodeCreateEvent(
                   Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
                   *code, *shared, *func_name));
@@ -1745,10 +1812,10 @@
       CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
       Object* callback_obj = call_data->callback();
       Address entry_point = v8::ToCData<Address>(callback_obj);
-      PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
+      PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
     }
   } else {
-    PROFILE(ISOLATE,
+    PROFILE(isolate_,
             CodeCreateEvent(
                 Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
   }
@@ -1789,11 +1856,11 @@
     Address getter_entry = v8::ToCData<Address>(ai->getter());
     Name* name = Name::cast(ai->name());
     if (getter_entry != 0) {
-      PROFILE(ISOLATE, GetterCallbackEvent(name, getter_entry));
+      PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
     }
     Address setter_entry = v8::ToCData<Address>(ai->setter());
     if (setter_entry != 0) {
-      PROFILE(ISOLATE, SetterCallbackEvent(name, setter_entry));
+      PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
     }
   }
 }
diff --git a/src/log.h b/src/log.h
index 5c121bc..a5eddc7 100644
--- a/src/log.h
+++ b/src/log.h
@@ -77,6 +77,7 @@
 class Ticker;
 class Isolate;
 class PositionsRecorder;
+class CpuProfiler;
 
 #undef LOG
 #define LOG(isolate, Call)                          \
diff --git a/src/macros.py b/src/macros.py
index 291a898..92ed437 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -99,7 +99,7 @@
 macro IS_NUMBER(arg)            = (typeof(arg) === 'number');
 macro IS_STRING(arg)            = (typeof(arg) === 'string');
 macro IS_BOOLEAN(arg)           = (typeof(arg) === 'boolean');
-macro IS_SYMBOL(arg)            = (%_IsSymbol(arg));
+macro IS_SYMBOL(arg)            = (typeof(arg) === 'symbol');
 macro IS_OBJECT(arg)            = (%_IsObject(arg));
 macro IS_ARRAY(arg)             = (%_IsArray(arg));
 macro IS_FUNCTION(arg)          = (%_IsFunction(arg));
@@ -110,11 +110,13 @@
 macro IS_DATE(arg)              = (%_ClassOf(arg) === 'Date');
 macro IS_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
 macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
+macro IS_SYMBOL_WRAPPER(arg)    = (%_ClassOf(arg) === 'Symbol');
 macro IS_BOOLEAN_WRAPPER(arg)   = (%_ClassOf(arg) === 'Boolean');
 macro IS_ERROR(arg)             = (%_ClassOf(arg) === 'Error');
 macro IS_SCRIPT(arg)            = (%_ClassOf(arg) === 'Script');
 macro IS_ARGUMENTS(arg)         = (%_ClassOf(arg) === 'Arguments');
 macro IS_GLOBAL(arg)            = (%_ClassOf(arg) === 'global');
+macro IS_ARRAYBUFFER(arg)       = (%_ClassOf(arg) === '__ArrayBuffer');
 macro IS_UNDETECTABLE(arg)      = (%_IsUndetectableObject(arg));
 macro FLOOR(arg)                = $floor(arg);
 
@@ -141,6 +143,7 @@
 macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
 macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0)));
 macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToInteger(ToNumber(arg)));
+macro TO_POSITIVE_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? (arg > 0 ? arg : 0) : %NumberToPositiveInteger(ToNumber(arg)));
 macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(ToNumber(arg)));
 macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
 macro TO_UINT32(arg) = (arg >>> 0);
diff --git a/src/messages.js b/src/messages.js
index 7353444..d51d384 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -100,6 +100,7 @@
   observe_notify_non_notifier:   ["notify called on non-notifier object"],
   // RangeError
   invalid_array_length:          ["Invalid array length"],
+  invalid_array_buffer_length:   ["Invalid array buffer length"],
   stack_overflow:                ["Maximum call stack size exceeded"],
   invalid_time_value:            ["Invalid time value"],
   // SyntaxError
@@ -150,6 +151,7 @@
   cant_prevent_ext_external_array_elements: ["Cannot prevent extension of an object with external array elements"],
   redef_external_array_element:  ["Cannot redefine a property of an object with external array elements"],
   harmony_const_assign:          ["Assignment to constant variable."],
+  symbol_to_string:              ["Conversion from symbol to string"],
   invalid_module_path:           ["Module does not export '", "%0", "', or export is not itself a module"],
   module_type_error:             ["Module '", "%0", "' used improperly"],
   module_export_undefined:       ["Export '", "%0", "' is not defined in module"],
@@ -745,64 +747,70 @@
 
 
 function GetStackTraceLine(recv, fun, pos, isGlobal) {
-  return new CallSite(recv, fun, pos).toString();
+  return new CallSite(recv, fun, pos, false).toString();
 }
 
 // ----------------------------------------------------------------------------
 // Error implementation
 
-function CallSite(receiver, fun, pos) {
-  this.receiver = receiver;
-  this.fun = fun;
-  this.pos = pos;
+var CallSiteReceiverKey = %CreateSymbol("receiver");
+var CallSiteFunctionKey = %CreateSymbol("function");
+var CallSitePositionKey = %CreateSymbol("position");
+var CallSiteStrictModeKey = %CreateSymbol("strict mode");
+
+function CallSite(receiver, fun, pos, strict_mode) {
+  this[CallSiteReceiverKey] = receiver;
+  this[CallSiteFunctionKey] = fun;
+  this[CallSitePositionKey] = pos;
+  this[CallSiteStrictModeKey] = strict_mode;
 }
 
 function CallSiteGetThis() {
-  return this.receiver;
+  return this[CallSiteStrictModeKey] ? void 0 : this[CallSiteReceiverKey];
 }
 
 function CallSiteGetTypeName() {
-  return GetTypeName(this, false);
+  return GetTypeName(this[CallSiteReceiverKey], false);
 }
 
 function CallSiteIsToplevel() {
-  if (this.receiver == null) {
+  if (this[CallSiteReceiverKey] == null) {
     return true;
   }
-  return IS_GLOBAL(this.receiver);
+  return IS_GLOBAL(this[CallSiteReceiverKey]);
 }
 
 function CallSiteIsEval() {
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   return script && script.compilation_type == COMPILATION_TYPE_EVAL;
 }
 
 function CallSiteGetEvalOrigin() {
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   return FormatEvalOrigin(script);
 }
 
 function CallSiteGetScriptNameOrSourceURL() {
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   return script ? script.nameOrSourceURL() : null;
 }
 
 function CallSiteGetFunction() {
-  return this.fun;
+  return this[CallSiteStrictModeKey] ? void 0 : this[CallSiteFunctionKey];
 }
 
 function CallSiteGetFunctionName() {
   // See if the function knows its own name
-  var name = this.fun.name;
+  var name = this[CallSiteFunctionKey].name;
   if (name) {
     return name;
   }
-  name = %FunctionGetInferredName(this.fun);
+  name = %FunctionGetInferredName(this[CallSiteFunctionKey]);
   if (name) {
     return name;
   }
   // Maybe this is an evaluation?
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
     return "eval";
   }
@@ -812,26 +820,22 @@
 function CallSiteGetMethodName() {
   // See if we can find a unique property on the receiver that holds
   // this function.
-  var ownName = this.fun.name;
-  if (ownName && this.receiver &&
-      (%_CallFunction(this.receiver,
-                      ownName,
-                      ObjectLookupGetter) === this.fun ||
-       %_CallFunction(this.receiver,
-                      ownName,
-                      ObjectLookupSetter) === this.fun ||
-       (IS_OBJECT(this.receiver) &&
-        %GetDataProperty(this.receiver, ownName) === this.fun))) {
+  var receiver = this[CallSiteReceiverKey];
+  var fun = this[CallSiteFunctionKey];
+  var ownName = fun.name;
+  if (ownName && receiver &&
+      (%_CallFunction(receiver, ownName, ObjectLookupGetter) === fun ||
+       %_CallFunction(receiver, ownName, ObjectLookupSetter) === fun ||
+       (IS_OBJECT(receiver) && %GetDataProperty(receiver, ownName) === fun))) {
     // To handle DontEnum properties we guess that the method has
     // the same name as the function.
     return ownName;
   }
   var name = null;
-  for (var prop in this.receiver) {
-    if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun ||
-        %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun ||
-        (IS_OBJECT(this.receiver) &&
-         %GetDataProperty(this.receiver, prop) === this.fun)) {
+  for (var prop in receiver) {
+    if (%_CallFunction(receiver, prop, ObjectLookupGetter) === fun ||
+        %_CallFunction(receiver, prop, ObjectLookupSetter) === fun ||
+        (IS_OBJECT(receiver) && %GetDataProperty(receiver, prop) === fun)) {
       // If we find more than one match bail out to avoid confusion.
       if (name) {
         return null;
@@ -846,49 +850,49 @@
 }
 
 function CallSiteGetFileName() {
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   return script ? script.name : null;
 }
 
 function CallSiteGetLineNumber() {
-  if (this.pos == -1) {
+  if (this[CallSitePositionKey] == -1) {
     return null;
   }
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   var location = null;
   if (script) {
-    location = script.locationFromPosition(this.pos, true);
+    location = script.locationFromPosition(this[CallSitePositionKey], true);
   }
   return location ? location.line + 1 : null;
 }
 
 function CallSiteGetColumnNumber() {
-  if (this.pos == -1) {
+  if (this[CallSitePositionKey] == -1) {
     return null;
   }
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   var location = null;
   if (script) {
-    location = script.locationFromPosition(this.pos, true);
+    location = script.locationFromPosition(this[CallSitePositionKey], true);
   }
   return location ? location.column + 1: null;
 }
 
 function CallSiteIsNative() {
-  var script = %FunctionGetScript(this.fun);
+  var script = %FunctionGetScript(this[CallSiteFunctionKey]);
   return script ? (script.type == TYPE_NATIVE) : false;
 }
 
 function CallSiteGetPosition() {
-  return this.pos;
+  return this[CallSitePositionKey];
 }
 
 function CallSiteIsConstructor() {
-  var receiver = this.receiver;
+  var receiver = this[CallSiteReceiverKey];
   var constructor =
       IS_OBJECT(receiver) ? %GetDataProperty(receiver, "constructor") : null;
   if (!constructor) return false;
-  return this.fun === constructor;
+  return this[CallSiteFunctionKey] === constructor;
 }
 
 function CallSiteToString() {
@@ -931,7 +935,7 @@
   var isConstructor = this.isConstructor();
   var isMethodCall = !(this.isToplevel() || isConstructor);
   if (isMethodCall) {
-    var typeName = GetTypeName(this, true);
+    var typeName = GetTypeName(this[CallSiteReceiverKey], true);
     var methodName = this.getMethodName();
     if (functionName) {
       if (typeName &&
@@ -1035,13 +1039,15 @@
 
 function GetStackFrames(raw_stack) {
   var frames = new InternalArray();
-  for (var i = 0; i < raw_stack.length; i += 4) {
+  var non_strict_frames = raw_stack[0];
+  for (var i = 1; i < raw_stack.length; i += 4) {
     var recv = raw_stack[i];
     var fun = raw_stack[i + 1];
     var code = raw_stack[i + 2];
     var pc = raw_stack[i + 3];
     var pos = %FunctionGetPositionForOffset(code, pc);
-    frames.push(new CallSite(recv, fun, pos));
+    non_strict_frames--;
+    frames.push(new CallSite(recv, fun, pos, (non_strict_frames < 0)));
   }
   return frames;
 }
@@ -1069,16 +1075,16 @@
 }
 
 
-function GetTypeName(obj, requireConstructor) {
-  var constructor = obj.receiver.constructor;
+function GetTypeName(receiver, requireConstructor) {
+  var constructor = receiver.constructor;
   if (!constructor) {
     return requireConstructor ? null :
-        %_CallFunction(obj.receiver, ObjectToString);
+        %_CallFunction(receiver, ObjectToString);
   }
   var constructorName = constructor.name;
   if (!constructorName) {
     return requireConstructor ? null :
-        %_CallFunction(obj.receiver, ObjectToString);
+        %_CallFunction(receiver, ObjectToString);
   }
   return constructorName;
 }
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 54efd94..1901f9c 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -227,13 +227,12 @@
         (JSArray::kSize + FixedArray::kHeaderSize) / kPointerSize);
   __ sra(scratch1, array_size, kSmiTagSize);
   __ Addu(elements_array_end, elements_array_end, scratch1);
-  __ AllocateInNewSpace(
-      elements_array_end,
-      result,
-      scratch1,
-      scratch2,
-      gc_required,
-      static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
+  __ Allocate(elements_array_end,
+              result,
+              scratch1,
+              scratch2,
+              gc_required,
+              static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
@@ -895,7 +894,7 @@
       // a1: constructor function
       // a2: initial map
       __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
-      __ AllocateInNewSpace(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
+      __ Allocate(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
 
       // Allocated the JSObject, now initialize the fields. Map is set to
       // initial map and properties and elements are set to empty fixed array.
@@ -974,7 +973,7 @@
       // t4: JSObject
       // t5: start of next object
       __ Addu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize));
-      __ AllocateInNewSpace(
+      __ Allocate(
           a0,
           t5,
           t6,
@@ -1130,10 +1129,6 @@
     __ GetObjectType(v0, a1, a3);
     __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
 
-    // Symbols are "objects".
-    __ lbu(a3, FieldMemOperand(a1, Map::kInstanceTypeOffset));
-    __ Branch(&exit, eq, a3, Operand(SYMBOL_TYPE));
-
     // Throw away the result of the constructor invocation and use the
     // on-stack receiver as the result.
     __ bind(&use_receiver);
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index a13cb93..37d7720 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -96,7 +96,7 @@
   // stack param count needs (constructor pointer, and single argument)
   descriptor->stack_parameter_count_ = &a0;
   descriptor->register_params_ = registers;
-  descriptor->extra_expression_stack_count_ = 1;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
       FUNCTION_ADDR(ArrayConstructor_StubFailure);
 }
@@ -684,6 +684,8 @@
                                      Register scratch1,
                                      Register scratch2,
                                      Label* not_number) {
+  ASSERT(!object.is(dst1) && !object.is(dst2));
+
   __ AssertRootValue(heap_number_map,
                      Heap::kHeapNumberMapRootIndex,
                      "HeapNumberMap register clobbered.");
@@ -878,6 +880,10 @@
   ASSERT(!heap_number_map.is(object) &&
          !heap_number_map.is(scratch1) &&
          !heap_number_map.is(scratch2));
+  // ARM uses pop/push and Ldlr to save dst_* and probably object registers in
+  // softfloat path. On MIPS there is no ldlr, 1st lw instruction may overwrite
+  // object register making the 2nd lw invalid.
+  ASSERT(!object.is(dst_mantissa) && !object.is(dst_exponent));
 
   Label done, obj_is_not_smi;
 
@@ -914,49 +920,24 @@
     if (destination == kCoreRegisters) {
       __ Move(dst_mantissa, dst_exponent, double_dst);
     }
-
   } else {
-    ASSERT(!scratch1.is(object) && !scratch2.is(object));
     // Load the double value in the destination registers.
-    bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent);
-    if (save_registers) {
-      // Save both output registers, because the other one probably holds
-      // an important value too.
-      __ Push(dst_exponent, dst_mantissa);
-    }
     __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
     __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
 
     // Check for 0 and -0.
-    Label zero;
     __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask));
     __ Or(scratch1, scratch1, Operand(dst_mantissa));
-    __ Branch(&zero, eq, scratch1, Operand(zero_reg));
+    __ Branch(&done, eq, scratch1, Operand(zero_reg));
 
     // Check that the value can be exactly represented by a 32-bit integer.
     // Jump to not_int32 if that's not the case.
-    Label restore_input_and_miss;
     DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2,
-                         &restore_input_and_miss);
+                         not_int32);
 
     // dst_* were trashed. Reload the double value.
-    if (save_registers) {
-      __ Pop(dst_exponent, dst_mantissa);
-    }
     __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
     __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
-    __ Branch(&done);
-
-    __ bind(&restore_input_and_miss);
-    if (save_registers) {
-      __ Pop(dst_exponent, dst_mantissa);
-    }
-    __ Branch(not_int32);
-
-    __ bind(&zero);
-    if (save_registers) {
-      __ Drop(2);
-    }
   }
 
   __ bind(&done);
@@ -2707,16 +2688,20 @@
               masm, destination, right, f14, a2, a3, heap_number_map,
               scratch1, scratch2, fail);
         }
+        // Use scratch3 as left in LoadNumber functions to avoid overwriting of
+        // left (a0) register.
+        __ mov(scratch3, left);
+
         // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it
         // jumps to |miss|.
         if (left_type == BinaryOpIC::INT32) {
           FloatingPointHelper::LoadNumberAsInt32Double(
-              masm, left, destination, f12, f16, a0, a1, heap_number_map,
+              masm, scratch3, destination, f12, f16, a0, a1, heap_number_map,
               scratch1, scratch2, f2, miss);
         } else {
           Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers;
           FloatingPointHelper::LoadNumber(
-              masm, destination, left, f12, a0, a1, heap_number_map,
+              masm, destination, scratch3, f12, a0, a1, heap_number_map,
               scratch1, scratch2, fail);
         }
       }
@@ -4555,35 +4540,6 @@
 }
 
 
-void ArrayLengthStub::Generate(MacroAssembler* masm) {
-  Label miss;
-  Register receiver;
-  if (kind() == Code::KEYED_LOAD_IC) {
-    // ----------- S t a t e -------------
-    //  -- ra    : return address
-    //  -- a0    : key
-    //  -- a1    : receiver
-    // -----------------------------------
-    __ Branch(&miss, ne, a0,
-        Operand(masm->isolate()->factory()->length_string()));
-    receiver = a1;
-  } else {
-    ASSERT(kind() == Code::LOAD_IC);
-    // ----------- S t a t e -------------
-    //  -- a2    : name
-    //  -- ra    : return address
-    //  -- a0    : receiver
-    //  -- sp[0] : receiver
-    // -----------------------------------
-    receiver = a0;
-  }
-
-  StubCompiler::GenerateLoadArrayLength(masm, receiver, a3, &miss);
-  __ bind(&miss);
-  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
-}
-
-
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver;
@@ -4872,7 +4828,7 @@
   __ Addu(t5, t5, Operand(Heap::kArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
-  __ AllocateInNewSpace(t5, v0, a3, t0, &runtime, TAG_OBJECT);
+  __ Allocate(t5, v0, a3, t0, &runtime, TAG_OBJECT);
 
   // v0 = address of new object(s) (tagged)
   // a2 = argument count (tagged)
@@ -5063,13 +5019,8 @@
   __ Addu(a1, a1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(a1,
-                        v0,
-                        a2,
-                        a3,
-                        &runtime,
-                        static_cast<AllocationFlags>(TAG_OBJECT |
-                                                     SIZE_IN_WORDS));
+  __ Allocate(a1, v0, a2, a3, &runtime,
+              static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
 
   // Get the arguments boilerplate from the current native context.
   __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
@@ -5589,7 +5540,7 @@
       (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
   __ srl(t1, a1, kSmiTagSize + kSmiShiftSize);
   __ Addu(a2, t1, Operand(objects_size));
-  __ AllocateInNewSpace(
+  __ Allocate(
       a2,  // In: Size, in words.
       v0,  // Out: Start of allocation (tagged).
       a3,  // Scratch register.
@@ -8136,6 +8087,9 @@
   int parameter_count_offset =
       StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
   __ lw(a1, MemOperand(fp, parameter_count_offset));
+  if (function_mode_ == JS_FUNCTION_STUB_MODE) {
+    __ Addu(a1, a1, Operand(1));
+  }
   masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
   __ sll(a1, a1, kPointerSizeLog2);
   __ Addu(sp, sp, a1);
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 967bb5b..bd403ce 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -206,8 +206,9 @@
   // Allocate new FixedDoubleArray.
   __ sll(scratch, t1, 2);
   __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize);
-  __ AllocateInNewSpace(scratch, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
+  __ Allocate(scratch, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
   // t2: destination FixedDoubleArray, not tagged as heap object
+
   // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex);
   __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
@@ -351,7 +352,7 @@
   // Allocate new FixedArray.
   __ sll(a0, t1, 1);
   __ Addu(a0, a0, FixedDoubleArray::kHeaderSize);
-  __ AllocateInNewSpace(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
+  __ Allocate(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
   // t2: destination FixedArray, not tagged as heap object
   // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex);
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index bacec10..3e7c8da 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -2780,28 +2780,6 @@
 }
 
 
-void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  ASSERT(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  __ JumpIfSmi(v0, if_false);
-  __ GetObjectType(v0, a1, a2);
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  Split(eq, a2, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -4320,6 +4298,10 @@
     __ And(a1, a1, Operand(1 << Map::kIsUndetectable));
     Split(eq, a1, Operand(zero_reg),
           if_true, if_false, fall_through);
+  } else if (check->Equals(isolate()->heap()->symbol_string())) {
+    __ JumpIfSmi(v0, if_false);
+    __ GetObjectType(v0, v0, a1);
+    Split(eq, a1, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->boolean_string())) {
     __ LoadRoot(at, Heap::kTrueValueRootIndex);
     __ Branch(if_true, eq, v0, Operand(at));
@@ -4351,10 +4333,6 @@
       __ LoadRoot(at, Heap::kNullValueRootIndex);
       __ Branch(if_true, eq, v0, Operand(at));
     }
-    if (FLAG_harmony_symbols) {
-      __ GetObjectType(v0, v0, a1);
-      __ Branch(if_true, eq, a1, Operand(SYMBOL_TYPE));
-    }
     // Check for JS objects => true.
     __ GetObjectType(v0, v0, a1);
     __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index c32be4f..b5d6c45 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -1492,13 +1492,6 @@
 }
 
 
-void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
-  Register result = ToRegister(instr->result());
-  Register array = ToRegister(instr->value());
-  __ lw(result, FieldMemOperand(array, JSArray::kLengthOffset));
-}
-
-
 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
   Register result = ToRegister(instr->result());
   Register array = ToRegister(instr->value());
@@ -1901,6 +1894,13 @@
         __ bind(&not_string);
       }
 
+      if (expected.Contains(ToBooleanStub::SYMBOL)) {
+        // Symbol value -> true.
+        const Register scratch = scratch1();
+        __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
+        __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE));
+      }
+
       if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
         CpuFeatureScope scope(masm(), FPU);
         // heap number -> false iff +0, -0, or NaN.
@@ -4571,10 +4571,11 @@
 
 // Convert unsigned integer with specified number of leading zeroes in binary
 // representation to IEEE 754 double.
-// Integer to convert is passed in register hiword.
+// Integer to convert is passed in register src.
 // Resulting double is returned in registers hiword:loword.
 // This functions does not work correctly for 0.
 static void GenerateUInt2Double(MacroAssembler* masm,
+                                Register src,
                                 Register hiword,
                                 Register loword,
                                 Register scratch,
@@ -4588,12 +4589,12 @@
       kBitsPerInt - mantissa_shift_for_hi_word;
   masm->li(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
   if (mantissa_shift_for_hi_word > 0) {
-    masm->sll(loword, hiword, mantissa_shift_for_lo_word);
-    masm->srl(hiword, hiword, mantissa_shift_for_hi_word);
+    masm->sll(loword, src, mantissa_shift_for_lo_word);
+    masm->srl(hiword, src, mantissa_shift_for_hi_word);
     masm->Or(hiword, scratch, hiword);
   } else {
     masm->mov(loword, zero_reg);
-    masm->sll(hiword, hiword, mantissa_shift_for_hi_word);
+    masm->sll(hiword, src, mantissa_shift_for_hi_word);
     masm->Or(hiword, scratch, hiword);
   }
 
@@ -4644,17 +4645,17 @@
       __ mtc1(src, dbl_scratch);
       __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
     } else {
-      Label no_leading_zero, done;
+      Label no_leading_zero, convert_done;
       __ And(at, src, Operand(0x80000000));
       __ Branch(&no_leading_zero, ne, at, Operand(zero_reg));
 
       // Integer has one leading zeros.
-      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1);
-      __ Branch(&done);
+      GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 1);
+      __ Branch(&convert_done);
 
       __ bind(&no_leading_zero);
-      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 0);
-      __ Branch(&done);
+      GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 0);
+      __ bind(&convert_done);
     }
   }
 
@@ -5344,12 +5345,12 @@
     __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
-    __ AllocateInNewSpace(size,
-                          result,
-                          scratch,
-                          scratch2,
-                          deferred->entry(),
-                          flags);
+    __ Allocate(size,
+                result,
+                scratch,
+                scratch2,
+                deferred->entry(),
+                flags);
   }
 
   __ bind(deferred->exit());
@@ -5771,6 +5772,13 @@
     cmp2 = Operand(zero_reg);
     final_branch_condition = eq;
 
+  } else if (type_name->Equals(heap()->symbol_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ GetObjectType(input, input, scratch);
+    cmp1 = scratch;
+    cmp2 = Operand(SYMBOL_TYPE);
+    final_branch_condition = eq;
+
   } else if (type_name->Equals(heap()->boolean_string())) {
     __ LoadRoot(at, Heap::kTrueValueRootIndex);
     __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
@@ -5814,27 +5822,15 @@
       __ LoadRoot(at, Heap::kNullValueRootIndex);
       __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
     }
-    if (FLAG_harmony_symbols) {
-      // input is an object, it is safe to use GetObjectType in the delay slot.
-      __ GetObjectType(input, input, scratch);
-      __ Branch(USE_DELAY_SLOT, true_label, eq, scratch, Operand(SYMBOL_TYPE));
-      // Still an object, so the InstanceType can be loaded.
-      __ lbu(scratch, FieldMemOperand(input, Map::kInstanceTypeOffset));
-      __ Branch(USE_DELAY_SLOT, false_label,
-                lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
-    } else {
-      // input is an object, it is safe to use GetObjectType in the delay slot.
-      __ GetObjectType(input, input, scratch);
-      __ Branch(USE_DELAY_SLOT, false_label,
-                lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
-    }
-    // Still an object, so the InstanceType can be loaded.
-    __ lbu(scratch, FieldMemOperand(input, Map::kInstanceTypeOffset));
+    Register map = input;
+    __ GetObjectType(input, map, scratch);
+    __ Branch(false_label,
+              lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
     __ Branch(USE_DELAY_SLOT, false_label,
               gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
-    // Still an object, so the BitField can be loaded.
+    // map is still valid, so the BitField can be loaded in delay slot.
     // Check for undetectable objects => false.
-    __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset));
+    __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
     __ And(at, at, 1 << Map::kIsUndetectable);
     cmp1 = at;
     cmp2 = Operand(zero_reg);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 8848032..652c7ca 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -871,6 +871,35 @@
   LInstruction* instr = current->CompileToLithium(this);
 
   if (instr != NULL) {
+#if DEBUG
+    // Make sure that the lithium instruction has either no fixed register
+    // constraints in temps or the result OR no uses that are only used at
+    // start. If this invariant doesn't hold, the register allocator can decide
+    // to insert a split of a range immediately before the instruction due to an
+    // already allocated register needing to be used for the instruction's fixed
+    // register constraint. In this case, The register allocator won't see an
+    // interference between the split child and the use-at-start (it would if
+    // the it was just a plain use), so it is free to move the split child into
+    // the same register that is used for the use-at-start.
+    // See https://code.google.com/p/chromium/issues/detail?id=201590
+    if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+      int fixed = 0;
+      int used_at_start = 0;
+      for (UseIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->IsUsedAtStart()) ++used_at_start;
+      }
+      if (instr->Output() != NULL) {
+        if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
+      }
+      for (TempIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->HasFixedPolicy()) ++fixed;
+      }
+      ASSERT(fixed == 0 || used_at_start == 0);
+    }
+#endif
+
     if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
       instr = AssignPointerMap(instr);
     }
@@ -1116,7 +1145,7 @@
     LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp);
     return DefineFixedDouble(result, f4);
   } else {
-    LOperand* input = UseRegisterAtStart(instr->value());
+    LOperand* input = UseRegister(instr->value());
 
     LOperand* temp = (op == kMathRound) ? FixedTemp(f6) :
         (op == kMathFloor) ? TempRegister() : NULL;
@@ -1585,12 +1614,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
-  LOperand* array = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LJSArrayLength(array));
-}
-
-
 LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
     HFixedArrayBaseLength* instr) {
   LOperand* array = UseRegisterAtStart(instr->value());
@@ -1697,11 +1720,13 @@
       return AssignEnvironment(DefineAsRegister(res));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = UseRegisterAtStart(instr->value());
+      LOperand* value = NULL;
       LInstruction* res = NULL;
       if (instr->value()->type().IsSmi()) {
+        value = UseRegisterAtStart(instr->value());
         res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
+        value = UseRegister(instr->value());
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                       : NULL;
@@ -2081,7 +2106,7 @@
     LOperand* new_map_reg = TempRegister();
     LTransitionElementsKind* result =
         new(zone()) LTransitionElementsKind(object, new_map_reg, NULL);
-    return DefineSameAsFirst(result);
+    return result;
   } else if (FLAG_compiled_transitions) {
     LTransitionElementsKind* result =
         new(zone()) LTransitionElementsKind(object, NULL, NULL);
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 80635c3..e995905 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -120,7 +120,6 @@
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
-  V(JSArrayLength)                              \
   V(Label)                                      \
   V(LazyBailout)                                \
   V(LoadContextSlot)                            \
@@ -291,7 +290,6 @@
   SetOncePointer<LPointerMap> pointer_map_;
   HValue* hydrogen_value_;
   bool is_call_;
-  bool is_save_doubles_;
 };
 
 
@@ -1111,19 +1109,6 @@
 };
 
 
-class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LJSArrayLength(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  LOperand* value() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
-  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
-};
-
-
 class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LFixedArrayBaseLength(LOperand* value) {
@@ -2060,7 +2045,7 @@
 };
 
 
-class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
+class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> {
  public:
   LTransitionElementsKind(LOperand* object,
                           LOperand* new_map_temp,
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 33ff9ab..12e1025 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -1928,7 +1928,7 @@
                                  BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
 
-  int32_t offset;
+  int32_t offset = 0;
   Register r2 = no_reg;
   Register scratch = at;
   if (rt.is_reg()) {
@@ -2361,7 +2361,7 @@
                                         BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
 
-  int32_t offset;
+  int32_t offset = 0;
   Register r2 = no_reg;
   Register scratch = at;
   if (rt.is_reg()) {
@@ -3002,13 +3002,12 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(Register object_size,
-                                        Register result,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
+void MacroAssembler::Allocate(Register object_size,
+                              Register result,
+                              Register scratch1,
+                              Register scratch2,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3029,19 +3028,19 @@
   // Check relative positions of allocation top and limit addresses.
   // ARM adds additional checks to make sure the ldm instruction can be
   // used. On MIPS we don't have ldm so we don't need additional checks either.
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
   intptr_t top   =
-      reinterpret_cast<intptr_t>(new_space_allocation_top.address());
+      reinterpret_cast<intptr_t>(allocation_top.address());
   intptr_t limit =
-      reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
+      reinterpret_cast<intptr_t>(allocation_limit.address());
   ASSERT((limit - top) == kPointerSize);
 
   // Set up allocation top address and object size registers.
   Register topaddr = scratch1;
-  li(topaddr, Operand(new_space_allocation_top));
+  li(topaddr, Operand(allocation_top));
 
   // This code stores a temporary value in t9.
   if ((flags & RESULT_CONTAINS_TOP) == 0) {
@@ -3120,12 +3119,12 @@
   And(scratch1, scratch1, Operand(~kObjectAlignmentMask));
 
   // Allocate two-byte string in new space.
-  AllocateInNewSpace(scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   InitializeNewString(result,
@@ -3150,12 +3149,12 @@
   And(scratch1, scratch1, Operand(~kObjectAlignmentMask));
 
   // Allocate ASCII string in new space.
-  AllocateInNewSpace(scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   InitializeNewString(result,
@@ -5515,7 +5514,6 @@
 
 CodePatcher::CodePatcher(byte* address, int instructions)
     : address_(address),
-      instructions_(instructions),
       size_(instructions * Assembler::kInstrSize),
       masm_(NULL, address, size_ + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index e4cf3bc..125cc8a 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -491,12 +491,12 @@
                 Label* gc_required,
                 AllocationFlags flags);
 
-  void AllocateInNewSpace(Register object_size,
-                          Register result,
-                          Register scratch1,
-                          Register scratch2,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(Register object_size,
+                Register result,
+                Register scratch1,
+                Register scratch2,
+                Label* gc_required,
+                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. The caller must make sure that no pointers
@@ -1565,7 +1565,6 @@
 
  private:
   byte* address_;  // The address of the code being patched.
-  int instructions_;  // Number of instructions of the expected patch size.
   int size_;  // Number of bytes of the expected patch size.
   MacroAssembler masm_;  // Macro assembler used to generate the code.
 };
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index be9f369..5eb79eb 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -132,8 +132,8 @@
   ASSERT(msg != NULL);
 
   // Update this stop description.
-  if (!watched_stops[code].desc) {
-    watched_stops[code].desc = msg;
+  if (!watched_stops_[code].desc) {
+    watched_stops_[code].desc = msg;
   }
 
   if (strlen(msg) > 0) {
@@ -163,8 +163,8 @@
   char* msg = *reinterpret_cast<char**>(sim_->get_pc() +
       Instruction::kInstrSize);
   // Update this stop description.
-  if (!sim_->watched_stops[code].desc) {
-    sim_->watched_stops[code].desc = msg;
+  if (!sim_->watched_stops_[code].desc) {
+    sim_->watched_stops_[code].desc = msg;
   }
   PrintF("Simulator hit %s (%u)\n", msg, code);
   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
@@ -513,7 +513,7 @@
         int32_t words;
         if (argc == next_arg) {
           words = 10;
-        } else if (argc == next_arg + 1) {
+        } else {
           if (!GetValue(argv[next_arg], &words)) {
             words = 10;
           }
@@ -1636,33 +1636,33 @@
 bool Simulator::IsEnabledStop(uint32_t code) {
   ASSERT(code <= kMaxStopCode);
   ASSERT(code > kMaxWatchpointCode);
-  return !(watched_stops[code].count & kStopDisabledBit);
+  return !(watched_stops_[code].count & kStopDisabledBit);
 }
 
 
 void Simulator::EnableStop(uint32_t code) {
   if (!IsEnabledStop(code)) {
-    watched_stops[code].count &= ~kStopDisabledBit;
+    watched_stops_[code].count &= ~kStopDisabledBit;
   }
 }
 
 
 void Simulator::DisableStop(uint32_t code) {
   if (IsEnabledStop(code)) {
-    watched_stops[code].count |= kStopDisabledBit;
+    watched_stops_[code].count |= kStopDisabledBit;
   }
 }
 
 
 void Simulator::IncreaseStopCounter(uint32_t code) {
   ASSERT(code <= kMaxStopCode);
-  if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) {
+  if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
     PrintF("Stop counter for code %i has overflowed.\n"
            "Enabling this code and reseting the counter to 0.\n", code);
-    watched_stops[code].count = 0;
+    watched_stops_[code].count = 0;
     EnableStop(code);
   } else {
-    watched_stops[code].count++;
+    watched_stops_[code].count++;
   }
 }
 
@@ -1677,12 +1677,12 @@
     return;
   }
   const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";
-  int32_t count = watched_stops[code].count & ~kStopDisabledBit;
+  int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
   // Don't print the state of unused breakpoints.
   if (count != 0) {
-    if (watched_stops[code].desc) {
+    if (watched_stops_[code].desc) {
       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
-             code, code, state, count, watched_stops[code].desc);
+             code, code, state, count, watched_stops_[code].desc);
     } else {
       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
              code, code, state, count);
diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h
index 67f5953..ed63443 100644
--- a/src/mips/simulator-mips.h
+++ b/src/mips/simulator-mips.h
@@ -391,14 +391,14 @@
   static const uint32_t kStopDisabledBit = 1 << 31;
 
   // A stop is enabled, meaning the simulator will stop when meeting the
-  // instruction, if bit 31 of watched_stops[code].count is unset.
-  // The value watched_stops[code].count & ~(1 << 31) indicates how many times
+  // instruction, if bit 31 of watched_stops_[code].count is unset.
+  // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
   // the breakpoint was hit or gone through.
   struct StopCountAndDesc {
     uint32_t count;
     char* desc;
   };
-  StopCountAndDesc watched_stops[kMaxStopCode + 1];
+  StopCountAndDesc watched_stops_[kMaxStopCode + 1];
 };
 
 
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index d5cf6de..da6770a 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -415,7 +415,7 @@
 // may be clobbered.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Handle<JSObject> object,
-                                      int index,
+                                      LookupResult* lookup,
                                       Handle<Map> transition,
                                       Handle<Name> name,
                                       Register receiver_reg,
@@ -428,16 +428,6 @@
   // a0 : value.
   Label exit;
 
-  LookupResult lookup(masm->isolate());
-  object->Lookup(*name, &lookup);
-  if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
-    // In sloppy mode, we could just return the value and be done. However, we
-    // might be in strict mode, where we have to throw. Since we cannot tell,
-    // go into slow case unconditionally.
-    __ jmp(miss_label);
-    return;
-  }
-
   // Check that the map of the object hasn't changed.
   CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
                                              : REQUIRE_EXACT_MAP;
@@ -452,8 +442,9 @@
   // Check that we are allowed to write this.
   if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
     JSObject* holder;
-    if (lookup.IsFound()) {
-      holder = lookup.holder();
+    // holder == object indicates that no property was found.
+    if (lookup->holder() != *object) {
+      holder = lookup->holder();
     } else {
       // Find the top object.
       holder = *object;
@@ -461,8 +452,19 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, miss_restore_name);
+    Register holder_reg = CheckPrototypes(
+        object, receiver_reg, Handle<JSObject>(holder), name_reg,
+        scratch1, scratch2, name, miss_restore_name);
+    // If no property was found, and the holder (the last object in the
+    // prototype chain) is in slow mode, we need to do a negative lookup on the
+    // holder.
+    if (lookup->holder() == *object &&
+        !holder->HasFastProperties() &&
+        !holder->IsJSGlobalProxy() &&
+        !holder->IsJSGlobalObject()) {
+      GenerateDictionaryNegativeLookup(
+          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    }
   }
 
   // Stub never generated for non-global objects that require access
@@ -483,6 +485,7 @@
     return;
   }
 
+  int index;
   if (!transition.is_null()) {
     // Update the map of the object.
     __ li(scratch1, Operand(transition));
@@ -498,6 +501,10 @@
                         kDontSaveFPRegs,
                         OMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
+    index = transition->instance_descriptors()->GetFieldIndex(
+        transition->LastAdded());
+  } else {
+    index = lookup->GetFieldIndex().field_index();
   }
 
   // Adjust for the number of properties stored in the object. Even in the
@@ -2424,6 +2431,12 @@
       // Check that the object is a symbol.
       __ GetObjectType(a1, a1, a3);
       __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE));
+      // Check that the maps starting from the prototype haven't changed.
+      GenerateDirectLoadGlobalFunctionPrototype(
+          masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss);
+      CheckPrototypes(
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+          a0, holder, a3, a1, t0, name, &miss);
       break;
 
     case NUMBER_CHECK: {
@@ -3010,7 +3023,7 @@
   __ Check(eq, "Instance size of initial map changed.",
            a3, Operand(instance_size >> kPointerSizeLog2));
 #endif
-  __ AllocateInNewSpace(a3, t4, t5, t6, &generic_stub_call, SIZE_IN_WORDS);
+  __ Allocate(a3, t4, t5, t6, &generic_stub_call, SIZE_IN_WORDS);
 
   // Allocated the JSObject, now initialize the fields. Map is set to initial
   // map and properties and elements are set to empty fixed array.
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 7f1a05a..e1fd872 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -638,7 +638,7 @@
   // Find all the named properties.
   if (kind & PropertyKind.Named) {
     // Get the local property names.
-    propertyNames = %GetLocalPropertyNames(this.value_);
+    propertyNames = %GetLocalPropertyNames(this.value_, true);
     total += propertyNames.length;
 
     // Get names for named interceptor properties if any.
diff --git a/src/object-observe.js b/src/object-observe.js
index b35f547..bfb4a65 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -117,6 +117,9 @@
 }
 
 function EnqueueChangeRecord(changeRecord, observers) {
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (IS_SYMBOL(changeRecord.name)) return;
+
   for (var i = 0; i < observers.length; i++) {
     var observer = observers[i];
     var observerInfo = observerInfoMap.get(observer);
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 82a71a5..44cab53 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -195,6 +195,9 @@
     case JS_MESSAGE_OBJECT_TYPE:
       JSMessageObject::cast(this)->JSMessageObjectVerify();
       break;
+    case JS_ARRAY_BUFFER_TYPE:
+      JSArrayBuffer::cast(this)->JSArrayBufferVerify();
+      break;
 
 #define MAKE_STRUCT_CASE(NAME, Name, name) \
   case NAME##_TYPE:                        \
@@ -220,6 +223,7 @@
   CHECK(IsSymbol());
   CHECK(HasHashCode());
   CHECK_GT(Hash(), 0);
+  CHECK(name()->IsUndefined() || name()->IsString());
 }
 
 
@@ -711,6 +715,14 @@
   VerifyPointer(construct_trap());
 }
 
+void JSArrayBuffer::JSArrayBufferVerify() {
+  CHECK(IsJSArrayBuffer());
+  JSObjectVerify();
+  VerifyPointer(byte_length());
+  CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber()
+        || byte_length()->IsUndefined());
+}
+
 
 void Foreign::ForeignVerify() {
   CHECK(IsForeign());
diff --git a/src/objects-inl.h b/src/objects-inl.h
index ba0a7f8..ec03405 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -674,6 +674,7 @@
 
 
 TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
+TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
 TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
 
 
@@ -1490,13 +1491,17 @@
 bool JSObject::TryTransitionToField(Handle<JSObject> object,
                                     Handle<Name> key) {
   if (!object->map()->HasTransitionArray()) return false;
-  TransitionArray* transitions = object->map()->transitions();
-  int transition = transitions->Search(*key);
-  if (transition == TransitionArray::kNotFound) return false;
-  PropertyDetails target_details = transitions->GetTargetDetails(transition);
-  if (target_details.type() != FIELD) return false;
-  if (target_details.attributes() != NONE) return false;
-  Handle<Map> target(transitions->GetTarget(transition));
+  Handle<Map> target;
+  {
+    AssertNoAllocation no_allocation;
+    TransitionArray* transitions = object->map()->transitions();
+    int transition = transitions->Search(*key);
+    if (transition == TransitionArray::kNotFound) return false;
+    PropertyDetails target_details = transitions->GetTargetDetails(transition);
+    if (target_details.type() != FIELD) return false;
+    if (target_details.attributes() != NONE) return false;
+    target = Handle<Map>(transitions->GetTarget(transition));
+  }
   JSObject::AddFastPropertyUsingMap(object, target);
   return true;
 }
@@ -1558,6 +1563,8 @@
       return JSDate::kSize;
     case JS_ARRAY_TYPE:
       return JSArray::kSize;
+    case JS_ARRAY_BUFFER_TYPE:
+      return JSArrayBuffer::kSize;
     case JS_SET_TYPE:
       return JSSet::kSize;
     case JS_MAP_TYPE:
@@ -2444,6 +2451,7 @@
 CAST_ACCESSOR(JSBuiltinsObject)
 CAST_ACCESSOR(Code)
 CAST_ACCESSOR(JSArray)
+CAST_ACCESSOR(JSArrayBuffer)
 CAST_ACCESSOR(JSRegExp)
 CAST_ACCESSOR(JSProxy)
 CAST_ACCESSOR(JSFunctionProxy)
@@ -2500,11 +2508,17 @@
 
 bool Name::Equals(Name* other) {
   if (other == this) return true;
-  if (this->IsUniqueName() && other->IsUniqueName()) return false;
+  if (this->IsSymbol() || other->IsSymbol() ||
+      (this->IsInternalizedString() && other->IsInternalizedString())) {
+    return false;
+  }
   return String::cast(this)->SlowEquals(String::cast(other));
 }
 
 
+ACCESSORS(Symbol, name, Object, kNameOffset)
+
+
 bool String::Equals(String* other) {
   if (other == this) return true;
   if (this->IsInternalizedString() && other->IsInternalizedString()) {
@@ -4508,6 +4522,7 @@
                kDontOptimize)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
 
 void SharedFunctionInfo::BeforeVisitingPointers() {
   if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
@@ -5124,6 +5139,21 @@
 ACCESSORS(JSArray, length, Object, kLengthOffset)
 
 
+void* JSArrayBuffer::backing_store() {
+  intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
+  return reinterpret_cast<void*>(ptr);
+}
+
+
+void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
+  intptr_t ptr = reinterpret_cast<intptr_t>(value);
+  WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
+}
+
+
+ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
+
+
 ACCESSORS(JSRegExp, data, Object, kDataOffset)
 
 
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 4522ee4..8342232 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -184,6 +184,8 @@
     case JS_GLOBAL_PROPERTY_CELL_TYPE:
       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out);
       break;
+    case JS_ARRAY_BUFFER_TYPE:
+      JSArrayBuffer::cast(this)->JSArrayBufferPrint(out);
 #define MAKE_STRUCT_CASE(NAME, Name, name) \
   case NAME##_TYPE:                        \
     Name::cast(this)->Name##Print(out);    \
@@ -552,6 +554,9 @@
 void Symbol::SymbolPrint(FILE* out) {
   HeapObject::PrintHeader(out, "Symbol");
   PrintF(out, " - hash: %d\n", Hash());
+  PrintF(out, " - name: ");
+  name()->ShortPrint();
+  PrintF(out, "\n");
 }
 
 
@@ -792,6 +797,16 @@
 }
 
 
+void JSArrayBuffer::JSArrayBufferPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "JSArrayBuffer");
+  PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
+  PrintF(out, " - backing_store = -0x%p\n", backing_store());
+  PrintF(out, " - byte_length = ");
+  byte_length()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
 void JSFunction::JSFunctionPrint(FILE* out) {
   HeapObject::PrintHeader(out, "Function");
   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 2b7fcf3..6a64cbf 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -49,6 +49,11 @@
                   SlicedString::BodyDescriptor,
                   int>::Visit);
 
+  table_.Register(kVisitSymbol,
+                  &FixedBodyVisitor<StaticVisitor,
+                  Symbol::BodyDescriptor,
+                  int>::Visit);
+
   table_.Register(kVisitFixedArray,
                   &FlexibleBodyVisitor<StaticVisitor,
                   FixedArray::BodyDescriptor,
@@ -110,6 +115,11 @@
                   SlicedString::BodyDescriptor,
                   void>::Visit);
 
+  table_.Register(kVisitSymbol,
+                  &FixedBodyVisitor<StaticVisitor,
+                  Symbol::BodyDescriptor,
+                  void>::Visit);
+
   table_.Register(kVisitFixedArray, &FixedArrayVisitor::Visit);
 
   table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
diff --git a/src/objects-visiting.cc b/src/objects-visiting.cc
index 088f5eb..fa53562 100644
--- a/src/objects-visiting.cc
+++ b/src/objects-visiting.cc
@@ -129,9 +129,7 @@
                                  Foreign::kSize);
 
     case SYMBOL_TYPE:
-      return GetVisitorIdForSize(kVisitDataObject,
-                                 kVisitDataObjectGeneric,
-                                 Symbol::kSize);
+      return kVisitSymbol;
 
     case FILLER_TYPE:
       return kVisitDataObjectGeneric;
@@ -146,6 +144,7 @@
     case JS_GLOBAL_OBJECT_TYPE:
     case JS_BUILTINS_OBJECT_TYPE:
     case JS_MESSAGE_OBJECT_TYPE:
+    case JS_ARRAY_BUFFER_TYPE:
       return GetVisitorIdForSize(kVisitJSObject,
                                  kVisitJSObjectGeneric,
                                  instance_size);
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index 9b2422c..d4a2ed2 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -84,6 +84,7 @@
   V(StructGeneric)            \
   V(ConsString)               \
   V(SlicedString)             \
+  V(Symbol)                   \
   V(Oddball)                  \
   V(Code)                     \
   V(Map)                      \
diff --git a/src/objects.cc b/src/objects.cc
index dbbec58..8f03b10 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -98,6 +98,10 @@
     Isolate* isolate = HeapObject::cast(this)->GetIsolate();
     Context* native_context = isolate->context()->native_context();
     return CreateJSValue(native_context->string_function(), this);
+  } else if (IsSymbol()) {
+    Isolate* isolate = HeapObject::cast(this)->GetIsolate();
+    Context* native_context = isolate->context()->native_context();
+    return CreateJSValue(native_context->symbol_function(), this);
   }
 
   // Throw a type error.
@@ -126,10 +130,10 @@
       holder = native_context->number_function()->instance_prototype();
     } else if (IsString()) {
       holder = native_context->string_function()->instance_prototype();
+    } else if (IsSymbol()) {
+      holder = native_context->symbol_function()->instance_prototype();
     } else if (IsBoolean()) {
       holder = native_context->boolean_function()->instance_prototype();
-    } else if (IsSymbol()) {
-      holder = native_context->symbol_delegate();
     } else {
       Isolate::Current()->PushStackTraceAndDie(
           0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001);
@@ -375,6 +379,9 @@
   Handle<Object> receiver(receiver_raw, isolate);
   Handle<Object> name(name_raw, isolate);
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) return isolate->heap()->undefined_value();
+
   Handle<Object> args[] = { receiver, name };
   Handle<Object> result = CallTrap(
     "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
@@ -756,7 +763,7 @@
   // holder in the prototype chain.
   // Proxy handlers do not use the proxy's prototype, so we can skip this.
   if (!result->IsHandler()) {
-    Object* last = result->IsProperty() && !receiver->IsSymbol()
+    Object* last = result->IsProperty()
         ? result->holder()
         : Object::cast(heap->null_value());
     ASSERT(this != this->GetPrototype(isolate));
@@ -837,10 +844,10 @@
         holder = native_context->number_function()->instance_prototype();
       } else if (holder->IsString()) {
         holder = native_context->string_function()->instance_prototype();
+      } else if (holder->IsSymbol()) {
+        holder = native_context->symbol_function()->instance_prototype();
       } else if (holder->IsBoolean()) {
         holder = native_context->boolean_function()->instance_prototype();
-      } else if (holder->IsSymbol()) {
-        holder = native_context->symbol_delegate();
       } else if (holder->IsJSProxy()) {
         return JSProxy::cast(holder)->GetElementWithHandler(receiver, index);
       } else {
@@ -900,6 +907,9 @@
   if (heap_object->IsString()) {
     return context->string_function()->instance_prototype();
   }
+  if (heap_object->IsSymbol()) {
+    return context->symbol_function()->instance_prototype();
+  }
   if (heap_object->IsBoolean()) {
     return context->boolean_function()->instance_prototype();
   } else {
@@ -908,16 +918,6 @@
 }
 
 
-Object* Object::GetDelegate(Isolate* isolate) {
-  if (IsSymbol()) {
-    Heap* heap = Symbol::cast(this)->GetHeap();
-    Context* context = heap->isolate()->context()->native_context();
-    return context->symbol_delegate();
-  }
-  return GetPrototype(isolate);
-}
-
-
 MaybeObject* Object::GetHash(CreationFlag flag) {
   // The object is either a number, a name, an odd-ball,
   // a real JS object, or a Harmony proxy.
@@ -1467,9 +1467,16 @@
         accumulator->Add("<Odd Oddball>");
       break;
     }
-    case SYMBOL_TYPE:
-      accumulator->Add("<Symbol: %d>", Symbol::cast(this)->Hash());
+    case SYMBOL_TYPE: {
+      Symbol* symbol = Symbol::cast(this);
+      accumulator->Add("<Symbol: %d", symbol->Hash());
+      if (!symbol->name()->IsUndefined()) {
+        accumulator->Add(" ");
+        String::cast(symbol->name())->StringShortPrint(accumulator);
+      }
+      accumulator->Add(">");
       break;
+    }
     case HEAP_NUMBER_TYPE:
       accumulator->Add("<Number: ");
       HeapNumber::cast(this)->HeapNumberPrint(accumulator);
@@ -1543,6 +1550,7 @@
     case JS_VALUE_TYPE:
     case JS_DATE_TYPE:
     case JS_ARRAY_TYPE:
+    case JS_ARRAY_BUFFER_TYPE:
     case JS_SET_TYPE:
     case JS_MAP_TYPE:
     case JS_WEAK_MAP_TYPE:
@@ -1579,6 +1587,8 @@
       JSGlobalPropertyCell::BodyDescriptor::IterateBody(this, v);
       break;
     case SYMBOL_TYPE:
+      Symbol::BodyDescriptor::IterateBody(this, v);
+      break;
     case HEAP_NUMBER_TYPE:
     case FILLER_TYPE:
     case BYTE_ARRAY_TYPE:
@@ -1728,7 +1738,7 @@
   // hidden strings) and is not a real identifier.
   // Normalize the object if it will have too many fast properties.
   Isolate* isolate = GetHeap()->isolate();
-  if ((!IsIdentifier(isolate->unicode_cache(), name)
+  if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name)
        && name != isolate->heap()->hidden_string()) ||
       (map()->unused_property_fields() == 0 &&
        TooManyFastProperties(properties()->length(), store_mode))) {
@@ -2755,6 +2765,9 @@
   Handle<Object> receiver(this, isolate);
   Handle<Object> name(name_raw, isolate);
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) return false;
+
   Handle<Object> args[] = { name };
   Handle<Object> result = CallTrap(
     "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
@@ -2776,6 +2789,9 @@
   Handle<Object> name(name_raw, isolate);
   Handle<Object> value(value_raw, isolate);
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) return *value;
+
   Handle<Object> args[] = { receiver, name, value };
   CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
   if (isolate->has_pending_exception()) return Failure::Exception();
@@ -2798,6 +2814,12 @@
   Handle<Object> value(value_raw, isolate);
   Handle<Object> handler(this->handler(), isolate);  // Trap might morph proxy.
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) {
+    *done = false;
+    return isolate->heap()->the_hole_value();
+  }
+
   *done = true;  // except where redefined...
   Handle<Object> args[] = { name };
   Handle<Object> result = proxy->CallTrap(
@@ -2806,7 +2828,7 @@
 
   if (result->IsUndefined()) {
     *done = false;
-    return GetHeap()->the_hole_value();
+    return isolate->heap()->the_hole_value();
   }
 
   // Emulate [[GetProperty]] semantics for proxies.
@@ -2887,6 +2909,9 @@
   Handle<JSProxy> receiver(this);
   Handle<Object> name(name_raw, isolate);
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) return isolate->heap()->false_value();
+
   Handle<Object> args[] = { name };
   Handle<Object> result = CallTrap(
     "delete", Handle<Object>(), ARRAY_SIZE(args), args);
@@ -2927,6 +2952,9 @@
   Handle<JSReceiver> receiver(receiver_raw);
   Handle<Object> name(name_raw, isolate);
 
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (name->IsSymbol()) return ABSENT;
+
   Handle<Object> args[] = { name };
   Handle<Object> result = CallTrap(
     "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
@@ -4665,6 +4693,145 @@
 }
 
 
+MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
+  StackLimitCheck check(isolate);
+  if (check.HasOverflowed()) return isolate->StackOverflow();
+
+  Heap* heap = isolate->heap();
+  Object* result;
+  { MaybeObject* maybe_result = heap->CopyJSObject(this);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+  JSObject* copy = JSObject::cast(result);
+
+  // Deep copy local properties.
+  if (copy->HasFastProperties()) {
+    FixedArray* properties = copy->properties();
+    for (int i = 0; i < properties->length(); i++) {
+      Object* value = properties->get(i);
+      if (value->IsJSObject()) {
+        JSObject* js_object = JSObject::cast(value);
+        { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
+        properties->set(i, result);
+      }
+    }
+    int nof = copy->map()->inobject_properties();
+    for (int i = 0; i < nof; i++) {
+      Object* value = copy->InObjectPropertyAt(i);
+      if (value->IsJSObject()) {
+        JSObject* js_object = JSObject::cast(value);
+        { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
+        copy->InObjectPropertyAtPut(i, result);
+      }
+    }
+  } else {
+    { MaybeObject* maybe_result =
+          heap->AllocateFixedArray(copy->NumberOfLocalProperties());
+      if (!maybe_result->ToObject(&result)) return maybe_result;
+    }
+    FixedArray* names = FixedArray::cast(result);
+    copy->GetLocalPropertyNames(names, 0);
+    for (int i = 0; i < names->length(); i++) {
+      ASSERT(names->get(i)->IsString());
+      String* key_string = String::cast(names->get(i));
+      PropertyAttributes attributes =
+          copy->GetLocalPropertyAttribute(key_string);
+      // Only deep copy fields from the object literal expression.
+      // In particular, don't try to copy the length attribute of
+      // an array.
+      if (attributes != NONE) continue;
+      Object* value =
+          copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
+      if (value->IsJSObject()) {
+        JSObject* js_object = JSObject::cast(value);
+        { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
+        { MaybeObject* maybe_result =
+              // Creating object copy for literals. No strict mode needed.
+              copy->SetProperty(key_string, result, NONE, kNonStrictMode);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
+      }
+    }
+  }
+
+  // Deep copy local elements.
+  // Pixel elements cannot be created using an object literal.
+  ASSERT(!copy->HasExternalArrayElements());
+  switch (copy->GetElementsKind()) {
+    case FAST_SMI_ELEMENTS:
+    case FAST_ELEMENTS:
+    case FAST_HOLEY_SMI_ELEMENTS:
+    case FAST_HOLEY_ELEMENTS: {
+      FixedArray* elements = FixedArray::cast(copy->elements());
+      if (elements->map() == heap->fixed_cow_array_map()) {
+        isolate->counters()->cow_arrays_created_runtime()->Increment();
+#ifdef DEBUG
+        for (int i = 0; i < elements->length(); i++) {
+          ASSERT(!elements->get(i)->IsJSObject());
+        }
+#endif
+      } else {
+        for (int i = 0; i < elements->length(); i++) {
+          Object* value = elements->get(i);
+          ASSERT(value->IsSmi() ||
+                 value->IsTheHole() ||
+                 (IsFastObjectElementsKind(copy->GetElementsKind())));
+          if (value->IsJSObject()) {
+            JSObject* js_object = JSObject::cast(value);
+            { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+              if (!maybe_result->ToObject(&result)) return maybe_result;
+            }
+            elements->set(i, result);
+          }
+        }
+      }
+      break;
+    }
+    case DICTIONARY_ELEMENTS: {
+      SeededNumberDictionary* element_dictionary = copy->element_dictionary();
+      int capacity = element_dictionary->Capacity();
+      for (int i = 0; i < capacity; i++) {
+        Object* k = element_dictionary->KeyAt(i);
+        if (element_dictionary->IsKey(k)) {
+          Object* value = element_dictionary->ValueAt(i);
+          if (value->IsJSObject()) {
+            JSObject* js_object = JSObject::cast(value);
+            { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+              if (!maybe_result->ToObject(&result)) return maybe_result;
+            }
+            element_dictionary->ValueAtPut(i, result);
+          }
+        }
+      }
+      break;
+    }
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
+      break;
+    case EXTERNAL_PIXEL_ELEMENTS:
+    case EXTERNAL_BYTE_ELEMENTS:
+    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case EXTERNAL_SHORT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case EXTERNAL_INT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case EXTERNAL_FLOAT_ELEMENTS:
+    case EXTERNAL_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS:
+    case FAST_HOLEY_DOUBLE_ELEMENTS:
+      // No contained objects, nothing to do.
+      break;
+  }
+  return copy;
+}
+
+
 // Tests for the fast common case for property enumeration:
 // - This object and all prototypes has an enum cache (which means that
 //   it is no proxy, has no interceptors and needs no access checks).
@@ -7626,33 +7793,45 @@
 }
 
 
-String* SeqString::Truncate(int new_length) {
-  Heap* heap = GetHeap();
-  if (new_length <= 0) return heap->empty_string();
+Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
+  int new_size, old_size;
+  int old_length = string->length();
+  if (old_length <= new_length) return string;
 
-  int string_size, allocated_string_size;
-  int old_length = length();
-  if (old_length <= new_length) return this;
-
-  if (IsSeqOneByteString()) {
-    allocated_string_size = SeqOneByteString::SizeFor(old_length);
-    string_size = SeqOneByteString::SizeFor(new_length);
+  if (string->IsSeqOneByteString()) {
+    old_size = SeqOneByteString::SizeFor(old_length);
+    new_size = SeqOneByteString::SizeFor(new_length);
   } else {
-    allocated_string_size = SeqTwoByteString::SizeFor(old_length);
-    string_size = SeqTwoByteString::SizeFor(new_length);
+    ASSERT(string->IsSeqTwoByteString());
+    old_size = SeqTwoByteString::SizeFor(old_length);
+    new_size = SeqTwoByteString::SizeFor(new_length);
   }
 
-  int delta = allocated_string_size - string_size;
-  set_length(new_length);
+  int delta = old_size - new_size;
+  string->set_length(new_length);
 
-  // String sizes are pointer size aligned, so that we can use filler objects
-  // that are a multiple of pointer size.
-  Address end_of_string = address() + string_size;
-  heap->CreateFillerObjectAt(end_of_string, delta);
-  if (Marking::IsBlack(Marking::MarkBitFrom(this))) {
-    MemoryChunk::IncrementLiveBytesFromMutator(address(), -delta);
+  Address start_of_string = string->address();
+  ASSERT_OBJECT_ALIGNED(start_of_string);
+  ASSERT_OBJECT_ALIGNED(start_of_string + new_size);
+
+  Heap* heap = string->GetHeap();
+  NewSpace* newspace = heap->new_space();
+  if (newspace->Contains(start_of_string) &&
+      newspace->top() == start_of_string + old_size) {
+    // Last allocated object in new space.  Simply lower allocation top.
+    *(newspace->allocation_top_address()) = start_of_string + new_size;
+  } else {
+    // Sizes are pointer size aligned, so that we can use filler objects
+    // that are a multiple of pointer size.
+    heap->CreateFillerObjectAt(start_of_string + new_size, delta);
   }
-  return this;
+  if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) {
+    MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta);
+  }
+
+
+  if (new_length == 0) return heap->isolate()->factory()->empty_string();
+  return string;
 }
 
 
@@ -8813,12 +8992,13 @@
   ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT);
 
   // copy code
-  CopyBytes(instruction_start(), desc.buffer, desc.instr_size);
+  CopyBytes(instruction_start(), desc.buffer,
+            static_cast<size_t>(desc.instr_size));
 
   // copy reloc info
   CopyBytes(relocation_start(),
             desc.buffer + desc.buffer_size - desc.reloc_size,
-            desc.reloc_size);
+            static_cast<size_t>(desc.reloc_size));
 
   // unbox handles and relocate
   intptr_t delta = instruction_start() - desc.buffer;
@@ -9751,9 +9931,14 @@
 
 void Map::ZapTransitions() {
   TransitionArray* transition_array = transitions();
-  MemsetPointer(transition_array->data_start(),
-                GetHeap()->the_hole_value(),
-                transition_array->length());
+  // TODO(mstarzinger): Temporarily use a slower version instead of the faster
+  // MemsetPointer to investigate a crasher. Switch back to MemsetPointer.
+  Object** data = transition_array->data_start();
+  Object* the_hole = GetHeap()->the_hole_value();
+  int length = transition_array->length();
+  for (int i = 0; i < length; i++) {
+    data[i] = the_hole;
+  }
 }
 
 
@@ -11586,18 +11771,22 @@
 // Fill in the names of local properties into the supplied storage. The main
 // purpose of this function is to provide reflection information for the object
 // mirrors.
-void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
-  ASSERT(storage->length() >= (NumberOfLocalProperties() - index));
+void JSObject::GetLocalPropertyNames(
+    FixedArray* storage, int index, PropertyAttributes filter) {
+  ASSERT(storage->length() >= (NumberOfLocalProperties(filter) - index));
   if (HasFastProperties()) {
     int real_size = map()->NumberOfOwnDescriptors();
     DescriptorArray* descs = map()->instance_descriptors();
-    ASSERT(storage->length() >= index + real_size);
     for (int i = 0; i < real_size; i++) {
-      storage->set(index + i, descs->GetKey(i));
+      if ((descs->GetDetails(i).attributes() & filter) == 0 &&
+          ((filter & SYMBOLIC) == 0 || !descs->GetKey(i)->IsSymbol())) {
+        storage->set(index++, descs->GetKey(i));
+      }
     }
   } else {
     property_dictionary()->CopyKeysTo(storage,
                                       index,
+                                      filter,
                                       NameDictionary::UNSORTED);
   }
 }
@@ -12348,6 +12537,7 @@
 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo(
     FixedArray*,
     int,
+    PropertyAttributes,
     Dictionary<NameDictionaryShape, Name*>::SortMode);
 
 template int
@@ -13590,6 +13780,7 @@
 void Dictionary<Shape, Key>::CopyKeysTo(
     FixedArray* storage,
     int index,
+    PropertyAttributes filter,
     typename Dictionary<Shape, Key>::SortMode sort_mode) {
   ASSERT(storage->length() >= NumberOfElementsFilterAttributes(
       static_cast<PropertyAttributes>(NONE)));
@@ -13599,7 +13790,8 @@
     if (HashTable<Shape, Key>::IsKey(k)) {
       PropertyDetails details = DetailsAt(i);
       if (details.IsDeleted()) continue;
-      storage->set(index++, k);
+      PropertyAttributes attr = details.attributes();
+      if ((attr & filter) == 0) storage->set(index++, k);
     }
   }
   if (sort_mode == Dictionary<Shape, Key>::SORTED) {
diff --git a/src/objects.h b/src/objects.h
index 933a075..37be25f 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -56,6 +56,7 @@
 //       - JSReceiver  (suitable for property access)
 //         - JSObject
 //           - JSArray
+//           - JSArrayBuffer
 //           - JSSet
 //           - JSMap
 //           - JSWeakMap
@@ -399,6 +400,7 @@
   V(JS_BUILTINS_OBJECT_TYPE)                                                   \
   V(JS_GLOBAL_PROXY_TYPE)                                                      \
   V(JS_ARRAY_TYPE)                                                             \
+  V(JS_ARRAY_BUFFER_TYPE)                                                      \
   V(JS_PROXY_TYPE)                                                             \
   V(JS_WEAK_MAP_TYPE)                                                          \
   V(JS_REGEXP_TYPE)                                                            \
@@ -729,6 +731,7 @@
   JS_BUILTINS_OBJECT_TYPE,
   JS_GLOBAL_PROXY_TYPE,
   JS_ARRAY_TYPE,
+  JS_ARRAY_BUFFER_TYPE,
   JS_SET_TYPE,
   JS_MAP_TYPE,
   JS_WEAK_MAP_TYPE,
@@ -974,6 +977,7 @@
   V(Foreign)                                   \
   V(Boolean)                                   \
   V(JSArray)                                   \
+  V(JSArrayBuffer)                             \
   V(JSProxy)                                   \
   V(JSFunctionProxy)                           \
   V(JSSet)                                     \
@@ -1102,9 +1106,6 @@
   // Return the object's prototype (might be Heap::null_value()).
   Object* GetPrototype(Isolate* isolate);
 
-  // Return the prototype, or the method holder for a value-like object.
-  Object* GetDelegate(Isolate* isolate);
-
   // Returns the permanent hash code associated with this object depending on
   // the actual object type.  Might return a failure in case no hash was
   // created yet or GC was caused by creation.
@@ -2060,7 +2061,8 @@
   int NumberOfLocalProperties(PropertyAttributes filter = NONE);
   // Fill in details for properties into storage starting at the specified
   // index.
-  void GetLocalPropertyNames(FixedArray* storage, int index);
+  void GetLocalPropertyNames(
+      FixedArray* storage, int index, PropertyAttributes filter = NONE);
 
   // Returns the number of properties on this object filtering out properties
   // with the specified attributes (ignoring interceptors).
@@ -2216,6 +2218,8 @@
   static Handle<Object> PreventExtensions(Handle<JSObject> object);
   MUST_USE_RESULT MaybeObject* PreventExtensions();
 
+  // Copy object
+  MUST_USE_RESULT MaybeObject* DeepCopy(Isolate* isolate);
 
   // Dispatched behavior.
   void JSObjectShortPrint(StringStream* accumulator);
@@ -3258,7 +3262,10 @@
                   PropertyAttributes filter,
                   SortMode sort_mode);
   // Fill in details for properties into storage.
-  void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode);
+  void CopyKeysTo(FixedArray* storage,
+                  int index,
+                  PropertyAttributes filter,
+                  SortMode sort_mode);
 
   // Accessors for next enumeration index.
   void SetNextEnumerationIndex(int index) {
@@ -4347,6 +4354,11 @@
     NONEXISTENT
   };
 
+  enum StubHolder {
+    OWN_STUB,
+    PROTOTYPE_STUB
+  };
+
   enum {
     NUMBER_OF_KINDS = LAST_IC_KIND + 1
   };
@@ -4542,6 +4554,8 @@
   class ExtraICStateKeyedAccessStoreMode:
       public BitField<KeyedAccessStoreMode, 1, 4> {};  // NOLINT
 
+  class ExtraICStateStubHolder: public BitField<StubHolder, 0, 1> {};
+
   static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) {
     return ExtraICStateStrictMode::decode(extra_ic_state);
   }
@@ -4558,6 +4572,10 @@
         ExtraICStateStrictMode::encode(strict_mode);
   }
 
+  static inline ExtraICState ComputeExtraICState(StubHolder stub_holder) {
+    return ExtraICStateStubHolder::encode(stub_holder);
+  }
+
   // Flags operations.
   static inline Flags ComputeFlags(
       Kind kind,
@@ -5943,6 +5961,9 @@
   // Indicates that code for this function cannot be cached.
   DECL_BOOLEAN_ACCESSORS(dont_cache)
 
+  // Indicates that this function is a generator.
+  DECL_BOOLEAN_ACCESSORS(is_generator)
+
   // Indicates whether or not the code in the shared function support
   // deoptimization.
   inline bool has_deoptimization_support();
@@ -6169,6 +6190,7 @@
     kDontOptimize,
     kDontInline,
     kDontCache,
+    kIsGenerator,
     kCompilerHintsCount  // Pseudo entry
   };
 
@@ -7401,6 +7423,9 @@
 // ES6 symbols.
 class Symbol: public Name {
  public:
+  // [name]: the print name of a symbol, or undefined if none.
+  DECL_ACCESSORS(name, Object)
+
   // Casting.
   static inline Symbol* cast(Object* obj);
 
@@ -7409,7 +7434,11 @@
   DECLARE_VERIFIER(Symbol)
 
   // Layout description.
-  static const int kSize = Name::kSize;
+  static const int kNameOffset = Name::kSize;
+  static const int kSize = kNameOffset + kPointerSize;
+
+  typedef FixedBodyDescriptor<kNameOffset, kNameOffset + kPointerSize, kSize>
+          BodyDescriptor;
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
@@ -7754,8 +7783,8 @@
   // Truncate the string in-place if possible and return the result.
   // In case of new_length == 0, the empty string is returned without
   // truncating the original string.
-  MUST_USE_RESULT String* Truncate(int new_length);
-
+  MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
+                                                 int new_length);
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
 };
@@ -8464,6 +8493,30 @@
 };
 
 
+class JSArrayBuffer: public JSObject {
+ public:
+  // [backing_store]: backing memory for thsi array
+  DECL_ACCESSORS(backing_store, void)
+
+  // [byte_length]: length in bytes
+  DECL_ACCESSORS(byte_length, Object)
+
+  // Casting.
+  static inline JSArrayBuffer* cast(Object* obj);
+
+  // Dispatched behavior.
+  DECLARE_PRINTER(JSArrayBuffer)
+  DECLARE_VERIFIER(JSArrayBuffer)
+
+  static const int kBackingStoreOffset = JSObject::kHeaderSize;
+  static const int kByteLengthOffset = kBackingStoreOffset + kPointerSize;
+  static const int kSize = kByteLengthOffset + kPointerSize;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
+};
+
+
 // Foreign describes objects pointing from JavaScript to C structures.
 // Since they cannot contain references to JS HeapObjects they can be
 // placed in old_data_space.
diff --git a/src/parser.cc b/src/parser.cc
index cdc0adb..d1228d2 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -486,10 +486,12 @@
 
 Parser::FunctionState::FunctionState(Parser* parser,
                                      Scope* scope,
+                                     bool is_generator,
                                      Isolate* isolate)
     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
       next_handler_index_(0),
       expected_property_count_(0),
+      is_generator_(is_generator),
       only_simple_this_property_assignments_(false),
       this_property_assignments_(isolate->factory()->empty_fixed_array()),
       parser_(parser),
@@ -642,7 +644,10 @@
     }
     ParsingModeScope parsing_mode(this, mode);
 
-    FunctionState function_state(this, scope, isolate());  // Enters 'scope'.
+    bool is_generator = false;
+    // Enters 'scope'.
+    FunctionState function_state(this, scope, is_generator, isolate());
+
     top_scope_->SetLanguageMode(info->language_mode());
     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
     bool ok = true;
@@ -680,7 +685,8 @@
           FunctionLiteral::kNoDuplicateParameters,
           FunctionLiteral::ANONYMOUS_EXPRESSION,
           FunctionLiteral::kGlobalOrEval,
-          FunctionLiteral::kNotParenthesized);
+          FunctionLiteral::kNotParenthesized,
+          FunctionLiteral::kNotGenerator);
       result->set_ast_properties(factory()->visitor()->ast_properties());
     } else if (stack_overflow_) {
       isolate()->StackOverflow();
@@ -754,7 +760,8 @@
       scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
                                            zone());
     }
-    FunctionState function_state(this, scope, isolate());
+    bool is_generator = false;  // Top scope is not a generator.
+    FunctionState function_state(this, scope, is_generator, isolate());
     ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
     ASSERT(scope->language_mode() != EXTENDED_MODE ||
            info()->is_extended_mode());
@@ -768,6 +775,7 @@
     bool ok = true;
     result = ParseFunctionLiteral(name,
                                   false,  // Strict mode name already checked.
+                                  shared_info->is_generator(),
                                   RelocInfo::kNoPosition,
                                   type,
                                   &ok);
@@ -1132,6 +1140,7 @@
   //    ModuleDeclaration
   //    ImportDeclaration
   //    ExportDeclaration
+  //    GeneratorDeclaration
 
   switch (peek()) {
     case Token::FUNCTION:
@@ -1430,6 +1439,7 @@
   //    'export' Identifier (',' Identifier)* ';'
   //    'export' VariableDeclaration
   //    'export' FunctionDeclaration
+  //    'export' GeneratorDeclaration
   //    'export' ModuleDeclaration
   //
   // TODO(ES6): implement structuring ExportSpecifiers
@@ -1509,6 +1519,7 @@
   // BlockElement (aka SourceElement):
   //    LetDeclaration
   //    ConstDeclaration
+  //    GeneratorDeclaration
 
   switch (peek()) {
     case Token::FUNCTION:
@@ -1628,6 +1639,10 @@
       //    FunctionDeclaration
       // Common language extension is to allow function declaration in place
       // of any statement. This language extension is disabled in strict mode.
+      //
+      // In Harmony mode, this case also handles the extension:
+      // Statement:
+      //    GeneratorDeclaration
       if (!top_scope_->is_classic_mode()) {
         ReportMessageAt(scanner().peek_location(), "strict_function",
                         Vector<const char*>::empty());
@@ -1890,13 +1905,18 @@
 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
   // FunctionDeclaration ::
   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
+  // GeneratorDeclaration ::
+  //   'function' '*' Identifier '(' FormalParameterListopt ')'
+  //      '{' FunctionBody '}'
   Expect(Token::FUNCTION, CHECK_OK);
   int function_token_position = scanner().location().beg_pos;
+  bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
   bool is_strict_reserved = false;
   Handle<String> name = ParseIdentifierOrStrictReservedWord(
       &is_strict_reserved, CHECK_OK);
   FunctionLiteral* fun = ParseFunctionLiteral(name,
                                               is_strict_reserved,
+                                              is_generator,
                                               function_token_position,
                                               FunctionLiteral::DECLARATION,
                                               CHECK_OK);
@@ -3004,8 +3024,13 @@
 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
   // AssignmentExpression ::
   //   ConditionalExpression
+  //   YieldExpression
   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
 
+  if (peek() == Token::YIELD && is_generator()) {
+    return ParseYieldExpression(ok);
+  }
+
   if (fni_ != NULL) fni_->Enter();
   Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
 
@@ -3074,6 +3099,17 @@
 }
 
 
+Expression* Parser::ParseYieldExpression(bool* ok) {
+  // YieldExpression ::
+  //   'yield' '*'? AssignmentExpression
+  int position = scanner().peek_location().beg_pos;
+  Expect(Token::YIELD, CHECK_OK);
+  bool is_yield_star = Check(Token::MUL);
+  Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
+  return factory()->NewYield(expression, is_yield_star, position);
+}
+
+
 // Precedence = 3
 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
   // ConditionalExpression ::
@@ -3450,6 +3486,7 @@
   if (peek() == Token::FUNCTION) {
     Expect(Token::FUNCTION, CHECK_OK);
     int function_token_position = scanner().location().beg_pos;
+    bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
     Handle<String> name;
     bool is_strict_reserved_name = false;
     if (peek_any_identifier()) {
@@ -3461,6 +3498,7 @@
         : FunctionLiteral::NAMED_EXPRESSION;
     result = ParseFunctionLiteral(name,
                                   is_strict_reserved_name,
+                                  is_generator,
                                   function_token_position,
                                   type,
                                   CHECK_OK);
@@ -3544,6 +3582,7 @@
     case Token::FUTURE_RESERVED_WORD:
       return ReportMessage("unexpected_reserved",
                            Vector<const char*>::empty());
+    case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD:
       return ReportMessage(top_scope_->is_classic_mode() ?
                                "unexpected_token_identifier" :
@@ -3604,6 +3643,7 @@
       break;
 
     case Token::IDENTIFIER:
+    case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD: {
       Handle<String> name = ParseIdentifier(CHECK_OK);
       if (fni_ != NULL) fni_->PushVariableName(name);
@@ -4009,6 +4049,7 @@
     FunctionLiteral* value =
         ParseFunctionLiteral(name,
                              false,   // reserved words are allowed here
+                             false,   // not a generator
                              RelocInfo::kNoPosition,
                              FunctionLiteral::ANONYMOUS_EXPRESSION,
                              CHECK_OK);
@@ -4310,6 +4351,7 @@
 
 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
                                               bool name_is_strict_reserved,
+                                              bool is_generator,
                                               int function_token_position,
                                               FunctionLiteral::Type type,
                                               bool* ok) {
@@ -4344,9 +4386,12 @@
   FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
       ? FunctionLiteral::kIsParenthesized
       : FunctionLiteral::kNotParenthesized;
+  FunctionLiteral::IsGeneratorFlag generator = is_generator
+      ? FunctionLiteral::kIsGenerator
+      : FunctionLiteral::kNotGenerator;
   AstProperties ast_properties;
   // Parse function body.
-  { FunctionState function_state(this, scope, isolate());
+  { FunctionState function_state(this, scope, is_generator, isolate());
     top_scope_->SetScopeName(function_name);
 
     //  FormalParameterList ::
@@ -4584,7 +4629,8 @@
                                     duplicate_parameters,
                                     type,
                                     FunctionLiteral::kIsFunction,
-                                    parenthesized);
+                                    parenthesized,
+                                    generator);
   function_literal->set_function_token_position(function_token_position);
   function_literal->set_ast_properties(&ast_properties);
 
@@ -4606,10 +4652,12 @@
                                                    stack_limit,
                                                    do_allow_lazy,
                                                    allow_natives_syntax_,
-                                                   allow_modules_);
+                                                   allow_modules_,
+                                                   FLAG_harmony_generators);
   }
   preparser::PreParser::PreParseResult result =
       reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
+                                                is_generator(),
                                                 logger);
   return result;
 }
@@ -4672,7 +4720,8 @@
   Token::Value next = peek();
   return next == Token::IDENTIFIER ||
          next == Token::FUTURE_RESERVED_WORD ||
-         next == Token::FUTURE_STRICT_RESERVED_WORD;
+         next == Token::FUTURE_STRICT_RESERVED_WORD ||
+         next == Token::YIELD;
 }
 
 
@@ -4744,13 +4793,17 @@
 // Parses an identifier that is valid for the current scope, in particular it
 // fails on strict mode future reserved keywords in a strict scope.
 Handle<String> Parser::ParseIdentifier(bool* ok) {
-  if (!top_scope_->is_classic_mode()) {
-    Expect(Token::IDENTIFIER, ok);
-  } else if (!Check(Token::IDENTIFIER)) {
-    Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+  Token::Value next = Next();
+  if (next == Token::IDENTIFIER ||
+      (top_scope_->is_classic_mode() &&
+       (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+        (next == Token::YIELD && !is_generator())))) {
+    return GetSymbol(ok);
+  } else {
+    ReportUnexpectedToken(next);
+    *ok = false;
+    return Handle<String>();
   }
-  if (!*ok) return Handle<String>();
-  return GetSymbol(ok);
 }
 
 
@@ -4758,12 +4811,17 @@
 // whether it is strict mode future reserved.
 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
     bool* is_strict_reserved, bool* ok) {
-  *is_strict_reserved = false;
-  if (!Check(Token::IDENTIFIER)) {
-    Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+  Token::Value next = Next();
+  if (next == Token::IDENTIFIER) {
+    *is_strict_reserved = false;
+  } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+             (next == Token::YIELD && !is_generator())) {
     *is_strict_reserved = true;
+  } else {
+    ReportUnexpectedToken(next);
+    *ok = false;
+    return Handle<String>();
   }
-  if (!*ok) return Handle<String>();
   return GetSymbol(ok);
 }
 
@@ -5875,6 +5933,9 @@
   if (FLAG_lazy && (extension == NULL)) {
     flags |= kAllowLazy;
   }
+  if (FLAG_harmony_generators) {
+    flags |= kAllowGenerators;
+  }
   CompleteParserRecorder recorder;
   return DoPreParse(source, flags, &recorder);
 }
diff --git a/src/parser.h b/src/parser.h
index 6dcf7f1..fc4aba2 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -474,6 +474,7 @@
    public:
     FunctionState(Parser* parser,
                   Scope* scope,
+                  bool is_generator,
                   Isolate* isolate);
     ~FunctionState();
 
@@ -504,6 +505,8 @@
     void AddProperty() { expected_property_count_++; }
     int expected_property_count() { return expected_property_count_; }
 
+    bool is_generator() const { return is_generator_; }
+
     AstNodeFactory<AstConstructionVisitor>* factory() { return &factory_; }
 
    private:
@@ -518,6 +521,9 @@
     // Properties count estimation.
     int expected_property_count_;
 
+    // Indicates that this function is a generator.
+    bool is_generator_;
+
     // Keeps track of assignments to properties of this. Used for
     // optimizing constructors.
     bool only_simple_this_property_assignments_;
@@ -631,6 +637,7 @@
 
   Expression* ParseExpression(bool accept_IN, bool* ok);
   Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
+  Expression* ParseYieldExpression(bool* ok);
   Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
   Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
   Expression* ParseUnaryExpression(bool* ok);
@@ -674,6 +681,7 @@
   ZoneList<Expression*>* ParseArguments(bool* ok);
   FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
                                         bool name_is_reserved,
+                                        bool is_generator,
                                         int function_token_position,
                                         FunctionLiteral::Type type,
                                         bool* ok);
@@ -703,6 +711,8 @@
     return scanner().Next();
   }
 
+  bool is_generator() const { return current_function_state_->is_generator(); }
+
   bool peek_any_identifier();
 
   INLINE(void Consume(Token::Value token));
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 8914d63..67c389e 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -687,13 +687,14 @@
     CONTEXT context;
     memset(&context, 0, sizeof(context));
 
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
     if (SuspendThread(profiled_thread) == kSuspendFailed) return;
-    sample->state = sampler->isolate()->current_vm_state();
+    sample->state = isolate->current_vm_state();
 
     context.ContextFlags = CONTEXT_FULL;
     if (GetThreadContext(profiled_thread, &context) != 0) {
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 986c5af..14f7171 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -715,7 +715,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 0359b2d..1f9cde1 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -111,8 +111,10 @@
   FILE* f = NULL;
   const char* what = search_string;
 
-  if (NULL == (f = fopen(file_name, "r")))
+  if (NULL == (f = fopen(file_name, "r"))) {
+    OS::PrintError("Failed to open /proc/cpuinfo\n");
     return false;
+  }
 
   int k;
   while (EOF != (k = fgetc(f))) {
@@ -1088,7 +1090,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index fde5217..30e2b89 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -818,8 +818,9 @@
 
   void SampleContext(Sampler* sampler) {
     thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
@@ -850,7 +851,7 @@
                          flavor,
                          reinterpret_cast<natural_t*>(&state),
                          &count) == KERN_SUCCESS) {
-      sample->state = sampler->isolate()->current_vm_state();
+      sample->state = isolate->current_vm_state();
       sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
       sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
       sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 66eac22..e48d4cb 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -748,7 +748,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index 85ba95f..0e616d1 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -682,7 +682,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 66dbade..c1bae93 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -2064,13 +2064,14 @@
     CONTEXT context;
     memset(&context, 0, sizeof(context));
 
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
     if (SuspendThread(profiled_thread) == kSuspendFailed) return;
-    sample->state = sampler->isolate()->current_vm_state();
+    sample->state = isolate->current_vm_state();
 
     context.ContextFlags = CONTEXT_FULL;
     if (GetThreadContext(profiled_thread, &context) != 0) {
diff --git a/src/preparser.cc b/src/preparser.cc
index c461d8a..c61a08d 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -53,12 +53,13 @@
 namespace preparser {
 
 PreParser::PreParseResult PreParser::PreParseLazyFunction(
-    i::LanguageMode mode, i::ParserRecorder* log) {
+    i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) {
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
   Scope top_scope(&scope_, kTopLevelScope);
   set_language_mode(mode);
   Scope function_scope(&scope_, kFunctionScope);
+  function_scope.set_is_generator(is_generator);
   ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
   bool ok = true;
   int start_position = scanner_->peek_location().beg_pos;
@@ -154,6 +155,7 @@
   // SourceElement:
   //    LetDeclaration
   //    ConstDeclaration
+  //    GeneratorDeclaration
 
   switch (peek()) {
     case i::Token::FUNCTION:
@@ -294,19 +296,23 @@
 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
   // FunctionDeclaration ::
   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
+  // GeneratorDeclaration ::
+  //   'function' '*' Identifier '(' FormalParameterListopt ')'
+  //      '{' FunctionBody '}'
   Expect(i::Token::FUNCTION, CHECK_OK);
 
+  bool is_generator = allow_generators_ && Check(i::Token::MUL);
   Identifier identifier = ParseIdentifier(CHECK_OK);
   i::Scanner::Location location = scanner_->location();
 
-  Expression function_value = ParseFunctionLiteral(CHECK_OK);
+  Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
 
   if (function_value.IsStrictFunction() &&
       !identifier.IsValidStrictVariable()) {
     // Strict mode violation, using either reserved word or eval/arguments
     // as name of strict function.
     const char* type = "strict_function_name";
-    if (identifier.IsFutureStrictReserved()) {
+    if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
       type = "strict_reserved_word";
     }
     ReportMessageAt(location, type, NULL);
@@ -475,7 +481,9 @@
   Expression expr = ParseExpression(true, CHECK_OK);
   if (expr.IsRawIdentifier()) {
     ASSERT(!expr.AsIdentifier().IsFutureReserved());
-    ASSERT(is_classic_mode() || !expr.AsIdentifier().IsFutureStrictReserved());
+    ASSERT(is_classic_mode() ||
+           (!expr.AsIdentifier().IsFutureStrictReserved() &&
+            !expr.AsIdentifier().IsYield()));
     if (peek() == i::Token::COLON) {
       Consume(i::Token::COLON);
       return ParseStatement(ok);
@@ -810,8 +818,13 @@
                                                            bool* ok) {
   // AssignmentExpression ::
   //   ConditionalExpression
+  //   YieldExpression
   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
 
+  if (scope_->is_generator() && peek() == i::Token::YIELD) {
+    return ParseYieldExpression(ok);
+  }
+
   i::Scanner::Location before = scanner_->peek_location();
   Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
 
@@ -842,6 +855,19 @@
 
 
 // Precedence = 3
+PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
+  // YieldExpression ::
+  //   'yield' '*'? AssignmentExpression
+  Consume(i::Token::YIELD);
+  Check(i::Token::MUL);
+
+  ParseAssignmentExpression(false, CHECK_OK);
+
+  return Expression::Default();
+}
+
+
+// Precedence = 3
 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
                                                             bool* ok) {
   // ConditionalExpression ::
@@ -1034,11 +1060,13 @@
   Expression result = Expression::Default();
   if (peek() == i::Token::FUNCTION) {
     Consume(i::Token::FUNCTION);
+
+    bool is_generator = allow_generators_ && Check(i::Token::MUL);
     Identifier identifier = Identifier::Default();
     if (peek_any_identifier()) {
       identifier = ParseIdentifier(CHECK_OK);
     }
-    result = ParseFunctionLiteral(CHECK_OK);
+    result = ParseFunctionLiteral(is_generator, CHECK_OK);
     if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
       StrictModeIdentifierViolation(scanner_->location(),
                                     "strict_function_name",
@@ -1112,6 +1140,7 @@
 
     case i::Token::FUTURE_RESERVED_WORD:
     case i::Token::FUTURE_STRICT_RESERVED_WORD:
+    case i::Token::YIELD:
     case i::Token::IDENTIFIER: {
       Identifier id = ParseIdentifier(CHECK_OK);
       result = Expression::FromIdentifier(id);
@@ -1257,7 +1286,7 @@
             }
             PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
             CheckDuplicate(&duplicate_finder, name, type, CHECK_OK);
-            ParseFunctionLiteral(CHECK_OK);
+            ParseFunctionLiteral(false, CHECK_OK);
             if (peek() != i::Token::RBRACE) {
               Expect(i::Token::COMMA, CHECK_OK);
             }
@@ -1344,7 +1373,8 @@
 }
 
 
-PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
+PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
+                                                      bool* ok) {
   // Function ::
   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
 
@@ -1352,6 +1382,7 @@
   ScopeType outer_scope_type = scope_->type();
   bool inside_with = scope_->IsInsideWith();
   Scope function_scope(&scope_, kFunctionScope);
+  function_scope.set_is_generator(is_generator);
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
   Expect(i::Token::LPAREN, CHECK_OK);
@@ -1497,6 +1528,8 @@
   } else if (scanner_->current_token() ==
              i::Token::FUTURE_STRICT_RESERVED_WORD) {
     return Identifier::FutureStrictReserved();
+  } else if (scanner_->current_token() == i::Token::YIELD) {
+    return Identifier::Yield();
   }
   if (scanner_->is_literal_ascii()) {
     // Detect strict-mode poison words.
@@ -1523,6 +1556,14 @@
       *ok = false;
       return GetIdentifierSymbol();
     }
+    case i::Token::YIELD:
+      if (scope_->is_generator()) {
+        // 'yield' in a generator is only valid as part of a YieldExpression.
+        ReportMessageAt(scanner_->location(), "unexpected_token", "yield");
+        *ok = false;
+        return Identifier::Yield();
+      }
+      // FALLTHROUGH
     case i::Token::FUTURE_STRICT_RESERVED_WORD:
       if (!is_classic_mode()) {
         i::Scanner::Location location = scanner_->location();
@@ -1580,7 +1621,7 @@
   const char* type = eval_args_type;
   if (identifier.IsFutureReserved()) {
     type = "reserved_word";
-  } else if (identifier.IsFutureStrictReserved()) {
+  } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
     type = "strict_reserved_word";
   }
   if (!is_classic_mode()) {
@@ -1634,7 +1675,8 @@
   i::Token::Value next = peek();
   return next == i::Token::IDENTIFIER ||
          next == i::Token::FUTURE_RESERVED_WORD ||
-         next == i::Token::FUTURE_STRICT_RESERVED_WORD;
+         next == i::Token::FUTURE_STRICT_RESERVED_WORD ||
+         next == i::Token::YIELD;
 }
 
 
diff --git a/src/preparser.h b/src/preparser.h
index ad52d74..ce9aa75 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -104,6 +104,11 @@
 };
 
 
+#ifdef WIN32
+#undef Yield
+#endif
+
+
 class PreParser {
  public:
   enum PreParseResult {
@@ -117,7 +122,8 @@
             uintptr_t stack_limit,
             bool allow_lazy,
             bool allow_natives_syntax,
-            bool allow_modules)
+            bool allow_modules,
+            bool allow_generators)
       : scanner_(scanner),
         log_(log),
         scope_(NULL),
@@ -128,6 +134,7 @@
         allow_lazy_(allow_lazy),
         allow_modules_(allow_modules),
         allow_natives_syntax_(allow_natives_syntax),
+        allow_generators_(allow_generators),
         parenthesized_function_(false),
         harmony_scoping_(scanner->HarmonyScoping()) { }
 
@@ -144,19 +151,22 @@
     bool allow_lazy = (flags & i::kAllowLazy) != 0;
     bool allow_natives_syntax = (flags & i::kAllowNativesSyntax) != 0;
     bool allow_modules = (flags & i::kAllowModules) != 0;
+    bool allow_generators = (flags & i::kAllowGenerators) != 0;
     return PreParser(scanner, log, stack_limit, allow_lazy,
-                     allow_natives_syntax, allow_modules).PreParse();
+                     allow_natives_syntax, allow_modules,
+                     allow_generators).PreParse();
   }
 
   // Parses a single function literal, from the opening parentheses before
   // parameters to the closing brace after the body.
   // Returns a FunctionEntry describing the body of the function in enough
   // detail that it can be lazily compiled.
-  // The scanner is expected to have matched the "function" keyword and
-  // parameters, and have consumed the initial '{'.
+  // The scanner is expected to have matched the "function" or "function*"
+  // keyword and parameters, and have consumed the initial '{'.
   // At return, unless an error occurred, the scanner is positioned before the
   // the final '}'.
   PreParseResult PreParseLazyFunction(i::LanguageMode mode,
+                                      bool is_generator,
                                       i::ParserRecorder* log);
 
  private:
@@ -240,9 +250,13 @@
     static Identifier FutureStrictReserved()  {
       return Identifier(kFutureStrictReservedIdentifier);
     }
+    static Identifier Yield()  {
+      return Identifier(kYieldIdentifier);
+    }
     bool IsEval() { return type_ == kEvalIdentifier; }
     bool IsArguments() { return type_ == kArgumentsIdentifier; }
     bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
+    bool IsYield() { return type_ == kYieldIdentifier; }
     bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
     bool IsFutureStrictReserved() {
       return type_ == kFutureStrictReservedIdentifier;
@@ -254,6 +268,7 @@
       kUnknownIdentifier,
       kFutureReservedIdentifier,
       kFutureStrictReservedIdentifier,
+      kYieldIdentifier,
       kEvalIdentifier,
       kArgumentsIdentifier
     };
@@ -347,7 +362,7 @@
         // Identifiers and string literals can be parenthesized.
         // They no longer work as labels or directive prologues,
         // but are still recognized in other contexts.
-        return Expression(code_ | kParentesizedExpressionFlag);
+        return Expression(code_ | kParenthesizedExpressionFlag);
       }
       // For other types of expressions, it's not important to remember
       // the parentheses.
@@ -373,7 +388,8 @@
       kUseStrictString = kStringLiteralFlag | 8,
       kStringLiteralMask = kUseStrictString,
 
-      kParentesizedExpressionFlag = 4,  // Only if identifier or string literal.
+      // Only if identifier or string literal.
+      kParenthesizedExpressionFlag = 4,
 
       // Below here applies if neither identifier nor string literal.
       kThisExpression = 4,
@@ -451,7 +467,8 @@
           expected_properties_(0),
           with_nesting_count_(0),
           language_mode_(
-              (prev_ != NULL) ? prev_->language_mode() : i::CLASSIC_MODE) {
+              (prev_ != NULL) ? prev_->language_mode() : i::CLASSIC_MODE),
+          is_generator_(false) {
       *variable = this;
     }
     ~Scope() { *variable_ = prev_; }
@@ -461,6 +478,8 @@
     int expected_properties() { return expected_properties_; }
     int materialized_literal_count() { return materialized_literal_count_; }
     bool IsInsideWith() { return with_nesting_count_ != 0; }
+    bool is_generator() { return is_generator_; }
+    void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
     bool is_classic_mode() {
       return language_mode_ == i::CLASSIC_MODE;
     }
@@ -492,6 +511,7 @@
     int expected_properties_;
     int with_nesting_count_;
     i::LanguageMode language_mode_;
+    bool is_generator_;
   };
 
   // Preparse the program. Only called in PreParseProgram after creating
@@ -557,6 +577,7 @@
 
   Expression ParseExpression(bool accept_IN, bool* ok);
   Expression ParseAssignmentExpression(bool accept_IN, bool* ok);
+  Expression ParseYieldExpression(bool* ok);
   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
   Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
   Expression ParseUnaryExpression(bool* ok);
@@ -572,7 +593,7 @@
   Expression ParseV8Intrinsic(bool* ok);
 
   Arguments ParseArguments(bool* ok);
-  Expression ParseFunctionLiteral(bool* ok);
+  Expression ParseFunctionLiteral(bool is_generator, bool* ok);
   void ParseLazyFunctionLiteralBody(bool* ok);
 
   Identifier ParseIdentifier(bool* ok);
@@ -664,6 +685,7 @@
   bool allow_lazy_;
   bool allow_modules_;
   bool allow_natives_syntax_;
+  bool allow_generators_;
   bool parenthesized_function_;
   bool harmony_scoping_;
 };
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index df6183a..50a71ce 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -353,6 +353,12 @@
 }
 
 
+void PrettyPrinter::VisitYield(Yield* node) {
+  Print("yield ");
+  Visit(node->expression());
+}
+
+
 void PrettyPrinter::VisitThrow(Throw* node) {
   Print("throw ");
   Visit(node->exception());
@@ -1059,6 +1065,11 @@
 }
 
 
+void AstPrinter::VisitYield(Yield* node) {
+  PrintIndentedVisit("YIELD", node->expression());
+}
+
+
 void AstPrinter::VisitThrow(Throw* node) {
   PrintIndentedVisit("THROW", node->exception());
 }
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 6e7f499..4e6302c 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -74,7 +74,8 @@
       entry_(entry),
       total_ticks_(0),
       self_ticks_(0),
-      children_(CodeEntriesMatch) {
+      children_(CodeEntriesMatch),
+      id_(tree->next_node_id()) {
 }
 
 
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 2bf1724..ce07213 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -296,6 +296,7 @@
                   "",
                   0,
                   TokenEnumerator::kNoSecurityToken),
+      next_node_id_(1),
       root_(new ProfileNode(this, &root_entry_)) {
 }
 
@@ -306,7 +307,7 @@
 }
 
 
-void ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
+ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start() + path.length() - 1;
        entry != path.start() - 1;
@@ -316,6 +317,7 @@
     }
   }
   node->IncrementSelfTicks();
+  return node;
 }
 
 
@@ -467,7 +469,8 @@
 
 
 void CpuProfile::AddPath(const Vector<CodeEntry*>& path) {
-  top_down_.AddPathFromEnd(path);
+  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path);
+  if (record_samples_) samples_.Add(top_frame_node);
 }
 
 
@@ -483,7 +486,7 @@
 
 CpuProfile* CpuProfile::FilteredClone(int security_token_id) {
   ASSERT(security_token_id != TokenEnumerator::kNoSecurityToken);
-  CpuProfile* clone = new CpuProfile(title_, uid_);
+  CpuProfile* clone = new CpuProfile(title_, uid_, false);
   clone->top_down_.FilteredClone(&top_down_, security_token_id);
   return clone;
 }
@@ -609,7 +612,8 @@
 }
 
 
-bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid) {
+bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid,
+                                           bool record_samples) {
   ASSERT(uid > 0);
   current_profiles_semaphore_->Wait();
   if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
@@ -623,17 +627,12 @@
       return false;
     }
   }
-  current_profiles_.Add(new CpuProfile(title, uid));
+  current_profiles_.Add(new CpuProfile(title, uid, record_samples));
   current_profiles_semaphore_->Signal();
   return true;
 }
 
 
-bool CpuProfilesCollection::StartProfiling(String* title, unsigned uid) {
-  return StartProfiling(GetName(title), uid);
-}
-
-
 CpuProfile* CpuProfilesCollection::StopProfiling(int security_token_id,
                                                  const char* title,
                                                  double actual_sampling_rate) {
diff --git a/src/profile-generator.h b/src/profile-generator.h
index b128dad..4ddb753 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -150,6 +150,7 @@
   INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }
   double GetSelfMillis() const;
   double GetTotalMillis() const;
+  unsigned id() const { return id_; }
 
   void Print(int indent);
 
@@ -170,6 +171,7 @@
   // Mapping from CodeEntry* to ProfileNode*
   HashMap children_;
   List<ProfileNode*> children_list_;
+  unsigned id_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileNode);
 };
@@ -180,7 +182,7 @@
   ProfileTree();
   ~ProfileTree();
 
-  void AddPathFromEnd(const Vector<CodeEntry*>& path);
+  ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
   void AddPathFromStart(const Vector<CodeEntry*>& path);
   void CalculateTotalTicks();
   void FilteredClone(ProfileTree* src, int security_token_id);
@@ -191,6 +193,8 @@
   ProfileNode* root() const { return root_; }
   void SetTickRatePerMs(double ticks_per_ms);
 
+  unsigned next_node_id() { return next_node_id_++; }
+
   void ShortPrint();
   void Print() {
     root_->Print(0);
@@ -201,6 +205,7 @@
   void TraverseDepthFirst(Callback* callback);
 
   CodeEntry root_entry_;
+  unsigned next_node_id_;
   ProfileNode* root_;
   double ms_to_ticks_scale_;
 
@@ -210,8 +215,8 @@
 
 class CpuProfile {
  public:
-  CpuProfile(const char* title, unsigned uid)
-      : title_(title), uid_(uid) { }
+  CpuProfile(const char* title, unsigned uid, bool record_samples)
+      : title_(title), uid_(uid), record_samples_(record_samples) { }
 
   // Add pc -> ... -> main() call path to the profile.
   void AddPath(const Vector<CodeEntry*>& path);
@@ -223,6 +228,9 @@
   INLINE(unsigned uid() const) { return uid_; }
   INLINE(const ProfileTree* top_down() const) { return &top_down_; }
 
+  INLINE(int samples_count() const) { return samples_.length(); }
+  INLINE(ProfileNode* sample(int index) const) { return samples_.at(index); }
+
   void UpdateTicksScale();
 
   void ShortPrint();
@@ -231,6 +239,8 @@
  private:
   const char* title_;
   unsigned uid_;
+  bool record_samples_;
+  List<ProfileNode*> samples_;
   ProfileTree top_down_;
 
   DISALLOW_COPY_AND_ASSIGN(CpuProfile);
@@ -288,8 +298,7 @@
   CpuProfilesCollection();
   ~CpuProfilesCollection();
 
-  bool StartProfiling(const char* title, unsigned uid);
-  bool StartProfiling(String* title, unsigned uid);
+  bool StartProfiling(const char* title, unsigned uid, bool record_samples);
   CpuProfile* StopProfiling(int security_token_id,
                             const char* title,
                             double actual_sampling_rate);
diff --git a/src/property.h b/src/property.h
index 546967a..bbba8ae 100644
--- a/src/property.h
+++ b/src/property.h
@@ -362,12 +362,16 @@
     return NULL;
   }
 
-  Map* GetTransitionTarget() {
+  Map* GetTransitionTarget(Map* map) {
     ASSERT(IsTransition());
-    TransitionArray* transitions = holder()->map()->transitions();
+    TransitionArray* transitions = map->transitions();
     return transitions->GetTarget(number_);
   }
 
+  Map* GetTransitionTarget() {
+    return GetTransitionTarget(holder()->map());
+  }
+
   PropertyDetails GetTransitionDetails(Map* map) {
     ASSERT(IsTransition());
     TransitionArray* transitions = map->transitions();
diff --git a/src/runtime.cc b/src/runtime.cc
index 58f2a51..78efc8d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -26,6 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdlib.h>
+#include <limits>
 
 #include "v8.h"
 
@@ -138,148 +139,6 @@
       static_cast<LanguageMode>(args.smi_at(index));
 
 
-MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
-                                                   JSObject* boilerplate) {
-  StackLimitCheck check(isolate);
-  if (check.HasOverflowed()) return isolate->StackOverflow();
-
-  Heap* heap = isolate->heap();
-  Object* result;
-  { MaybeObject* maybe_result = heap->CopyJSObject(boilerplate);
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  JSObject* copy = JSObject::cast(result);
-
-  // Deep copy local properties.
-  if (copy->HasFastProperties()) {
-    FixedArray* properties = copy->properties();
-    for (int i = 0; i < properties->length(); i++) {
-      Object* value = properties->get(i);
-      if (value->IsJSObject()) {
-        JSObject* js_object = JSObject::cast(value);
-        { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
-          if (!maybe_result->ToObject(&result)) return maybe_result;
-        }
-        properties->set(i, result);
-      }
-    }
-    int nof = copy->map()->inobject_properties();
-    for (int i = 0; i < nof; i++) {
-      Object* value = copy->InObjectPropertyAt(i);
-      if (value->IsJSObject()) {
-        JSObject* js_object = JSObject::cast(value);
-        { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
-          if (!maybe_result->ToObject(&result)) return maybe_result;
-        }
-        copy->InObjectPropertyAtPut(i, result);
-      }
-    }
-  } else {
-    { MaybeObject* maybe_result =
-          heap->AllocateFixedArray(copy->NumberOfLocalProperties());
-      if (!maybe_result->ToObject(&result)) return maybe_result;
-    }
-    FixedArray* names = FixedArray::cast(result);
-    copy->GetLocalPropertyNames(names, 0);
-    for (int i = 0; i < names->length(); i++) {
-      ASSERT(names->get(i)->IsString());
-      String* key_string = String::cast(names->get(i));
-      PropertyAttributes attributes =
-          copy->GetLocalPropertyAttribute(key_string);
-      // Only deep copy fields from the object literal expression.
-      // In particular, don't try to copy the length attribute of
-      // an array.
-      if (attributes != NONE) continue;
-      Object* value =
-          copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
-      if (value->IsJSObject()) {
-        JSObject* js_object = JSObject::cast(value);
-        { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
-          if (!maybe_result->ToObject(&result)) return maybe_result;
-        }
-        { MaybeObject* maybe_result =
-              // Creating object copy for literals. No strict mode needed.
-              copy->SetProperty(key_string, result, NONE, kNonStrictMode);
-          if (!maybe_result->ToObject(&result)) return maybe_result;
-        }
-      }
-    }
-  }
-
-  // Deep copy local elements.
-  // Pixel elements cannot be created using an object literal.
-  ASSERT(!copy->HasExternalArrayElements());
-  switch (copy->GetElementsKind()) {
-    case FAST_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS: {
-      FixedArray* elements = FixedArray::cast(copy->elements());
-      if (elements->map() == heap->fixed_cow_array_map()) {
-        isolate->counters()->cow_arrays_created_runtime()->Increment();
-#ifdef DEBUG
-        for (int i = 0; i < elements->length(); i++) {
-          ASSERT(!elements->get(i)->IsJSObject());
-        }
-#endif
-      } else {
-        for (int i = 0; i < elements->length(); i++) {
-          Object* value = elements->get(i);
-          ASSERT(value->IsSmi() ||
-                 value->IsTheHole() ||
-                 (IsFastObjectElementsKind(copy->GetElementsKind())));
-          if (value->IsJSObject()) {
-            JSObject* js_object = JSObject::cast(value);
-            { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
-                                                              js_object);
-              if (!maybe_result->ToObject(&result)) return maybe_result;
-            }
-            elements->set(i, result);
-          }
-        }
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      SeededNumberDictionary* element_dictionary = copy->element_dictionary();
-      int capacity = element_dictionary->Capacity();
-      for (int i = 0; i < capacity; i++) {
-        Object* k = element_dictionary->KeyAt(i);
-        if (element_dictionary->IsKey(k)) {
-          Object* value = element_dictionary->ValueAt(i);
-          if (value->IsJSObject()) {
-            JSObject* js_object = JSObject::cast(value);
-            { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
-                                                              js_object);
-              if (!maybe_result->ToObject(&result)) return maybe_result;
-            }
-            element_dictionary->ValueAtPut(i, result);
-          }
-        }
-      }
-      break;
-    }
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
-      UNIMPLEMENTED();
-      break;
-    case EXTERNAL_PIXEL_ELEMENTS:
-    case EXTERNAL_BYTE_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-    case EXTERNAL_SHORT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-    case EXTERNAL_FLOAT_ELEMENTS:
-    case EXTERNAL_DOUBLE_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS:
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-      // No contained objects, nothing to do.
-      break;
-  }
-  return copy;
-}
-
-
 static Handle<Map> ComputeObjectLiteralMap(
     Handle<Context> context,
     Handle<FixedArray> constant_properties,
@@ -598,7 +457,7 @@
     // Update the functions literal and return the boilerplate.
     literals->set(literals_index, *boilerplate);
   }
-  return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
+  return JSObject::cast(*boilerplate)->DeepCopy(isolate);
 }
 
 
@@ -645,7 +504,7 @@
     // Update the functions literal and return the boilerplate.
     literals->set(literals_index, *boilerplate);
   }
-  return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
+  return JSObject::cast(*boilerplate)->DeepCopy(isolate);
 }
 
 
@@ -683,9 +542,23 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  Handle<Object> name(args[0], isolate);
+  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+  Symbol* symbol;
+  MaybeObject* maybe = isolate->heap()->AllocateSymbol();
+  if (!maybe->To(&symbol)) return maybe;
+  if (name->IsString()) symbol->set_name(*name);
+  return symbol;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) {
   NoHandleAllocation ha(isolate);
-  ASSERT(args.length() == 0);
-  return isolate->heap()->AllocateSymbol();
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
+  return symbol->name();
 }
 
 
@@ -764,6 +637,125 @@
 }
 
 
+static size_t ArrayBufferAllocatedLength(Isolate* isolate,
+                                         JSArrayBuffer* buffer) {
+  NoHandleAllocation hc(isolate);
+  Object* byte_length = buffer->byte_length();
+  if (byte_length->IsSmi()) {
+    return Smi::cast(byte_length)->value();
+  } else {
+    double value = HeapNumber::cast(byte_length)->value();
+    return static_cast<size_t>(value);
+  }
+}
+
+
+static void ArrayBufferWeakCallback(v8::Isolate* external_isolate,
+                                    Persistent<Value> object,
+                                    void* data) {
+  Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate);
+  HandleScope scope(isolate);
+  Handle<Object> internal_object = Utils::OpenHandle(*object);
+
+  size_t allocated_length = ArrayBufferAllocatedLength(
+      isolate, JSArrayBuffer::cast(*internal_object));
+  isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
+      -static_cast<intptr_t>(allocated_length));
+  if (data != NULL)
+    free(data);
+  object.Dispose(external_isolate);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
+  size_t allocated_length;
+  if (byteLength->IsSmi()) {
+    allocated_length = Smi::cast(*byteLength)->value();
+  } else {
+    ASSERT(byteLength->IsHeapNumber());
+    double value = HeapNumber::cast(*byteLength)->value();
+
+    ASSERT(value >= 0);
+
+    if (value > std::numeric_limits<size_t>::max()) {
+      return isolate->Throw(
+          *isolate->factory()->NewRangeError("invalid_array_buffer_length",
+            HandleVector<Object>(NULL, 0)));
+    }
+
+    allocated_length = static_cast<size_t>(value);
+  }
+
+  void* data;
+  if (allocated_length != 0) {
+    data = malloc(allocated_length);
+
+    if (data == NULL) {
+      return isolate->Throw(*isolate->factory()->
+          NewRangeError("invalid_array_buffer_length",
+            HandleVector<Object>(NULL, 0)));
+    }
+
+    memset(data, 0, allocated_length);
+  } else {
+    data = NULL;
+  }
+  holder->set_backing_store(data);
+
+  Object* byte_length;
+  {
+    MaybeObject* maybe_byte_length =
+        isolate->heap()->NumberFromDouble(
+            static_cast<double>(allocated_length));
+    if (!maybe_byte_length->ToObject(&byte_length)) return maybe_byte_length;
+  }
+  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
+  holder->set_byte_length(byte_length);
+
+  v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate);
+  v8::Handle<Object> external_holder(*holder);
+  Persistent<Object> weak_handle = Persistent<Object>::New(
+      external_isolate, external_holder);
+  weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback);
+  weak_handle.MarkIndependent(external_isolate);
+  isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
+
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
+  NoHandleAllocation ha(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
+  return holder->byte_length();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
+  CONVERT_DOUBLE_ARG_CHECKED(first, 2);
+  size_t start = static_cast<size_t>(first);
+  size_t target_length = ArrayBufferAllocatedLength(isolate, *target);
+
+  if (target_length == 0)
+    return isolate->heap()->undefined_value();
+
+  ASSERT(ArrayBufferAllocatedLength(isolate, *source) - target_length >= start);
+  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
+  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
+  CopyBytes(target_data, source_data + start, target_length);
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
@@ -2231,7 +2223,7 @@
   target->set_literals(*literals);
 
   if (isolate->logger()->is_logging_code_events() ||
-      CpuProfiler::is_profiling(isolate)) {
+      isolate->cpu_profiler()->is_profiling()) {
     isolate->logger()->LogExistingFunction(
         source_shared, Handle<Code>(source_shared->code()));
   }
@@ -4731,11 +4723,13 @@
 // args[0]: object
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 2);
   if (!args[0]->IsJSObject()) {
     return isolate->heap()->undefined_value();
   }
   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(include_symbols, 1);
+  PropertyAttributes filter = include_symbols ? NONE : SYMBOLIC;
 
   // Skip the global proxy as it has no properties and always delegates to the
   // real global object.
@@ -4768,7 +4762,7 @@
       return *isolate->factory()->NewJSArray(0);
     }
     int n;
-    n = jsproto->NumberOfLocalProperties();
+    n = jsproto->NumberOfLocalProperties(filter);
     local_property_count[i] = n;
     total_property_count += n;
     if (i < length - 1) {
@@ -4785,7 +4779,7 @@
   int proto_with_hidden_properties = 0;
   int next_copy_index = 0;
   for (int i = 0; i < length; i++) {
-    jsproto->GetLocalPropertyNames(*names, next_copy_index);
+    jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
     next_copy_index += local_property_count[i];
     if (jsproto->HasHiddenProperties()) {
       proto_with_hidden_properties++;
@@ -4795,7 +4789,7 @@
     }
   }
 
-  // Filter out name of hidden propeties object.
+  // Filter out name of hidden properties object.
   if (proto_with_hidden_properties > 0) {
     Handle<FixedArray> old_names = names;
     names = isolate->factory()->NewFixedArray(
@@ -5035,6 +5029,8 @@
       }
       ASSERT(heap_obj->IsUndefined());
       return isolate->heap()->undefined_string();
+    case SYMBOL_TYPE:
+      return isolate->heap()->symbol_string();
     case JS_FUNCTION_TYPE:
     case JS_FUNCTION_PROXY_TYPE:
       return isolate->heap()->function_string();
@@ -5137,10 +5133,10 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
-  NoHandleAllocation ha(isolate);
-  CONVERT_ARG_CHECKED(SeqString, string, 0);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
   CONVERT_SMI_ARG_CHECKED(new_length, 1);
-  return string->Truncate(new_length);
+  return *SeqString::Truncate(string, new_length);
 }
 
 
@@ -5171,365 +5167,11 @@
 }
 
 
-static const unsigned int kQuoteTableLength = 128u;
-
-static const int kJsonQuotesCharactersPerEntry = 8;
-static const char* const JsonQuotes =
-    "\\u0000  \\u0001  \\u0002  \\u0003  "
-    "\\u0004  \\u0005  \\u0006  \\u0007  "
-    "\\b      \\t      \\n      \\u000b  "
-    "\\f      \\r      \\u000e  \\u000f  "
-    "\\u0010  \\u0011  \\u0012  \\u0013  "
-    "\\u0014  \\u0015  \\u0016  \\u0017  "
-    "\\u0018  \\u0019  \\u001a  \\u001b  "
-    "\\u001c  \\u001d  \\u001e  \\u001f  "
-    "        !       \\\"      #       "
-    "$       %       &       '       "
-    "(       )       *       +       "
-    ",       -       .       /       "
-    "0       1       2       3       "
-    "4       5       6       7       "
-    "8       9       :       ;       "
-    "<       =       >       ?       "
-    "@       A       B       C       "
-    "D       E       F       G       "
-    "H       I       J       K       "
-    "L       M       N       O       "
-    "P       Q       R       S       "
-    "T       U       V       W       "
-    "X       Y       Z       [       "
-    "\\\\      ]       ^       _       "
-    "`       a       b       c       "
-    "d       e       f       g       "
-    "h       i       j       k       "
-    "l       m       n       o       "
-    "p       q       r       s       "
-    "t       u       v       w       "
-    "x       y       z       {       "
-    "|       }       ~       \177       ";
-
-
-// For a string that is less than 32k characters it should always be
-// possible to allocate it in new space.
-static const int kMaxGuaranteedNewSpaceString = 32 * 1024;
-
-
-// Doing JSON quoting cannot make the string more than this many times larger.
-static const int kJsonQuoteWorstCaseBlowup = 6;
-
-static const int kSpaceForQuotesAndComma = 3;
-static const int kSpaceForBrackets = 2;
-
-// Covers the entire ASCII range (all other characters are unchanged by JSON
-// quoting).
-static const byte JsonQuoteLengths[kQuoteTableLength] = {
-    6, 6, 6, 6, 6, 6, 6, 6,
-    2, 2, 2, 6, 2, 2, 6, 6,
-    6, 6, 6, 6, 6, 6, 6, 6,
-    6, 6, 6, 6, 6, 6, 6, 6,
-    1, 1, 2, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 2, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1,
-};
-
-
-template <typename StringType>
-MaybeObject* AllocateRawString(Isolate* isolate, int length);
-
-
-template <>
-MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) {
-  return isolate->heap()->AllocateRawTwoByteString(length);
-}
-
-
-template <>
-MaybeObject* AllocateRawString<SeqOneByteString>(Isolate* isolate, int length) {
-  return isolate->heap()->AllocateRawOneByteString(length);
-}
-
-
-template <typename Char, typename StringType, bool comma>
-static MaybeObject* SlowQuoteJsonString(Isolate* isolate,
-                                        Vector<const Char> characters) {
-  int length = characters.length();
-  const Char* read_cursor = characters.start();
-  const Char* end = read_cursor + length;
-  const int kSpaceForQuotes = 2 + (comma ? 1 :0);
-  int quoted_length = kSpaceForQuotes;
-  while (read_cursor < end) {
-    Char c = *(read_cursor++);
-    if (static_cast<unsigned>(c) >= kQuoteTableLength) {
-      quoted_length++;
-    } else {
-      quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)];
-    }
-  }
-  MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
-                                                         quoted_length);
-  Object* new_object;
-  if (!new_alloc->ToObject(&new_object)) {
-    return new_alloc;
-  }
-  StringType* new_string = StringType::cast(new_object);
-
-  Char* write_cursor = reinterpret_cast<Char*>(
-      new_string->address() + SeqString::kHeaderSize);
-  if (comma) *(write_cursor++) = ',';
-  *(write_cursor++) = '"';
-
-  read_cursor = characters.start();
-  while (read_cursor < end) {
-    Char c = *(read_cursor++);
-    if (static_cast<unsigned>(c) >= kQuoteTableLength) {
-      *(write_cursor++) = c;
-    } else {
-      int len = JsonQuoteLengths[static_cast<unsigned>(c)];
-      const char* replacement = JsonQuotes +
-          static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
-      for (int i = 0; i < len; i++) {
-        *write_cursor++ = *replacement++;
-      }
-    }
-  }
-  *(write_cursor++) = '"';
-  return new_string;
-}
-
-
-template <typename SinkChar, typename SourceChar>
-static inline SinkChar* WriteQuoteJsonString(
-    Isolate* isolate,
-    SinkChar* write_cursor,
-    Vector<const SourceChar> characters) {
-  // SinkChar is only char if SourceChar is guaranteed to be char.
-  ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
-  const SourceChar* read_cursor = characters.start();
-  const SourceChar* end = read_cursor + characters.length();
-  *(write_cursor++) = '"';
-  while (read_cursor < end) {
-    SourceChar c = *(read_cursor++);
-    if (static_cast<unsigned>(c) >= kQuoteTableLength) {
-      *(write_cursor++) = static_cast<SinkChar>(c);
-    } else {
-      int len = JsonQuoteLengths[static_cast<unsigned>(c)];
-      const char* replacement = JsonQuotes +
-          static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
-      write_cursor[0] = replacement[0];
-      if (len > 1) {
-        write_cursor[1] = replacement[1];
-        if (len > 2) {
-          ASSERT(len == 6);
-          write_cursor[2] = replacement[2];
-          write_cursor[3] = replacement[3];
-          write_cursor[4] = replacement[4];
-          write_cursor[5] = replacement[5];
-        }
-      }
-      write_cursor += len;
-    }
-  }
-  *(write_cursor++) = '"';
-  return write_cursor;
-}
-
-
-template <typename Char, typename StringType, bool comma>
-static MaybeObject* QuoteJsonString(Isolate* isolate,
-                                    Vector<const Char> characters) {
-  int length = characters.length();
-  isolate->counters()->quote_json_char_count()->Increment(length);
-  int worst_case_length =
-        length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
-  if (worst_case_length > kMaxGuaranteedNewSpaceString) {
-    return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
-  }
-
-  MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
-                                                         worst_case_length);
-  Object* new_object;
-  if (!new_alloc->ToObject(&new_object)) {
-    return new_alloc;
-  }
-  if (!isolate->heap()->new_space()->Contains(new_object)) {
-    // Even if our string is small enough to fit in new space we still have to
-    // handle it being allocated in old space as may happen in the third
-    // attempt.  See CALL_AND_RETRY in heap-inl.h and similar code in
-    // CEntryStub::GenerateCore.
-    return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
-  }
-  StringType* new_string = StringType::cast(new_object);
-  ASSERT(isolate->heap()->new_space()->Contains(new_string));
-
-  Char* write_cursor = reinterpret_cast<Char*>(
-      new_string->address() + SeqString::kHeaderSize);
-  if (comma) *(write_cursor++) = ',';
-  write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
-                                                  write_cursor,
-                                                  characters);
-  int final_length = static_cast<int>(
-      write_cursor - reinterpret_cast<Char*>(
-          new_string->address() + SeqString::kHeaderSize));
-  isolate->heap()->new_space()->
-      template ShrinkStringAtAllocationBoundary<StringType>(
-          new_string, final_length);
-  return new_string;
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
-  NoHandleAllocation ha(isolate);
-  CONVERT_ARG_CHECKED(String, str, 0);
-  if (!str->IsFlat()) {
-    MaybeObject* try_flatten = str->TryFlatten();
-    Object* flat;
-    if (!try_flatten->ToObject(&flat)) {
-      return try_flatten;
-    }
-    str = String::cast(flat);
-    ASSERT(str->IsFlat());
-  }
-  String::FlatContent flat = str->GetFlatContent();
-  ASSERT(flat.IsFlat());
-  if (flat.IsTwoByte()) {
-    return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
-                                                          flat.ToUC16Vector());
-  } else {
-    return QuoteJsonString<uint8_t, SeqOneByteString, false>(
-        isolate,
-        flat.ToOneByteVector());
-  }
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
-  NoHandleAllocation ha(isolate);
-  CONVERT_ARG_CHECKED(String, str, 0);
-  if (!str->IsFlat()) {
-    MaybeObject* try_flatten = str->TryFlatten();
-    Object* flat;
-    if (!try_flatten->ToObject(&flat)) {
-      return try_flatten;
-    }
-    str = String::cast(flat);
-    ASSERT(str->IsFlat());
-  }
-  String::FlatContent flat = str->GetFlatContent();
-  if (flat.IsTwoByte()) {
-    return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
-                                                         flat.ToUC16Vector());
-  } else {
-    return QuoteJsonString<uint8_t, SeqOneByteString, true>(
-        isolate,
-        flat.ToOneByteVector());
-  }
-}
-
-
-template <typename Char, typename StringType>
-static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
-                                         FixedArray* array,
-                                         int worst_case_length) {
-  int length = array->length();
-
-  MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
-                                                         worst_case_length);
-  Object* new_object;
-  if (!new_alloc->ToObject(&new_object)) {
-    return new_alloc;
-  }
-  if (!isolate->heap()->new_space()->Contains(new_object)) {
-    // Even if our string is small enough to fit in new space we still have to
-    // handle it being allocated in old space as may happen in the third
-    // attempt.  See CALL_AND_RETRY in heap-inl.h and similar code in
-    // CEntryStub::GenerateCore.
-    return isolate->heap()->undefined_value();
-  }
-  AssertNoAllocation no_gc;
-  StringType* new_string = StringType::cast(new_object);
-  ASSERT(isolate->heap()->new_space()->Contains(new_string));
-
-  Char* write_cursor = reinterpret_cast<Char*>(
-      new_string->address() + SeqString::kHeaderSize);
-  *(write_cursor++) = '[';
-  for (int i = 0; i < length; i++) {
-    if (i != 0) *(write_cursor++) = ',';
-    String* str = String::cast(array->get(i));
-    String::FlatContent content = str->GetFlatContent();
-    ASSERT(content.IsFlat());
-    if (content.IsTwoByte()) {
-      write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
-                                                      write_cursor,
-                                                      content.ToUC16Vector());
-    } else {
-      write_cursor =
-          WriteQuoteJsonString<Char, uint8_t>(isolate,
-                                              write_cursor,
-                                              content.ToOneByteVector());
-    }
-  }
-  *(write_cursor++) = ']';
-
-  int final_length = static_cast<int>(
-      write_cursor - reinterpret_cast<Char*>(
-          new_string->address() + SeqString::kHeaderSize));
-  isolate->heap()->new_space()->
-      template ShrinkStringAtAllocationBoundary<StringType>(
-          new_string, final_length);
-  return new_string;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
-  NoHandleAllocation ha(isolate);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
   ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSArray, array, 0);
-
-  if (!array->HasFastObjectElements()) {
-    return isolate->heap()->undefined_value();
-  }
-  FixedArray* elements = FixedArray::cast(array->elements());
-  int n = elements->length();
-  bool ascii = true;
-  int total_length = 0;
-
-  for (int i = 0; i < n; i++) {
-    Object* elt = elements->get(i);
-    if (!elt->IsString()) return isolate->heap()->undefined_value();
-    String* element = String::cast(elt);
-    if (!element->IsFlat()) return isolate->heap()->undefined_value();
-    total_length += element->length();
-    if (ascii && element->IsTwoByteRepresentation()) {
-      ascii = false;
-    }
-  }
-
-  int worst_case_length =
-      kSpaceForBrackets + n * kSpaceForQuotesAndComma
-      + total_length * kJsonQuoteWorstCaseBlowup;
-
-  if (worst_case_length > kMaxGuaranteedNewSpaceString) {
-    return isolate->heap()->undefined_value();
-  }
-
-  if (ascii) {
-    return QuoteJsonStringArray<char, SeqOneByteString>(isolate,
-                                                      elements,
-                                                      worst_case_length);
-  } else {
-    return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
-                                                        elements,
-                                                        worst_case_length);
-  }
+  return BasicJsonStringifier::StringifyString(isolate, string);
 }
 
 
@@ -6134,6 +5776,24 @@
 }
 
 
+// ES6 draft 9.1.11
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPositiveInteger) {
+  NoHandleAllocation ha(isolate);
+  ASSERT(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+
+  // We do not include 0 so that we don't have to treat +0 / -0 cases.
+  if (number > 0 && number <= Smi::kMaxValue) {
+    return Smi::FromInt(static_cast<int>(number));
+  }
+  if (number <= 0) {
+    return Smi::FromInt(0);
+  }
+  return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
   NoHandleAllocation ha(isolate);
   ASSERT(args.length() == 1);
@@ -9895,9 +9555,9 @@
 
 
 // Returns an array that tells you where in the [0, length) interval an array
-// might have elements.  Can either return keys (positive integers) or
-// intervals (pair of a negative integer (-start-1) followed by a
-// positive (length)) or undefined values.
+// might have elements.  Can either return an array of keys (positive integers
+// or undefined) or a number representing the positive length of an interval
+// starting at index 0.
 // Intervals can span over some keys that are not in the object.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
   HandleScope scope(isolate);
@@ -9905,37 +9565,34 @@
   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
   if (array->elements()->IsDictionary()) {
-    // Create an array and get all the keys into it, then remove all the
-    // keys that are not integers in the range 0 to length-1.
-    bool threw = false;
-    Handle<FixedArray> keys =
-        GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw);
-    if (threw) return Failure::Exception();
-
-    int keys_length = keys->length();
-    for (int i = 0; i < keys_length; i++) {
-      Object* key = keys->get(i);
-      uint32_t index = 0;
-      if (!key->ToArrayIndex(&index) || index >= length) {
-        // Zap invalid keys.
-        keys->set_undefined(i);
+    Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
+    for (Handle<Object> p = array;
+         !p->IsNull();
+         p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
+      if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
+        // Bail out if we find a proxy or interceptor, likely not worth
+        // collecting keys in that case.
+        return *isolate->factory()->NewNumberFromUint(length);
       }
+      Handle<JSObject> current = Handle<JSObject>::cast(p);
+      Handle<FixedArray> current_keys =
+          isolate->factory()->NewFixedArray(
+              current->NumberOfLocalElements(NONE));
+      current->GetLocalElementKeys(*current_keys, NONE);
+      keys = UnionOfKeys(keys, current_keys);
+    }
+    // Erase any keys >= length.
+    // TODO(adamk): Remove this step when the contract of %GetArrayKeys
+    // is changed to let this happen on the JS side.
+    for (int i = 0; i < keys->length(); i++) {
+      if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
     }
     return *isolate->factory()->NewJSArrayWithElements(keys);
   } else {
     ASSERT(array->HasFastSmiOrObjectElements() ||
            array->HasFastDoubleElements());
-    Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
-    // -1 means start of array.
-    single_interval->set(0, Smi::FromInt(-1));
-    FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
-    uint32_t actual_length =
-        static_cast<uint32_t>(elements->length());
-    uint32_t min_length = actual_length < length ? actual_length : length;
-    Handle<Object> length_object =
-        isolate->factory()->NewNumber(static_cast<double>(min_length));
-    single_interval->set(1, *length_object);
-    return *isolate->factory()->NewJSArrayWithElements(single_interval);
+    uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
+    return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
   }
 }
 
@@ -11810,6 +11467,13 @@
 }
 
 
+static bool IsBlockOrCatchOrWithScope(ScopeIterator::ScopeType type) {
+  return type == ScopeIterator::ScopeTypeBlock ||
+         type == ScopeIterator::ScopeTypeCatch ||
+         type == ScopeIterator::ScopeTypeWith;
+}
+
+
 // Creates a copy of the with context chain. The copy of the context chain is
 // is linked to the function context supplied.
 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
@@ -11824,8 +11488,7 @@
   ScopeIterator it(isolate, frame, inlined_jsframe_index);
   if (it.Failed()) return Handle<Context>::null();
 
-  for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
-         it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
+  for ( ; IsBlockOrCatchOrWithScope(it.Type()); it.Next()) {
     ASSERT(!it.Done());
     scope_chain.Add(it.CurrentScopeInfo());
     context_chain.Add(it.CurrentContext());
@@ -11841,6 +11504,7 @@
     ASSERT(!(scope_info->HasContext() & current.is_null()));
 
     if (scope_info->Type() == CATCH_SCOPE) {
+      ASSERT(current->IsCatchContext());
       Handle<String> name(String::cast(current->extension()));
       Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX),
                                    isolate);
@@ -11851,6 +11515,7 @@
                                               thrown_object);
     } else if (scope_info->Type() == BLOCK_SCOPE) {
       // Materialize the contents of the block scope into a JSObject.
+      ASSERT(current->IsBlockContext());
       Handle<JSObject> block_scope_object =
           MaterializeBlockScope(isolate, current);
       CHECK(!block_scope_object.is_null());
@@ -11903,19 +11568,10 @@
     }
   }
 
-  Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction()));
-  int length = frame_inspector->GetParametersCount();
-  Handle<JSObject> arguments =
-      isolate->factory()->NewArgumentsObject(function, length);
-  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
-
-  AssertNoAllocation no_gc;
-  WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
-  for (int i = 0; i < length; i++) {
-    array->set(i, frame_inspector->GetParameter(i), mode);
-  }
-  arguments->set_elements(*array);
-  return arguments;
+  // FunctionGetArguments can't return a non-Object.
+  return Handle<JSObject>(JSObject::cast(
+      Accessors::FunctionGetArguments(frame_inspector->GetFunction(),
+                                      NULL)->ToObjectUnchecked()), isolate);
 }
 
 
@@ -12026,23 +11682,26 @@
       isolate, frame, &frame_inspector);
   RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
 
-  Handle<Context> frame_context(Context::cast(frame->context()));
-  Handle<Context> function_context;
-  Handle<ScopeInfo> scope_info(function->shared()->scope_info());
-  if (scope_info->HasContext()) {
-    function_context = Handle<Context>(frame_context->declaration_context());
+  // Do not materialize the arguments object for eval or top-level code.
+  if (function->shared()->is_function()) {
+    Handle<Context> frame_context(Context::cast(frame->context()));
+    Handle<Context> function_context;
+    Handle<ScopeInfo> scope_info(function->shared()->scope_info());
+    if (scope_info->HasContext()) {
+      function_context = Handle<Context>(frame_context->declaration_context());
+    }
+    Handle<Object> arguments = GetArgumentsObject(isolate,
+                                                  frame,
+                                                  &frame_inspector,
+                                                  scope_info,
+                                                  function_context);
+    SetProperty(isolate,
+                local_scope,
+                isolate->factory()->arguments_string(),
+                arguments,
+                ::NONE,
+                kNonStrictMode);
   }
-  Handle<Object> arguments = GetArgumentsObject(isolate,
-                                                frame,
-                                                &frame_inspector,
-                                                scope_info,
-                                                function_context);
-  SetProperty(isolate,
-              local_scope,
-              isolate->factory()->arguments_string(),
-              arguments,
-              ::NONE,
-              kNonStrictMode);
 
   // Allocate a new context for the debug evaluation and set the extension
   // object build.
@@ -13181,7 +12840,7 @@
   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
   if (obj->IsJSGlobalProxy()) {
     Object* proto = obj->GetPrototype();
-    if (obj->IsNull()) return isolate->heap()->false_value();
+    if (proto->IsNull()) return isolate->heap()->false_value();
     ASSERT(proto->IsJSGlobalObject());
     obj = JSReceiver::cast(proto);
   }
@@ -13196,7 +12855,7 @@
   CONVERT_BOOLEAN_ARG_CHECKED(is_observed, 1);
   if (obj->IsJSGlobalProxy()) {
     Object* proto = obj->GetPrototype();
-    if (obj->IsNull()) return isolate->heap()->undefined_value();
+    if (proto->IsNull()) return isolate->heap()->undefined_value();
     ASSERT(proto->IsJSGlobalObject());
     obj = JSReceiver::cast(proto);
   }
diff --git a/src/runtime.h b/src/runtime.h
index 2959fed..b16acd1 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -55,7 +55,7 @@
   F(IsPropertyEnumerable, 2, 1) \
   F(GetPropertyNames, 1, 1) \
   F(GetPropertyNamesFast, 1, 1) \
-  F(GetLocalPropertyNames, 1, 1) \
+  F(GetLocalPropertyNames, 2, 1) \
   F(GetLocalElementNames, 1, 1) \
   F(GetInterceptorInfo, 1, 1) \
   F(GetNamedInterceptorPropertyNames, 1, 1) \
@@ -129,6 +129,7 @@
   F(NumberToString, 1, 1) \
   F(NumberToStringSkipCache, 1, 1) \
   F(NumberToInteger, 1, 1) \
+  F(NumberToPositiveInteger, 1, 1) \
   F(NumberToIntegerMapMinusZero, 1, 1) \
   F(NumberToJSUint32, 1, 1) \
   F(NumberToJSInt32, 1, 1) \
@@ -195,8 +196,6 @@
   F(ParseJson, 1, 1) \
   F(BasicJSONStringify, 1, 1) \
   F(QuoteJSONString, 1, 1) \
-  F(QuoteJSONStringComma, 1, 1) \
-  F(QuoteJSONStringArray, 1, 1) \
   \
   /* Strings */ \
   F(StringCharCodeAt, 2, 1) \
@@ -299,7 +298,8 @@
   F(IsJSModule, 1, 1) \
   \
   /* Harmony symbols */ \
-  F(CreateSymbol, 0, 1) \
+  F(CreateSymbol, 1, 1) \
+  F(SymbolName, 1, 1) \
   \
   /* Harmony proxies */ \
   F(CreateJSProxy, 2, 1) \
@@ -341,6 +341,11 @@
   F(ObservationWeakMapCreate, 0, 1) \
   F(UnwrapGlobalProxy, 1, 1) \
   \
+  /* Harmony typed arrays */ \
+  F(ArrayBufferInitialize, 2, 1)\
+  F(ArrayBufferGetByteLength, 1, 1)\
+  F(ArrayBufferSliceImpl, 3, 1) \
+  \
   /* Statements */ \
   F(NewClosure, 3, 1) \
   F(NewObject, 1, 1) \
@@ -514,7 +519,6 @@
 #define INLINE_FUNCTION_LIST(F) \
   F(IsSmi, 1, 1)                                                             \
   F(IsNonNegativeSmi, 1, 1)                                                  \
-  F(IsSymbol, 1, 1)                                                          \
   F(IsArray, 1, 1)                                                           \
   F(IsRegExp, 1, 1)                                                          \
   F(IsConstructCall, 0, 1)                                                   \
diff --git a/src/runtime.js b/src/runtime.js
index 09b39ff..22f888d 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -69,16 +69,24 @@
     } else if (IS_STRING(x)) {
       while (true) {
         if (IS_STRING(y)) return %StringEquals(x, y);
+        if (IS_SYMBOL(y)) return 1;  // not equal
         if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
         if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
         if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
         y = %ToPrimitive(y, NO_HINT);
       }
+    } else if (IS_SYMBOL(x)) {
+      while (true) {
+        if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1;
+        if (!IS_SPEC_OBJECT(y)) return 1;  // not equal
+        y = %ToPrimitive(y, NO_HINT);
+      }
     } else if (IS_BOOLEAN(x)) {
       if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
       if (IS_NULL_OR_UNDEFINED(y)) return 1;
       if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
       if (IS_STRING(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
+      if (IS_SYMBOL(y)) return 1;  // not equal
       // y is object.
       x = %ToNumber(x);
       y = %ToPrimitive(y, NO_HINT);
@@ -508,6 +516,7 @@
   if (IS_STRING(x)) return x;
   // Normal behavior.
   if (!IS_SPEC_OBJECT(x)) return x;
+  if (IS_SYMBOL_WRAPPER(x)) return %_ValueOf(x);
   if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
   return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x);
 }
@@ -532,6 +541,7 @@
   }
   if (IS_BOOLEAN(x)) return x ? 1 : 0;
   if (IS_UNDEFINED(x)) return $NaN;
+  if (IS_SYMBOL(x)) return $NaN;
   return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
 }
 
@@ -542,6 +552,7 @@
   }
   if (IS_BOOLEAN(x)) return x ? 1 : 0;
   if (IS_UNDEFINED(x)) return $NaN;
+  if (IS_SYMBOL(x)) return $NaN;
   return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
 }
 
@@ -572,6 +583,7 @@
 // ECMA-262, section 9.9, page 36.
 function ToObject(x) {
   if (IS_STRING(x)) return new $String(x);
+  if (IS_SYMBOL(x)) return new $Symbol(x);
   if (IS_NUMBER(x)) return new $Number(x);
   if (IS_BOOLEAN(x)) return new $Boolean(x);
   if (IS_NULL_OR_UNDEFINED(x) && !IS_UNDETECTABLE(x)) {
diff --git a/src/scanner.cc b/src/scanner.cc
index bd2db58..ef2dc2c 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -877,7 +877,7 @@
   KEYWORD("while", Token::WHILE)                                    \
   KEYWORD("with", Token::WITH)                                      \
   KEYWORD_GROUP('y')                                                \
-  KEYWORD("yield", Token::FUTURE_STRICT_RESERVED_WORD)
+  KEYWORD("yield", Token::YIELD)
 
 
 static Token::Value KeywordOrIdentifierToken(const char* input,
diff --git a/src/scanner.h b/src/scanner.h
index a454750..dd1bfb8 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -53,7 +53,8 @@
   kLanguageModeMask = 0x03,
   kAllowLazy = 0x04,
   kAllowNativesSyntax = 0x08,
-  kAllowModules = 0x10
+  kAllowModules = 0x10,
+  kAllowGenerators = 0x20
 };
 
 STATIC_ASSERT((kLanguageModeMask & CLASSIC_MODE) == CLASSIC_MODE);
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index aeac570..77117b8 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -351,23 +351,6 @@
 }
 
 
-template <typename StringType>
-void NewSpace::ShrinkStringAtAllocationBoundary(String* string, int length) {
-  ASSERT(length <= string->length());
-  ASSERT(string->IsSeqString());
-  ASSERT(string->address() + StringType::SizeFor(string->length()) ==
-         allocation_info_.top);
-  Address old_top = allocation_info_.top;
-  allocation_info_.top =
-      string->address() + StringType::SizeFor(length);
-  string->set_length(length);
-  if (Marking::IsBlack(Marking::MarkBitFrom(string))) {
-    int delta = static_cast<int>(old_top - allocation_info_.top);
-    MemoryChunk::IncrementLiveBytesFromMutator(string->address(), -delta);
-  }
-}
-
-
 bool FreeListNode::IsFreeListNode(HeapObject* object) {
   Map* map = object->map();
   Heap* heap = object->GetHeap();
diff --git a/src/spaces.cc b/src/spaces.cc
index 2952fd5..f8e6a1e 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1030,10 +1030,10 @@
       size = 16 * kPointerSize * KB;
       break;
     case CODE_SPACE:
-      if (kPointerSize == 8) {
-        // On x64 we allocate code pages in a special way (from the reserved
-        // 2Byte area). That part of the code is not yet upgraded to handle
-        // small pages.
+      if (heap()->isolate()->code_range()->exists()) {
+        // When code range exists, code pages are allocated in a special way
+        // (from the reserved code range). That part of the code is not yet
+        // upgraded to handle small pages.
         size = AreaSize();
       } else {
         size = 384 * KB;
diff --git a/src/spaces.h b/src/spaces.h
index 39c19a4..65eefd0 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -2419,11 +2419,6 @@
 
   virtual bool ReserveSpace(int bytes);
 
-  // Resizes a sequential string which must be the most recent thing that was
-  // allocated in new space.
-  template <typename StringType>
-  inline void ShrinkStringAtAllocationBoundary(String* string, int len);
-
 #ifdef VERIFY_HEAP
   // Verify the active semispace.
   virtual void Verify();
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index c104d80..553c6f5 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -123,10 +123,13 @@
 
 
 Handle<Code> StubCache::FindHandler(Handle<Name> name,
+                                    Handle<JSObject> receiver,
                                     Handle<JSObject> stub_holder,
                                     Code::Kind kind,
-                                    Code::StubType type,
-                                    Code::ExtraICState extra_ic_state) {
+                                    Code::StubType type) {
+  Code::ExtraICState extra_ic_state = Code::ComputeExtraICState(
+      receiver.is_identical_to(stub_holder) ? Code::OWN_STUB
+                                            : Code::PROTOTYPE_STUB);
   ASSERT(type != Code::NORMAL);
   Code::Flags flags = Code::ComputeMonomorphicFlags(
       Code::STUB, extra_ic_state, type, kind);
@@ -194,7 +197,7 @@
   // Compile the stub that is either shared for all names or
   // name specific if there are global objects involved.
   Handle<Code> handler = FindHandler(
-      cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
+      cache_name, receiver, receiver, Code::LOAD_IC, Code::NONEXISTENT);
   if (!handler.is_null()) return handler;
 
   LoadStubCompiler compiler(isolate_);
@@ -218,7 +221,7 @@
 
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::LOAD_IC, Code::FIELD);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD);
   if (!stub.is_null()) return stub;
 
   LoadStubCompiler compiler(isolate_);
@@ -237,7 +240,7 @@
   ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
   LoadStubCompiler compiler(isolate_);
@@ -254,7 +257,7 @@
                                              Handle<JSFunction> getter) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
   LoadStubCompiler compiler(isolate_);
@@ -271,7 +274,7 @@
                                             Handle<JSFunction> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> handler = FindHandler(
-      name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
   if (!handler.is_null()) return handler;
 
   LoadStubCompiler compiler(isolate_);
@@ -287,7 +290,7 @@
                                                Handle<JSObject> holder) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
   if (!stub.is_null()) return stub;
 
   LoadStubCompiler compiler(isolate_);
@@ -334,7 +337,7 @@
 
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
+      name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
   if (!stub.is_null()) return stub;
 
   KeyedLoadStubCompiler compiler(isolate_);
@@ -351,7 +354,8 @@
                                                  Handle<JSFunction> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> handler = FindHandler(
-      name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
+      name, receiver, stub_holder, Code::KEYED_LOAD_IC,
+      Code::CONSTANT_FUNCTION);
   if (!handler.is_null()) return handler;
 
   KeyedLoadStubCompiler compiler(isolate_);
@@ -366,7 +370,7 @@
                                                     Handle<JSObject> holder) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
+      name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
   if (!stub.is_null()) return stub;
 
   KeyedLoadStubCompiler compiler(isolate_);
@@ -384,7 +388,7 @@
     Handle<ExecutableAccessorInfo> callback) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> stub = FindHandler(
-      name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
+      name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
   KeyedLoadStubCompiler compiler(isolate_);
@@ -397,7 +401,7 @@
 
 Handle<Code> StubCache::ComputeStoreField(Handle<Name> name,
                                           Handle<JSObject> receiver,
-                                          int field_index,
+                                          LookupResult* lookup,
                                           Handle<Map> transition,
                                           StrictModeFlag strict_mode) {
   Code::StubType type =
@@ -409,7 +413,7 @@
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code =
-      compiler.CompileStoreField(receiver, field_index, transition, name);
+      compiler.CompileStoreField(receiver, lookup, transition, name);
   JSObject::UpdateMapCodeCache(receiver, name, code);
   return code;
 }
@@ -532,7 +536,7 @@
 
 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name,
                                                Handle<JSObject> receiver,
-                                               int field_index,
+                                               LookupResult* lookup,
                                                Handle<Map> transition,
                                                StrictModeFlag strict_mode) {
   Code::StubType type =
@@ -543,7 +547,7 @@
 
   KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
   Handle<Code> code =
-      compiler.CompileStoreField(receiver, field_index, transition, name);
+      compiler.CompileStoreField(receiver, lookup, transition, name);
   JSObject::UpdateMapCodeCache(receiver, name, code);
   return code;
 }
@@ -1584,7 +1588,7 @@
 
 
 Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                      int index,
+                                                      LookupResult* lookup,
                                                       Handle<Map> transition,
                                                       Handle<Name> name) {
   Label miss, miss_restore_name;
@@ -1594,7 +1598,7 @@
   // Generate store field code.
   GenerateStoreField(masm(),
                      object,
-                     index,
+                     lookup,
                      transition,
                      name,
                      receiver(), this->name(), value(), scratch1(), scratch2(),
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 7c45566..bca3b7b 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -85,10 +85,10 @@
 
   Handle<Code> FindHandler(
       Handle<Name> name,
+      Handle<JSObject> receiver,
       Handle<JSObject> stub_holder,
       Code::Kind kind,
-      Code::StubType type,
-      Code::ExtraICState extra_state = Code::kNoExtraICState);
+      Code::StubType type);
 
   Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver,
                                     Handle<Code> handler,
@@ -161,7 +161,7 @@
 
   Handle<Code> ComputeStoreField(Handle<Name> name,
                                  Handle<JSObject> object,
-                                 int field_index,
+                                 LookupResult* lookup,
                                  Handle<Map> transition,
                                  StrictModeFlag strict_mode);
 
@@ -192,7 +192,7 @@
 
   Handle<Code> ComputeKeyedStoreField(Handle<Name> name,
                                       Handle<JSObject> object,
-                                      int field_index,
+                                      LookupResult* lookup,
                                       Handle<Map> transition,
                                       StrictModeFlag strict_mode);
 
@@ -511,7 +511,7 @@
 
   void GenerateStoreField(MacroAssembler* masm,
                           Handle<JSObject> object,
-                          int index,
+                          LookupResult* lookup,
                           Handle<Map> transition,
                           Handle<Name> name,
                           Register receiver_reg,
@@ -782,7 +782,7 @@
   virtual ~BaseStoreStubCompiler() { }
 
   Handle<Code> CompileStoreField(Handle<JSObject> object,
-                                 int index,
+                                 LookupResult* lookup,
                                  Handle<Map> transition,
                                  Handle<Name> name);
 
diff --git a/src/symbol.js b/src/symbol.js
index b7f9dc9..fb7476f 100644
--- a/src/symbol.js
+++ b/src/symbol.js
@@ -27,13 +27,55 @@
 
 "use strict";
 
-var $Symbol = function() { return %CreateSymbol() }
-global.Symbol = $Symbol
+var $Symbol = global.Symbol;
 
-// Symbols only have a toString method and no prototype.
-var SymbolDelegate = {
-  __proto__: null,
-  toString: $Object.prototype.toString
+function SymbolConstructor(x) {
+  var value =
+    IS_SYMBOL(x) ? x : %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
+  if (%_IsConstructCall()) {
+    %_SetValueOf(this, value);
+  } else {
+    return value;
+  }
 }
 
-$Object.freeze(SymbolDelegate)
+function SymbolGetName() {
+  var symbol = IS_SYMBOL_WRAPPER(this) ? %_ValueOf(this) : this;
+  if (!IS_SYMBOL(symbol)) {
+    throw MakeTypeError(
+        'incompatible_method_receiver', ["Symbol.prototype.name", this]);
+  }
+  return %SymbolName(symbol);
+}
+
+function SymbolToString() {
+  throw MakeTypeError('symbol_to_string');
+}
+
+function SymbolValueOf() {
+  // NOTE: Both Symbol objects and values can enter here as
+  // 'this'. This is not as dictated by ECMA-262.
+  if (!IS_SYMBOL(this) && !IS_SYMBOL_WRAPPER(this)) {
+    throw MakeTypeError(
+        'incompatible_method_receiver', ["Symbol.prototype.valueOf", this]);
+  }
+  return %_ValueOf(this);
+}
+
+//-------------------------------------------------------------------
+
+function SetUpSymbol() {
+  %CheckIsBootstrapping();
+
+  %SetCode($Symbol, SymbolConstructor);
+  %FunctionSetPrototype($Symbol, new $Symbol());
+  %SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
+
+  InstallGetter($Symbol.prototype, "name", SymbolGetName);
+  InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
+    "toString", SymbolToString,
+    "valueOf", SymbolValueOf
+  ));
+}
+
+SetUpSymbol();
diff --git a/src/token.h b/src/token.h
index 4078a15..04d7f76 100644
--- a/src/token.h
+++ b/src/token.h
@@ -174,6 +174,7 @@
   K(EXPORT, "export", 0)                                                \
   K(IMPORT, "import", 0)                                                \
   K(LET, "let", 0)                                                      \
+  K(YIELD, "yield", 0)                                                  \
                                                                         \
   /* Illegal token - not able to scan. */                               \
   T(ILLEGAL, "ILLEGAL", 0)                                              \
diff --git a/src/type-info.cc b/src/type-info.cc
index f31edb7..39a01f5 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -283,11 +283,12 @@
     case RECEIVER_MAP_CHECK:
       UNREACHABLE();
       break;
-    case SYMBOL_CHECK:
-      return Handle<JSObject>(native_context_->symbol_delegate());
     case STRING_CHECK:
       function = native_context_->string_function();
       break;
+    case SYMBOL_CHECK:
+      function = native_context_->symbol_function();
+      break;
     case NUMBER_CHECK:
       function = native_context_->number_function();
       break;
diff --git a/src/typedarray.js b/src/typedarray.js
new file mode 100644
index 0000000..c3e3ebd
--- /dev/null
+++ b/src/typedarray.js
@@ -0,0 +1,98 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"use strict";
+
+var $ArrayBuffer = global.__ArrayBuffer;
+
+function ArrayBufferConstructor(byteLength) { // length = 1
+  if (%_IsConstructCall()) {
+    var l = TO_POSITIVE_INTEGER(byteLength);
+    %ArrayBufferInitialize(this, l);
+  } else {
+    return new $ArrayBuffer(byteLength);
+  }
+}
+
+function ArrayBufferGetByteLength() {
+  if (!IS_ARRAYBUFFER(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['ArrayBuffer.prototype.byteLength', this]);
+  }
+  return %ArrayBufferGetByteLength(this);
+}
+
+// ES6 Draft 15.13.5.5.3
+function ArrayBufferSlice(start, end) {
+  if (!IS_ARRAYBUFFER(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['ArrayBuffer.prototype.slice', this]);
+  }
+
+  var relativeStart = TO_INTEGER(start);
+  var first;
+  if (relativeStart < 0) {
+    first = MathMax(this.byteLength + relativeStart, 0);
+  } else {
+    first = MathMin(relativeStart, this.byteLength);
+  }
+  var relativeEnd = IS_UNDEFINED(end) ? this.byteLength : TO_INTEGER(end);
+  var fin;
+  if (relativeEnd < 0) {
+    fin = MathMax(this.byteLength + relativeEnd, 0);
+  } else {
+    fin = MathMin(relativeEnd, this.byteLength);
+  }
+
+  var newLen = fin - first;
+  // TODO(dslomov): implement inheritance
+  var result = new $ArrayBuffer(newLen);
+
+  %ArrayBufferSliceImpl(this, result, first);
+  return result;
+}
+
+
+
+// -------------------------------------------------------------------
+
+(function () {
+  %CheckIsBootstrapping();
+
+  // Set up the Uint16Array constructor function.
+  %SetCode($ArrayBuffer, ArrayBufferConstructor);
+
+  // Set up the constructor property on the ArrayBuffer prototype object.
+  %SetProperty($ArrayBuffer.prototype, "constructor", $ArrayBuffer, DONT_ENUM);
+
+  InstallGetter($ArrayBuffer.prototype, "byteLength", ArrayBufferGetByteLength);
+
+  InstallFunctions($ArrayBuffer.prototype, DONT_ENUM, $Array(
+      "slice", ArrayBufferSlice
+  ));
+
+})();
diff --git a/src/v8globals.h b/src/v8globals.h
index 8874cfb..4b4d312 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -296,7 +296,7 @@
 
 enum InlineCacheHolderFlag {
   OWN_MAP,  // For fast properties objects.
-  DELEGATE_MAP  // For slow properties objects (except GlobalObjects).
+  PROTOTYPE_MAP  // For slow properties objects (except GlobalObjects).
 };
 
 
diff --git a/src/v8natives.js b/src/v8natives.js
index 24ad22d..d9dc096 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -233,7 +233,6 @@
 function ObjectToString() {
   if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
   if (IS_NULL(this)) return "[object Null]";
-  if (IS_SYMBOL(this)) return "[object Symbol]";
   return "[object " + %_ClassOf(ToObject(this)) + "]";
 }
 
@@ -257,6 +256,9 @@
 // ECMA-262 - 15.2.4.5
 function ObjectHasOwnProperty(V) {
   if (%IsJSProxy(this)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(V)) return false;
+
     var handler = %GetHandler(this);
     return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V));
   }
@@ -279,6 +281,9 @@
 function ObjectPropertyIsEnumerable(V) {
   var P = ToName(V);
   if (%IsJSProxy(this)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(V)) return false;
+
     var desc = GetOwnProperty(this, P);
     return IS_UNDEFINED(desc) ? false : desc.isEnumerable();
   }
@@ -646,6 +651,9 @@
 function GetOwnProperty(obj, v) {
   var p = ToName(v);
   if (%IsJSProxy(obj)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(v)) return void 0;
+
     var handler = %GetHandler(obj);
     var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p);
     if (IS_UNDEFINED(descriptor)) return descriptor;
@@ -686,6 +694,9 @@
 
 // Harmony proxies.
 function DefineProxyProperty(obj, p, attributes, should_throw) {
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (IS_SYMBOL(p)) return false;
+
   var handler = %GetHandler(obj);
   var result = CallTrap2(handler, "defineProperty", void 0, p, attributes);
   if (!ToBoolean(result)) {
@@ -865,7 +876,7 @@
   // DefineObjectProperty() to modify its value.
 
   // Step 3 - Special handling for length property.
-  if (p == "length") {
+  if (p === "length") {
     var length = obj.length;
     if (!desc.hasValue()) {
       return DefineObjectProperty(obj, "length", desc, should_throw);
@@ -951,6 +962,9 @@
 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
 function DefineOwnProperty(obj, p, desc, should_throw) {
   if (%IsJSProxy(obj)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(p)) return false;
+
     var attributes = FromGenericPropertyDescriptor(desc);
     return DefineProxyProperty(obj, p, attributes, should_throw);
   } else if (IS_ARRAY(obj)) {
@@ -988,16 +1002,20 @@
   }
   var n = ToUint32(obj.length);
   var array = new $Array(n);
+  var realLength = 0;
   var names = { __proto__: null };  // TODO(rossberg): use sets once ready.
   for (var index = 0; index < n; index++) {
     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)) {
       throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]);
     }
     array[index] = s;
+    ++realLength;
     names[s] = 0;
   }
+  array.length = realLength;
   return array;
 }
 
@@ -1011,7 +1029,7 @@
   if (%IsJSProxy(obj)) {
     var handler = %GetHandler(obj);
     var names = CallTrap0(handler, "getOwnPropertyNames", void 0);
-    return ToNameArray(names, "getOwnPropertyNames", true);
+    return ToNameArray(names, "getOwnPropertyNames", false);
   }
 
   var nameArrays = new InternalArray();
@@ -1037,7 +1055,7 @@
   // Find all the named properties.
 
   // Get the local property names.
-  nameArrays.push(%GetLocalPropertyNames(obj));
+  nameArrays.push(%GetLocalPropertyNames(obj, false));
 
   // Get names for named interceptor properties if any.
   if ((interceptorInfo & 2) != 0) {
@@ -1057,7 +1075,8 @@
     var propertySet = { __proto__: null };
     var j = 0;
     for (var i = 0; i < propertyNames.length; ++i) {
-      var name = ToName(propertyNames[i]);
+      if (IS_SYMBOL(propertyNames[i])) continue;
+      var name = ToString(propertyNames[i]);
       // We need to check for the exact property value since for intrinsic
       // properties like toString if(propertySet["toString"]) will always
       // succeed.
diff --git a/src/v8utils.h b/src/v8utils.h
index 606d8e7..b5c8f08 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -151,20 +151,19 @@
 
 // Copies data from |src| to |dst|.  The data spans must not overlap.
 template <typename T>
-inline void CopyBytes(T* dst, T* src, int num_bytes) {
+inline void CopyBytes(T* dst, T* src, size_t num_bytes) {
   STATIC_ASSERT(sizeof(T) == 1);
   ASSERT(Min(dst, src) + num_bytes <= Max(dst, src));
-  ASSERT(num_bytes >= 0);
   if (num_bytes == 0) return;
 
   // Use block copying OS::MemCopy if the segment we're copying is
   // enough to justify the extra call/setup overhead.
   static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
 
-  if (num_bytes >= kBlockCopyLimit) {
+  if (num_bytes >= static_cast<size_t>(kBlockCopyLimit)) {
     OS::MemCopy(dst, src, num_bytes);
   } else {
-    int remaining = num_bytes;
+    size_t remaining = num_bytes;
     do {
       remaining--;
       *dst++ = *src++;
diff --git a/src/version.cc b/src/version.cc
index 0ecf596..64ed98d 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     17
-#define BUILD_NUMBER      15
-#define PATCH_LEVEL       6
+#define BUILD_NUMBER      16
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 0b70c1a..2da3de2 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -220,12 +220,12 @@
       __ movzxbq(rdi, FieldOperand(rax, Map::kInstanceSizeOffset));
       __ shl(rdi, Immediate(kPointerSizeLog2));
       // rdi: size of new object
-      __ AllocateInNewSpace(rdi,
-                            rbx,
-                            rdi,
-                            no_reg,
-                            &rt_call,
-                            NO_ALLOCATION_FLAGS);
+      __ Allocate(rdi,
+                  rbx,
+                  rdi,
+                  no_reg,
+                  &rt_call,
+                  NO_ALLOCATION_FLAGS);
       // Allocated the JSObject, now initialize the fields.
       // rax: initial map
       // rbx: JSObject (not HeapObject tagged - the actual address).
@@ -287,14 +287,14 @@
       // rbx: JSObject
       // rdi: start of next object (will be start of FixedArray)
       // rdx: number of elements in properties array
-      __ AllocateInNewSpace(FixedArray::kHeaderSize,
-                            times_pointer_size,
-                            rdx,
-                            rdi,
-                            rax,
-                            no_reg,
-                            &undo_allocation,
-                            RESULT_CONTAINS_TOP);
+      __ Allocate(FixedArray::kHeaderSize,
+                  times_pointer_size,
+                  rdx,
+                  rdi,
+                  rax,
+                  no_reg,
+                  &undo_allocation,
+                  RESULT_CONTAINS_TOP);
 
       // Initialize the FixedArray.
       // rbx: JSObject
@@ -416,10 +416,6 @@
     __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
     __ j(above_equal, &exit);
 
-    // Symbols are "objects".
-    __ CmpInstanceType(rcx, SYMBOL_TYPE);
-    __ j(equal, &exit);
-
     // Throw away the result of the constructor invocation and use the
     // on-stack receiver as the result.
     __ bind(&use_receiver);
@@ -1216,14 +1212,14 @@
   // requested elements.
   SmiIndex index =
       masm->SmiToIndex(kScratchRegister, array_size, kPointerSizeLog2);
-  __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
-                        index.scale,
-                        index.reg,
-                        result,
-                        elements_array_end,
-                        scratch,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSArray::kSize + FixedArray::kHeaderSize,
+              index.scale,
+              index.reg,
+              result,
+              elements_array_end,
+              scratch,
+              gc_required,
+              TAG_OBJECT);
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 4ff1635..fffd37f 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -95,7 +95,7 @@
   // stack param count needs (constructor pointer, and single argument)
   descriptor->stack_parameter_count_ = &rax;
   descriptor->register_params_ = registers;
-  descriptor->extra_expression_stack_count_ = 1;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
       FUNCTION_ADDR(ArrayConstructor_StubFailure);
 }
@@ -2386,34 +2386,6 @@
 }
 
 
-void ArrayLengthStub::Generate(MacroAssembler* masm) {
-  Label miss;
-  Register receiver;
-  if (kind() == Code::KEYED_LOAD_IC) {
-    // ----------- S t a t e -------------
-    //  -- rax    : key
-    //  -- rdx    : receiver
-    //  -- rsp[0] : return address
-    // -----------------------------------
-    __ Cmp(rax, masm->isolate()->factory()->length_string());
-    __ j(not_equal, &miss);
-    receiver = rdx;
-  } else {
-    ASSERT(kind() == Code::LOAD_IC);
-    // ----------- S t a t e -------------
-    //  -- rax    : receiver
-    //  -- rcx    : name
-    //  -- rsp[0] : return address
-    // -----------------------------------
-    receiver = rax;
-  }
-
-  StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss);
-  __ bind(&miss);
-  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
-}
-
-
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver;
@@ -2663,7 +2635,7 @@
   __ addq(r8, Immediate(Heap::kArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
-  __ AllocateInNewSpace(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
+  __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
 
   // rax = address of new object(s) (tagged)
   // rcx = argument count (untagged)
@@ -2881,7 +2853,7 @@
   __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
+  __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
 
   // Get the arguments boilerplate from the current native context.
   __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
@@ -3414,14 +3386,14 @@
   // Allocate RegExpResult followed by FixedArray with size in rbx.
   // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
   // Elements:  [Map][Length][..elements..]
-  __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
-                        times_pointer_size,
-                        rbx,  // In: Number of elements.
-                        rax,  // Out: Start of allocation (tagged).
-                        rcx,  // Out: End of allocation.
-                        rdx,  // Scratch register
-                        &slowcase,
-                        TAG_OBJECT);
+  __ Allocate(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+              times_pointer_size,
+              rbx,  // In: Number of elements.
+              rax,  // Out: Start of allocation (tagged).
+              rcx,  // Out: End of allocation.
+              rdx,  // Scratch register
+              &slowcase,
+              TAG_OBJECT);
   // rax: Start of allocated area, object-tagged.
   // rbx: Number of array elements as int32.
   // r8: Number of array elements as smi.
@@ -6811,8 +6783,10 @@
   __ movq(rbx, MemOperand(rbp, parameter_count_offset));
   masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
   __ pop(rcx);
-  __ lea(rsp, MemOperand(rsp, rbx, times_pointer_size,
-                         extra_expression_stack_count_ * kPointerSize));
+  int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
+      ? kPointerSize
+      : 0;
+  __ lea(rsp, MemOperand(rsp, rbx, times_pointer_size, additional_offset));
   __ jmp(rcx);  // Return to IC Miss stub, continuation still on stack.
 }
 
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index ec66127..6f32f7c 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -347,7 +347,7 @@
   // Allocate new backing store.
   __ bind(&new_backing_store);
   __ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
-  __ AllocateInNewSpace(rdi, r14, r11, r15, fail, TAG_OBJECT);
+  __ Allocate(rdi, r14, r11, r15, fail, TAG_OBJECT);
   // Set backing store's map
   __ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
   __ movq(FieldOperand(r14, HeapObject::kMapOffset), rdi);
@@ -435,7 +435,7 @@
   // r8 : source FixedDoubleArray
   // r9 : number of elements
   __ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
-  __ AllocateInNewSpace(rdi, r11, r14, r15, &gc_required, TAG_OBJECT);
+  __ Allocate(rdi, r11, r14, r15, &gc_required, TAG_OBJECT);
   // r11: destination FixedArray
   __ LoadRoot(rdi, Heap::kFixedArrayMapRootIndex);
   __ movq(FieldOperand(r11, HeapObject::kMapOffset), rdi);
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 8ff12df..322479d 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2678,28 +2678,6 @@
 }
 
 
-void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  ASSERT(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  __ JumpIfSmi(rax, if_false);
-  __ CmpObjectType(rax, SYMBOL_TYPE, rbx);
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  Split(equal, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -4271,6 +4249,10 @@
     __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
              Immediate(1 << Map::kIsUndetectable));
     Split(zero, if_true, if_false, fall_through);
+  } else if (check->Equals(isolate()->heap()->symbol_string())) {
+    __ JumpIfSmi(rax, if_false);
+    __ CmpObjectType(rax, SYMBOL_TYPE, rdx);
+    Split(equal, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->boolean_string())) {
     __ CompareRoot(rax, Heap::kTrueValueRootIndex);
     __ j(equal, if_true);
@@ -4302,10 +4284,6 @@
       __ CompareRoot(rax, Heap::kNullValueRootIndex);
       __ j(equal, if_true);
     }
-    if (FLAG_harmony_symbols) {
-      __ CmpObjectType(rax, SYMBOL_TYPE, rdx);
-      __ j(equal, if_true);
-    }
     __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx);
     __ j(below, if_false);
     __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index b9bd30b..817a9d3 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1574,13 +1574,6 @@
 }
 
 
-void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
-  Register result = ToRegister(instr->result());
-  Register array = ToRegister(instr->value());
-  __ movq(result, FieldOperand(array, JSArray::kLengthOffset));
-}
-
-
 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
   Register result = ToRegister(instr->result());
   Register array = ToRegister(instr->value());
@@ -5129,7 +5122,7 @@
     __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
-    __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
+    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   }
 
   __ bind(deferred->exit());
@@ -5538,6 +5531,11 @@
              Immediate(1 << Map::kIsUndetectable));
     final_branch_condition = zero;
 
+  } else if (type_name->Equals(heap()->symbol_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ CmpObjectType(input, SYMBOL_TYPE, input);
+    final_branch_condition = equal;
+
   } else if (type_name->Equals(heap()->boolean_string())) {
     __ CompareRoot(input, Heap::kTrueValueRootIndex);
     __ j(equal, true_label);
@@ -5572,13 +5570,7 @@
       __ CompareRoot(input, Heap::kNullValueRootIndex);
       __ j(equal, true_label);
     }
-    if (FLAG_harmony_symbols) {
-      __ CmpObjectType(input, SYMBOL_TYPE, input);
-      __ j(equal, true_label);
-      __ CmpInstanceType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    } else {
-      __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
-    }
+    __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
     __ j(below, false_label);
     __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
     __ j(above, false_label);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 16248ee..9a3166e 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -879,6 +879,35 @@
   LInstruction* instr = current->CompileToLithium(this);
 
   if (instr != NULL) {
+#if DEBUG
+    // Make sure that the lithium instruction has either no fixed register
+    // constraints in temps or the result OR no uses that are only used at
+    // start. If this invariant doesn't hold, the register allocator can decide
+    // to insert a split of a range immediately before the instruction due to an
+    // already allocated register needing to be used for the instruction's fixed
+    // register constraint. In this case, The register allocator won't see an
+    // interference between the split child and the use-at-start (it would if
+    // the it was just a plain use), so it is free to move the split child into
+    // the same register that is used for the use-at-start.
+    // See https://code.google.com/p/chromium/issues/detail?id=201590
+    if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+      int fixed = 0;
+      int used_at_start = 0;
+      for (UseIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->IsUsedAtStart()) ++used_at_start;
+      }
+      if (instr->Output() != NULL) {
+        if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
+      }
+      for (TempIterator it(instr); !it.Done(); it.Advance()) {
+        LUnallocated* operand = LUnallocated::cast(it.Current());
+        if (operand->HasFixedPolicy()) ++fixed;
+      }
+      ASSERT(fixed == 0 || used_at_start == 0);
+    }
+#endif
+
     if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
       instr = AssignPointerMap(instr);
     }
@@ -1632,12 +1661,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
-  LOperand* array = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LJSArrayLength(array));
-}
-
-
 LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
     HFixedArrayBaseLength* instr) {
   LOperand* array = UseRegisterAtStart(instr->value());
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 9e3e836..051f9a4 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -121,7 +121,6 @@
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
-  V(JSArrayLength)                              \
   V(Label)                                      \
   V(LazyBailout)                                \
   V(LoadContextSlot)                            \
@@ -1109,19 +1108,6 @@
 };
 
 
-class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LJSArrayLength(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  LOperand* value() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
-  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
-};
-
-
 class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LFixedArrayBaseLength(LOperand* value) {
@@ -2034,7 +2020,7 @@
 };
 
 
-class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
+class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> {
  public:
   LTransitionElementsKind(LOperand* object,
                           LOperand* new_map_temp,
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 9ecf66c..6c1c19d 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -3830,16 +3830,15 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(int header_size,
-                                        ScaleFactor element_size,
-                                        Register element_count,
-                                        Register result,
-                                        Register result_end,
-                                        Register scratch,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(int header_size,
+                              ScaleFactor element_size,
+                              Register element_count,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & SIZE_IN_WORDS) == 0);
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3866,15 +3865,15 @@
   }
 
   // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
 
   // We assume that element_count*element_size + header_size does not
   // overflow.
   lea(result_end, Operand(element_count, element_size, header_size));
   addq(result_end, result);
   j(carry, gc_required);
-  Operand limit_operand = ExternalOperand(new_space_allocation_limit);
+  Operand limit_operand = ExternalOperand(allocation_limit);
   cmpq(result_end, limit_operand);
   j(above, gc_required);
 
@@ -3889,14 +3888,13 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(Register object_size,
-                                        Register result,
-                                        Register result_end,
-                                        Register scratch,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(Register object_size,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
-  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3916,14 +3914,14 @@
   LoadAllocationTopHelper(result, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
   if (!object_size.is(result_end)) {
     movq(result_end, object_size);
   }
   addq(result_end, result);
   j(carry, gc_required);
-  Operand limit_operand = ExternalOperand(new_space_allocation_limit);
+  Operand limit_operand = ExternalOperand(allocation_limit);
   cmpq(result_end, limit_operand);
   j(above, gc_required);
 
@@ -3991,14 +3989,14 @@
   }
 
   // Allocate two byte string in new space.
-  AllocateInNewSpace(SeqTwoByteString::kHeaderSize,
-                     times_1,
-                     scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SeqTwoByteString::kHeaderSize,
+           times_1,
+           scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   LoadRoot(kScratchRegister, Heap::kStringMapRootIndex);
@@ -4029,14 +4027,14 @@
   }
 
   // Allocate ASCII string in new space.
-  AllocateInNewSpace(SeqOneByteString::kHeaderSize,
-                     times_1,
-                     scratch1,
-                     result,
-                     scratch2,
-                     scratch3,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SeqOneByteString::kHeaderSize,
+           times_1,
+           scratch1,
+           result,
+           scratch2,
+           scratch3,
+           gc_required,
+           TAG_OBJECT);
 
   // Set the map, length and hash field.
   LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex);
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index df52159..3381a5b 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1042,21 +1042,21 @@
                 Label* gc_required,
                 AllocationFlags flags);
 
-  void AllocateInNewSpace(int header_size,
-                          ScaleFactor element_size,
-                          Register element_count,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(int header_size,
+                ScaleFactor element_size,
+                Register element_count,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
-  void AllocateInNewSpace(Register object_size,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(Register object_size,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. Make sure that no pointers are left to the
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 69d7a91..7e900db 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -716,7 +716,7 @@
 // but may be destroyed if store is successful.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Handle<JSObject> object,
-                                      int index,
+                                      LookupResult* lookup,
                                       Handle<Map> transition,
                                       Handle<Name> name,
                                       Register receiver_reg,
@@ -726,16 +726,6 @@
                                       Register scratch2,
                                       Label* miss_label,
                                       Label* miss_restore_name) {
-  LookupResult lookup(masm->isolate());
-  object->Lookup(*name, &lookup);
-  if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
-    // In sloppy mode, we could just return the value and be done. However, we
-    // might be in strict mode, where we have to throw. Since we cannot tell,
-    // go into slow case unconditionally.
-    __ jmp(miss_label);
-    return;
-  }
-
   // Check that the map of the object hasn't changed.
   CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
                                              : REQUIRE_EXACT_MAP;
@@ -750,8 +740,9 @@
   // Check that we are allowed to write this.
   if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
     JSObject* holder;
-    if (lookup.IsFound()) {
-      holder = lookup.holder();
+    // holder == object indicates that no property was found.
+    if (lookup->holder() != *object) {
+      holder = lookup->holder();
     } else {
       // Find the top object.
       holder = *object;
@@ -759,8 +750,19 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, miss_restore_name);
+    Register holder_reg = CheckPrototypes(
+        object, receiver_reg, Handle<JSObject>(holder), name_reg,
+        scratch1, scratch2, name, miss_restore_name);
+    // If no property was found, and the holder (the last object in the
+    // prototype chain) is in slow mode, we need to do a negative lookup on the
+    // holder.
+    if (lookup->holder() == *object &&
+        !holder->HasFastProperties() &&
+        !holder->IsJSGlobalProxy() &&
+        !holder->IsJSGlobalObject()) {
+      GenerateDictionaryNegativeLookup(
+          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    }
   }
 
   // Stub never generated for non-global objects that require access
@@ -784,6 +786,7 @@
     return;
   }
 
+  int index;
   if (!transition.is_null()) {
     // Update the map of the object.
     __ Move(scratch1, transition);
@@ -798,6 +801,10 @@
                         kDontSaveFPRegs,
                         OMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
+    index = transition->instance_descriptors()->GetFieldIndex(
+        transition->LastAdded());
+  } else {
+    index = lookup->GetFieldIndex().field_index();
   }
 
   // Adjust for the number of properties stored in the object. Even in the
@@ -2174,6 +2181,12 @@
       // Check that the object is a symbol.
       __ CmpObjectType(rdx, SYMBOL_TYPE, rax);
       __ j(not_equal, &miss);
+      // Check that the maps starting from the prototype haven't changed.
+      GenerateDirectLoadGlobalFunctionPrototype(
+          masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss);
+      CheckPrototypes(
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+          rax, holder, rbx, rdx, rdi, name, &miss);
       break;
 
     case NUMBER_CHECK: {