Version 3.20.1

Implemented WeakMap.prototype.clear function. (issue 2753)

Ensure CheckInitialized is present independent of define. (Chromium issue 255779)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@15448 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index edffca1..ee80579 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2092,13 +2092,12 @@
 v8::TryCatch::TryCatch()
     : isolate_(i::Isolate::Current()),
       next_(isolate_->try_catch_handler_address()),
-      exception_(isolate_->heap()->the_hole_value()),
-      message_(i::Smi::FromInt(0)),
       is_verbose_(false),
       can_continue_(true),
       capture_message_(true),
       rethrow_(false),
       has_terminated_(false) {
+  Reset();
   isolate_->RegisterTryCatchHandler(this);
 }
 
@@ -2108,8 +2107,17 @@
   if (rethrow_) {
     v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate_));
     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
+    if (HasCaught() && capture_message_) {
+      // If an exception was caught and rethrow_ is indicated, the saved
+      // message, script, and location need to be restored to Isolate TLS
+      // for reuse.  capture_message_ needs to be disabled so that DoThrow()
+      // does not create a new message.
+      isolate_->thread_local_top()->rethrowing_message_ = true;
+      isolate_->RestorePendingMessageFromTryCatch(this);
+    }
     isolate_->UnregisterTryCatchHandler(this);
     v8::ThrowException(exc);
+    ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
   } else {
     isolate_->UnregisterTryCatchHandler(this);
   }
@@ -2170,8 +2178,9 @@
 
 v8::Local<v8::Message> v8::TryCatch::Message() const {
   ASSERT(isolate_ == i::Isolate::Current());
-  if (HasCaught() && message_ != i::Smi::FromInt(0)) {
-    i::Object* message = reinterpret_cast<i::Object*>(message_);
+  i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
+  ASSERT(message->IsJSMessageObject() || message->IsTheHole());
+  if (HasCaught() && !message->IsTheHole()) {
     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
   } else {
     return v8::Local<v8::Message>();
@@ -2181,8 +2190,12 @@
 
 void v8::TryCatch::Reset() {
   ASSERT(isolate_ == i::Isolate::Current());
-  exception_ = isolate_->heap()->the_hole_value();
-  message_ = i::Smi::FromInt(0);
+  i::Object* the_hole = isolate_->heap()->the_hole_value();
+  exception_ = the_hole;
+  message_obj_ = the_hole;
+  message_script_ = the_hole;
+  message_start_pos_ = 0;
+  message_end_pos_ = 0;
 }
 
 
@@ -2921,14 +2934,12 @@
 }
 
 
-#ifdef V8_ENABLE_CHECKS
-void i::Internals::CheckInitialized(v8::Isolate* external_isolate) {
+void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
   ApiCheck(isolate != NULL && isolate->IsInitialized() && !i::V8::IsDead(),
            "v8::internal::Internals::CheckInitialized()",
            "Isolate is not initialized or V8 has died");
 }
-#endif
 
 
 void External::CheckCast(v8::Value* that) {
@@ -7315,6 +7326,15 @@
 }
 
 
+int CpuProfileNode::GetScriptId() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptId");
+  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+  const i::CodeEntry* entry = node->entry();
+  return entry->script_id();
+}
+
+
 Handle<String> CpuProfileNode::GetScriptResourceName() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index c6ea600..89c0a3b 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -36,7 +36,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "arm/assembler-arm-inl.h"
 #include "serialize.h"
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 6b3caf3..69ba00a 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "codegen.h"
 #include "debug.h"
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 8e9237c..6af5cce 100755
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "bootstrapper.h"
 #include "code-stubs.h"
@@ -3077,7 +3077,7 @@
   __ mov(r0, Operand(r4));
   __ mov(r1, Operand(r6));
 
-#if defined(V8_HOST_ARCH_ARM)
+#if V8_HOST_ARCH_ARM
   int frame_alignment = MacroAssembler::ActivationFrameAlignment();
   int frame_alignment_mask = frame_alignment - 1;
   if (FLAG_debug_code) {
@@ -7125,7 +7125,7 @@
     __ and_(sp, sp, Operand(-frame_alignment));
   }
 
-#if defined(V8_HOST_ARCH_ARM)
+#if V8_HOST_ARCH_ARM
   int32_t entry_hook =
       reinterpret_cast<int32_t>(masm->isolate()->function_entry_hook());
   __ mov(ip, Operand(entry_hook));
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 5b2980a..60de5fc 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "codegen.h"
 #include "macro-assembler.h"
diff --git a/src/arm/constants-arm.cc b/src/arm/constants-arm.cc
index a130484..7d59a84 100644
--- a/src/arm/constants-arm.cc
+++ b/src/arm/constants-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "constants-arm.h"
 
diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc
index 101cd9f..8766a24 100644
--- a/src/arm/cpu-arm.cc
+++ b/src/arm/cpu-arm.cc
@@ -32,7 +32,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "cpu.h"
 #include "macro-assembler.h"
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
index 2f0a7c4..7faea08 100644
--- a/src/arm/debug-arm.cc
+++ b/src/arm/debug-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "codegen.h"
 #include "debug.h"
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index f55552d..6101bec 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -56,7 +56,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "constants-arm.h"
 #include "disasm.h"
diff --git a/src/arm/frames-arm.cc b/src/arm/frames-arm.cc
index 72fc5ce..b207180 100644
--- a/src/arm/frames-arm.cc
+++ b/src/arm/frames-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "assembler.h"
 #include "assembler-arm.h"
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 357f0af..41f02be 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "code-stubs.h"
 #include "codegen.h"
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index cc78151..89ebfde 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "assembler-arm.h"
 #include "code-stubs.h"
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index fb379e2..9e4dc40 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -29,7 +29,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "bootstrapper.h"
 #include "codegen.h"
@@ -985,19 +985,19 @@
 
 
 int MacroAssembler::ActivationFrameAlignment() {
-#if defined(V8_HOST_ARCH_ARM)
+#if V8_HOST_ARCH_ARM
   // Running on the real platform. Use the alignment as mandated by the local
   // environment.
   // Note: This will break if we ever start generating snapshots on one ARM
   // platform for another ARM platform with a different alignment.
   return OS::ActivationFrameAlignment();
-#else  // defined(V8_HOST_ARCH_ARM)
+#else  // V8_HOST_ARCH_ARM
   // If we are using the simulator then we should always align to the expected
   // alignment. As the simulator is used to generate snapshots we do not know
   // if the target platform will need alignment, so this is controlled from a
   // flag.
   return FLAG_sim_stack_alignment;
-#endif  // defined(V8_HOST_ARCH_ARM)
+#endif  // V8_HOST_ARCH_ARM
 }
 
 
@@ -3403,7 +3403,7 @@
   // Make sure that the stack is aligned before calling a C function unless
   // running in the simulator. The simulator has its own alignment check which
   // provides more information.
-#if defined(V8_HOST_ARCH_ARM)
+#if V8_HOST_ARCH_ARM
   if (emit_debug_code()) {
     int frame_alignment = OS::ActivationFrameAlignment();
     int frame_alignment_mask = frame_alignment - 1;
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index f05cba5..0acb737 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "unicode.h"
 #include "log.h"
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index a29d461..238632a 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -30,7 +30,7 @@
 #include <cstdarg>
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "disasm.h"
 #include "assembler.h"
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 21cb802..c154f9a 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_ARM
 
 #include "ic-inl.h"
 #include "codegen.h"
diff --git a/src/assembler.cc b/src/assembler.cc
index 626fd4f..b669e09 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -1308,7 +1308,7 @@
 ExternalReference ExternalReference::re_check_stack_guard_state(
     Isolate* isolate) {
   Address function;
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState);
 #elif V8_TARGET_ARCH_IA32
   function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState);
diff --git a/src/ast.h b/src/ast.h
index 6336b3a..b9a98e0 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1884,6 +1884,9 @@
   BailoutId RightId() const { return right_id_; }
 
   TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
+  // TODO(rossberg): result_type should be subsumed by lower_type.
+  Handle<Type> result_type() const { return result_type_; }
+  void set_result_type(Handle<Type> type) { result_type_ = type; }
   Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
   void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; }
 
@@ -1910,6 +1913,7 @@
   Expression* right_;
   int pos_;
 
+  Handle<Type> result_type_;
   // TODO(rossberg): the fixed arg should probably be represented as a Constant
   // type for the RHS.
   Maybe<int> fixed_right_arg_;
diff --git a/src/atomicops.h b/src/atomicops.h
index ebca91d..b18b54d 100644
--- a/src/atomicops.h
+++ b/src/atomicops.h
@@ -154,17 +154,17 @@
 #if defined(THREAD_SANITIZER)
 #include "atomicops_internals_tsan.h"
 #elif defined(_MSC_VER) && \
-  (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64))
+  (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
 #include "atomicops_internals_x86_msvc.h"
 #elif defined(__APPLE__) && \
-  (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64))
+  (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
 #include "atomicops_internals_x86_macosx.h"
 #elif defined(__GNUC__) && \
-  (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64))
+  (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
 #include "atomicops_internals_x86_gcc.h"
-#elif defined(__GNUC__) && defined(V8_HOST_ARCH_ARM)
+#elif defined(__GNUC__) && V8_HOST_ARCH_ARM
 #include "atomicops_internals_arm_gcc.h"
-#elif defined(__GNUC__) && defined(V8_HOST_ARCH_MIPS)
+#elif defined(__GNUC__) && V8_HOST_ARCH_MIPS
 #include "atomicops_internals_mips_gcc.h"
 #else
 #error "Atomic operations are not supported on your platform"
diff --git a/src/code-stubs.h b/src/code-stubs.h
index c7076b6..d197c84 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -95,7 +95,7 @@
   V(KeyedLoadField)
 
 // List of code stubs only used on ARM platforms.
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
 #define CODE_STUB_LIST_ARM(V)  \
   V(GetProperty)               \
   V(SetProperty)               \
@@ -107,7 +107,7 @@
 #endif
 
 // List of code stubs only used on MIPS platforms.
-#ifdef V8_TARGET_ARCH_MIPS
+#if V8_TARGET_ARCH_MIPS
 #define CODE_STUB_LIST_MIPS(V)  \
   V(RegExpCEntry)               \
   V(DirectCEntry)
diff --git a/src/collection.js b/src/collection.js
index 950c7e7..c5604ab 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -295,6 +295,16 @@
 }
 
 
+function WeakMapClear() {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['WeakMap.prototype.clear', this]);
+  }
+  // Replace the internal table with a new empty table.
+  %WeakMapInitialize(this);
+}
+
+
 // -------------------------------------------------------------------
 
 function SetUpWeakMap() {
@@ -309,7 +319,8 @@
     "get", WeakMapGet,
     "set", WeakMapSet,
     "has", WeakMapHas,
-    "delete", WeakMapDelete
+    "delete", WeakMapDelete,
+    "clear", WeakMapClear
   ));
 }
 
diff --git a/src/cpu-profiler-inl.h b/src/cpu-profiler-inl.h
index 4982197..c3cc27c 100644
--- a/src/cpu-profiler-inl.h
+++ b/src/cpu-profiler-inl.h
@@ -56,6 +56,17 @@
 }
 
 
+void ReportBuiltinEventRecord::UpdateCodeMap(CodeMap* code_map) {
+  CodeEntry* entry = code_map->FindEntry(start);
+  if (!entry) {
+    // Code objects for builtins should already have been added to the map but
+    // some of them have been filtered out by CpuProfiler.
+    return;
+  }
+  entry->SetBuiltinId(builtin_id);
+}
+
+
 TickSample* ProfilerEventsProcessor::TickSampleEvent() {
   generator_->Tick();
   TickSampleEventRecord* evt =
@@ -64,16 +75,6 @@
 }
 
 
-bool ProfilerEventsProcessor::FilterOutCodeCreateEvent(
-    Logger::LogEventsAndTags tag) {
-  return FLAG_prof_browser_mode
-      && (tag != Logger::CALLBACK_TAG
-          && tag != Logger::FUNCTION_TAG
-          && tag != Logger::LAZY_COMPILE_TAG
-          && tag != Logger::REG_EXP_TAG
-          && tag != Logger::SCRIPT_TAG);
-}
-
 } }  // namespace v8::internal
 
 #endif  // V8_CPU_PROFILER_INL_H_
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 109ddd5..be64dd7 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -45,11 +45,9 @@
 static const int kProfilerStackSize = 64 * KB;
 
 
-ProfilerEventsProcessor::ProfilerEventsProcessor(
-    ProfileGenerator* generator, CpuProfilesCollection* profiles)
+ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
     : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
       generator_(generator),
-      profiles_(profiles),
       running_(true),
       ticks_buffer_(sizeof(TickSampleEventRecord),
                     kTickSamplesBufferChunkSize,
@@ -58,120 +56,9 @@
 }
 
 
-void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
-                                                  const char* prefix,
-                                                  Name* name,
-                                                  Address start) {
-  if (FilterOutCodeCreateEvent(tag)) return;
-  CodeEventsContainer evt_rec;
-  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
-  rec->type = CodeEventRecord::CODE_CREATION;
-  rec->order = ++enqueue_order_;
-  rec->start = start;
-  rec->entry = profiles_->NewCodeEntry(tag, prefix, name);
-  rec->size = 1;
-  rec->shared = NULL;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                                              Name* name,
-                                              String* resource_name,
-                                              int line_number,
-                                              Address start,
-                                              unsigned size,
-                                              Address shared,
-                                              CompilationInfo* info) {
-  if (FilterOutCodeCreateEvent(tag)) return;
-  CodeEventsContainer evt_rec;
-  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
-  rec->type = CodeEventRecord::CODE_CREATION;
-  rec->order = ++enqueue_order_;
-  rec->start = start;
-  rec->entry = profiles_->NewCodeEntry(tag, name, resource_name, line_number);
-  if (info) {
-    rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
-  }
-  rec->size = size;
-  rec->shared = shared;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                                              const char* name,
-                                              Address start,
-                                              unsigned size) {
-  if (FilterOutCodeCreateEvent(tag)) return;
-  CodeEventsContainer evt_rec;
-  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
-  rec->type = CodeEventRecord::CODE_CREATION;
-  rec->order = ++enqueue_order_;
-  rec->start = start;
-  rec->entry = profiles_->NewCodeEntry(tag, name);
-  rec->size = size;
-  rec->shared = NULL;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                                              int args_count,
-                                              Address start,
-                                              unsigned size) {
-  if (FilterOutCodeCreateEvent(tag)) return;
-  CodeEventsContainer evt_rec;
-  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
-  rec->type = CodeEventRecord::CODE_CREATION;
-  rec->order = ++enqueue_order_;
-  rec->start = start;
-  rec->entry = profiles_->NewCodeEntry(tag, args_count);
-  rec->size = size;
-  rec->shared = NULL;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
-  CodeEventsContainer evt_rec;
-  CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
-  rec->type = CodeEventRecord::CODE_MOVE;
-  rec->order = ++enqueue_order_;
-  rec->from = from;
-  rec->to = to;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
-                                                          Address to) {
-  CodeEventsContainer evt_rec;
-  SharedFunctionInfoMoveEventRecord* rec =
-      &evt_rec.SharedFunctionInfoMoveEventRecord_;
-  rec->type = CodeEventRecord::SHARED_FUNC_MOVE;
-  rec->order = ++enqueue_order_;
-  rec->from = from;
-  rec->to = to;
-  events_buffer_.Enqueue(evt_rec);
-}
-
-
-void ProfilerEventsProcessor::RegExpCodeCreateEvent(
-    Logger::LogEventsAndTags tag,
-    const char* prefix,
-    String* name,
-    Address start,
-    unsigned size) {
-  if (FilterOutCodeCreateEvent(tag)) return;
-  CodeEventsContainer evt_rec;
-  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
-  rec->type = CodeEventRecord::CODE_CREATION;
-  rec->order = ++enqueue_order_;
-  rec->start = start;
-  rec->entry = profiles_->NewCodeEntry(tag, prefix, name);
-  rec->size = size;
-  events_buffer_.Enqueue(evt_rec);
+void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
+  event.generic.order = ++enqueue_order_;
+  events_buffer_.Enqueue(event);
 }
 
 
@@ -305,30 +192,56 @@
 }
 
 
+static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag) {
+  return FLAG_prof_browser_mode
+      && (tag != Logger::CALLBACK_TAG
+          && tag != Logger::FUNCTION_TAG
+          && tag != Logger::LAZY_COMPILE_TAG
+          && tag != Logger::REG_EXP_TAG
+          && tag != Logger::SCRIPT_TAG);
+}
+
+
 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) {
-  processor_->CallbackCreateEvent(
-      Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
+  if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = entry_point;
+  rec->entry = profiles_->NewCodeEntry(
+      Logger::CALLBACK_TAG,
+      profiles_->GetName(name),
+      TokenEnumerator::kInheritsSecurityToken);
+  rec->size = 1;
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                           Code* code, const char* comment) {
-  processor_->CodeCreateEvent(
-      tag, comment, code->address(), code->ExecutableSize());
+                                  Code* code,
+                                  const char* name) {
+  if (FilterOutCodeCreateEvent(tag)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
+  rec->size = code->ExecutableSize();
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                           Code* code, Name* name) {
-  processor_->CodeCreateEvent(
-      tag,
-      name,
-      isolate_->heap()->empty_string(),
-      v8::CpuProfileNode::kNoLineNumberInfo,
-      code->address(),
-      code->ExecutableSize(),
-      NULL,
-      NULL);
+                                  Code* code,
+                                  Name* name) {
+  if (FilterOutCodeCreateEvent(tag)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
+  rec->size = code->ExecutableSize();
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
@@ -337,15 +250,22 @@
                                   SharedFunctionInfo* shared,
                                   CompilationInfo* info,
                                   Name* name) {
-  processor_->CodeCreateEvent(
-      tag,
-      name,
-      isolate_->heap()->empty_string(),
-      v8::CpuProfileNode::kNoLineNumberInfo,
-      code->address(),
-      code->ExecutableSize(),
-      shared->address(),
-      info);
+  if (FilterOutCodeCreateEvent(tag)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
+  if (info) {
+    rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
+  }
+  if (shared->script()->IsScript()) {
+    ASSERT(Script::cast(shared->script()));
+    Script* script = Script::cast(shared->script());
+    rec->entry->set_script_id(script->id()->value());
+  }
+  rec->size = code->ExecutableSize();
+  rec->shared = shared->address();
+  processor_->Enqueue(evt_rec);
 }
 
 
@@ -354,30 +274,53 @@
                                   SharedFunctionInfo* shared,
                                   CompilationInfo* info,
                                   String* source, int line) {
-  processor_->CodeCreateEvent(
+  if (FilterOutCodeCreateEvent(tag)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(
       tag,
-      shared->DebugName(),
-      source,
-      line,
-      code->address(),
-      code->ExecutableSize(),
-      shared->address(),
-      info);
+      profiles_->GetFunctionName(shared->DebugName()),
+      TokenEnumerator::kNoSecurityToken,
+      CodeEntry::kEmptyNamePrefix,
+      profiles_->GetName(source),
+      line);
+  if (info) {
+    rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
+  }
+  ASSERT(Script::cast(shared->script()));
+  Script* script = Script::cast(shared->script());
+  rec->entry->set_script_id(script->id()->value());
+  rec->size = code->ExecutableSize();
+  rec->shared = shared->address();
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
-                           Code* code, int args_count) {
-  processor_->CodeCreateEvent(
+                                  Code* code,
+                                  int args_count) {
+  if (FilterOutCodeCreateEvent(tag)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(
       tag,
-      args_count,
-      code->address(),
-      code->ExecutableSize());
+      profiles_->GetName(args_count),
+      TokenEnumerator::kInheritsSecurityToken,
+      "args_count: ");
+  rec->size = code->ExecutableSize();
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
-  processor_->CodeMoveEvent(from, to);
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
+  CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
+  rec->from = from;
+  rec->to = to;
+  processor_->Enqueue(evt_rec);
 }
 
 
@@ -386,29 +329,59 @@
 
 
 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
-  processor_->SharedFunctionInfoMoveEvent(from, to);
+  CodeEventsContainer evt_rec(CodeEventRecord::SHARED_FUNC_MOVE);
+  SharedFunctionInfoMoveEventRecord* rec =
+      &evt_rec.SharedFunctionInfoMoveEventRecord_;
+  rec->from = from;
+  rec->to = to;
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
-  processor_->CallbackCreateEvent(
-      Logger::CALLBACK_TAG, "get ", name, entry_point);
+  if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = entry_point;
+  rec->entry = profiles_->NewCodeEntry(
+      Logger::CALLBACK_TAG,
+      profiles_->GetName(name),
+      TokenEnumerator::kInheritsSecurityToken,
+      "get ");
+  rec->size = 1;
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
-  processor_->RegExpCodeCreateEvent(
+  if (FilterOutCodeCreateEvent(Logger::REG_EXP_TAG)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = code->address();
+  rec->entry = profiles_->NewCodeEntry(
       Logger::REG_EXP_TAG,
-      "RegExp: ",
-      source,
-      code->address(),
-      code->ExecutableSize());
+      profiles_->GetName(source),
+      TokenEnumerator::kInheritsSecurityToken,
+      "RegExp: ");
+  rec->size = code->ExecutableSize();
+  processor_->Enqueue(evt_rec);
 }
 
 
 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
-  processor_->CallbackCreateEvent(
-      Logger::CALLBACK_TAG, "set ", name, entry_point);
+  if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
+  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+  rec->start = entry_point;
+  rec->entry = profiles_->NewCodeEntry(
+      Logger::CALLBACK_TAG,
+      profiles_->GetName(name),
+      TokenEnumerator::kInheritsSecurityToken,
+      "set ");
+  rec->size = 1;
+  rec->shared = NULL;
+  processor_->Enqueue(evt_rec);
 }
 
 
@@ -424,7 +397,23 @@
 }
 
 
+CpuProfiler::CpuProfiler(Isolate* isolate,
+                         CpuProfilesCollection* test_profiles,
+                         ProfileGenerator* test_generator,
+                         ProfilerEventsProcessor* test_processor)
+    : isolate_(isolate),
+      profiles_(test_profiles),
+      next_profile_uid_(1),
+      token_enumerator_(new TokenEnumerator()),
+      generator_(test_generator),
+      processor_(test_processor),
+      need_to_stop_sampler_(false),
+      is_profiling_(false) {
+}
+
+
 CpuProfiler::~CpuProfiler() {
+  ASSERT(!is_profiling_);
   delete token_enumerator_;
   delete profiles_;
 }
@@ -450,23 +439,24 @@
 
 void CpuProfiler::StartProcessorIfNotStarted() {
   if (processor_ == NULL) {
+    Logger* logger = isolate_->logger();
     // Disable logging when using the new implementation.
-    saved_logging_nesting_ = isolate_->logger()->logging_nesting_;
-    isolate_->logger()->logging_nesting_ = 0;
+    saved_logging_nesting_ = logger->logging_nesting_;
+    logger->logging_nesting_ = 0;
     generator_ = new ProfileGenerator(profiles_);
-    processor_ = new ProfilerEventsProcessor(generator_, profiles_);
+    processor_ = new ProfilerEventsProcessor(generator_);
     is_profiling_ = true;
     processor_->StartSynchronously();
     // Enumerate stuff we already have in the heap.
-    if (isolate_->heap()->HasBeenSetUp()) {
-      if (!FLAG_prof_browser_mode) {
-        isolate_->logger()->LogCodeObjects();
-      }
-      isolate_->logger()->LogCompiledFunctions();
-      isolate_->logger()->LogAccessorCallbacks();
+    ASSERT(isolate_->heap()->HasBeenSetUp());
+    if (!FLAG_prof_browser_mode) {
+      logger->LogCodeObjects();
     }
+    logger->LogCompiledFunctions();
+    logger->LogAccessorCallbacks();
+    LogBuiltins();
     // Enable stack sampling.
-    Sampler* sampler = isolate_->logger()->sampler();
+    Sampler* sampler = logger->sampler();
     sampler->IncreaseProfilingDepth();
     if (!sampler->IsActive()) {
       sampler->Start();
@@ -525,4 +515,18 @@
 }
 
 
+void CpuProfiler::LogBuiltins() {
+  Builtins* builtins = isolate_->builtins();
+  ASSERT(builtins->is_initialized());
+  for (int i = 0; i < Builtins::builtin_count; i++) {
+    CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
+    ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
+    Builtins::Name id = static_cast<Builtins::Name>(i);
+    rec->start = builtins->builtin(id)->address();
+    rec->builtin_id = id;
+    processor_->Enqueue(evt_rec);
+  }
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 455c893..61d40f0 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -49,7 +49,8 @@
 #define CODE_EVENTS_TYPE_LIST(V)                                   \
   V(CODE_CREATION,    CodeCreateEventRecord)                       \
   V(CODE_MOVE,        CodeMoveEventRecord)                         \
-  V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)
+  V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)           \
+  V(REPORT_BUILTIN,   ReportBuiltinEventRecord)
 
 
 class CodeEventRecord {
@@ -63,7 +64,7 @@
 #undef DECLARE_TYPE
 
   Type type;
-  unsigned order;
+  mutable unsigned order;
 };
 
 
@@ -96,6 +97,15 @@
 };
 
 
+class ReportBuiltinEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  Builtins::Name builtin_id;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
 class TickSampleEventRecord {
  public:
   // The parameterless constructor is used when we dequeue data from
@@ -122,41 +132,34 @@
 };
 
 
+class CodeEventsContainer {
+ public:
+  explicit CodeEventsContainer(
+      CodeEventRecord::Type type = CodeEventRecord::NONE) {
+    generic.type = type;
+  }
+  union  {
+    CodeEventRecord generic;
+#define DECLARE_CLASS(ignore, type) type type##_;
+    CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
+#undef DECLARE_TYPE
+  };
+};
+
+
 // This class implements both the profile events processor thread and
 // methods called by event producers: VM and stack sampler threads.
 class ProfilerEventsProcessor : public Thread {
  public:
-  ProfilerEventsProcessor(ProfileGenerator* generator,
-                          CpuProfilesCollection* profiles);
+  explicit ProfilerEventsProcessor(ProfileGenerator* generator);
   virtual ~ProfilerEventsProcessor() {}
 
   // Thread control.
   virtual void Run();
   inline void Stop() { running_ = false; }
   INLINE(bool running()) { return running_; }
+  void Enqueue(const CodeEventsContainer& event);
 
-  // Events adding methods. Called by VM threads.
-  void CallbackCreateEvent(Logger::LogEventsAndTags tag,
-                           const char* prefix, Name* name,
-                           Address start);
-  void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                       Name* name,
-                       String* resource_name, int line_number,
-                       Address start, unsigned size,
-                       Address shared,
-                       CompilationInfo* info);
-  void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                       const char* name,
-                       Address start, unsigned size);
-  void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                       int args_count,
-                       Address start, unsigned size);
-  void CodeMoveEvent(Address from, Address to);
-  void CodeDeleteEvent(Address from);
-  void SharedFunctionInfoMoveEvent(Address from, Address to);
-  void RegExpCodeCreateEvent(Logger::LogEventsAndTags tag,
-                             const char* prefix, String* name,
-                             Address start, unsigned size);
   // Puts current stack into tick sample events buffer.
   void AddCurrentStack();
 
@@ -167,21 +170,11 @@
   INLINE(TickSample* TickSampleEvent());
 
  private:
-  union CodeEventsContainer {
-    CodeEventRecord generic;
-#define DECLARE_CLASS(ignore, type) type type##_;
-    CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
-#undef DECLARE_TYPE
-  };
-
   // Called from events processing thread (Run() method.)
   bool ProcessCodeEvent(unsigned* dequeue_order);
   bool ProcessTicks(unsigned dequeue_order);
 
-  INLINE(static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag));
-
   ProfileGenerator* generator_;
-  CpuProfilesCollection* profiles_;
   bool running_;
   UnboundQueue<CodeEventsContainer> events_buffer_;
   SamplingCircularQueue ticks_buffer_;
@@ -204,6 +197,12 @@
 class CpuProfiler {
  public:
   explicit CpuProfiler(Isolate* isolate);
+
+  CpuProfiler(Isolate* isolate,
+              CpuProfilesCollection* test_collection,
+              ProfileGenerator* test_generator,
+              ProfilerEventsProcessor* test_processor);
+
   ~CpuProfiler();
 
   void StartProfiling(const char* title, bool record_samples = false);
@@ -257,6 +256,7 @@
   void StopProcessorIfLastProfile(const char* title);
   void StopProcessor();
   void ResetProfiles();
+  void LogBuiltins();
 
   Isolate* isolate_;
   CpuProfilesCollection* profiles_;
diff --git a/src/d8.gyp b/src/d8.gyp
index ea043dc..47a7cc0 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -26,12 +26,13 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 {
-  'includes': ['../build/common.gypi'],
   'variables': {
+    'v8_code': 1,
     'console%': '',
     # Enable support for Intel VTune. Supported on ia32/x64 only
     'v8_enable_vtunejit%': 0,
   },
+  'includes': ['../build/common.gypi'],
   'targets': [
     {
       'target_name': 'd8',
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 7787312..88efbe2 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -71,6 +71,13 @@
                                ScriptName: 1,
                                ScriptRegExp: 2 };
 
+// The different types of breakpoint position alignments.
+// Must match BreakPositionAlignment in debug.h.
+Debug.BreakPositionAlignment = {
+  Statement: 0,
+  BreakPosition: 1
+};
+
 function ScriptTypeFlag(type) {
   return (1 << type);
 }
@@ -251,7 +258,7 @@
 // script name or script id and the break point is represented as line and
 // column.
 function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                          opt_groupId) {
+                          opt_groupId, opt_position_alignment) {
   this.type_ = type;
   if (type == Debug.ScriptBreakPointType.ScriptId) {
     this.script_id_ = script_id_or_name;
@@ -265,6 +272,8 @@
   this.line_ = opt_line || 0;
   this.column_ = opt_column;
   this.groupId_ = opt_groupId;
+  this.position_alignment_ = IS_UNDEFINED(opt_position_alignment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
   this.hit_count_ = 0;
   this.active_ = true;
   this.condition_ = null;
@@ -276,7 +285,8 @@
 //Creates a clone of script breakpoint that is linked to another script.
 ScriptBreakPoint.prototype.cloneForOtherScript = function (other_script) {
   var copy = new ScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
-      other_script.id, this.line_, this.column_, this.groupId_);
+      other_script.id, this.line_, this.column_, this.groupId_,
+      this.position_alignment_);
   copy.number_ = next_break_point_number++;
   script_break_points.push(copy);
 
@@ -443,7 +453,9 @@
   // Create a break point object and set the break point.
   break_point = MakeBreakPoint(position, this);
   break_point.setIgnoreCount(this.ignoreCount());
-  var actual_position = %SetScriptBreakPoint(script, position, break_point);
+  var actual_position = %SetScriptBreakPoint(script, position,
+                                             this.position_alignment_,
+                                             break_point);
   if (IS_UNDEFINED(actual_position)) {
     actual_position = position;
   }
@@ -509,9 +521,11 @@
   %Break();
 };
 
-Debug.breakLocations = function(f) {
+Debug.breakLocations = function(f, opt_position_aligment) {
   if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %GetBreakLocations(f);
+  var position_aligment = IS_UNDEFINED(opt_position_aligment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_aligment;
+  return %GetBreakLocations(f, position_aligment);
 };
 
 // Returns a Script object. If the parameter is a function the return value
@@ -674,7 +688,8 @@
 
 
 Debug.setBreakPointByScriptIdAndPosition = function(script_id, position,
-                                                    condition, enabled)
+                                                    condition, enabled,
+                                                    opt_position_alignment)
 {
   break_point = MakeBreakPoint(position);
   break_point.setCondition(condition);
@@ -682,10 +697,12 @@
     break_point.disable();
   }
   var scripts = this.scripts();
+  var position_alignment = IS_UNDEFINED(opt_position_alignment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
   for (var i = 0; i < scripts.length; i++) {
     if (script_id == scripts[i].id) {
       break_point.actual_position = %SetScriptBreakPoint(scripts[i], position,
-                                                         break_point);
+          position_alignment, break_point);
       break;
     }
   }
@@ -780,11 +797,11 @@
 // specified source line and column within that line.
 Debug.setScriptBreakPoint = function(type, script_id_or_name,
                                      opt_line, opt_column, opt_condition,
-                                     opt_groupId) {
+                                     opt_groupId, opt_position_alignment) {
   // Create script break point object.
   var script_break_point =
       new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                           opt_groupId);
+                           opt_groupId, opt_position_alignment);
 
   // Assign number to the new script break point and add it.
   script_break_point.number_ = next_break_point_number++;
@@ -806,10 +823,12 @@
 
 Debug.setScriptBreakPointById = function(script_id,
                                          opt_line, opt_column,
-                                         opt_condition, opt_groupId) {
+                                         opt_condition, opt_groupId,
+                                         opt_position_alignment) {
   return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
                                   script_id, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
+                                  opt_condition, opt_groupId,
+                                  opt_position_alignment);
 };
 
 
@@ -893,11 +912,11 @@
   return !!%IsBreakOnException(Debug.ExceptionBreak.Uncaught);
 };
 
-Debug.showBreakPoints = function(f, full) {
+Debug.showBreakPoints = function(f, full, opt_position_alignment) {
   if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
   var source = full ? this.scriptSource(f) : this.source(f);
   var offset = full ? this.sourcePosition(f) : 0;
-  var locations = this.breakLocations(f);
+  var locations = this.breakLocations(f, opt_position_alignment);
   if (!locations) return source;
   locations.sort(function(x, y) { return x - y; });
   var result = "";
diff --git a/src/debug.cc b/src/debug.cc
index efb95a0..07c1a0c 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -235,17 +235,30 @@
 
 
 // Find the break point closest to the supplied source position.
-void BreakLocationIterator::FindBreakLocationFromPosition(int position) {
+void BreakLocationIterator::FindBreakLocationFromPosition(int position,
+    BreakPositionAlignment alignment) {
   // Run through all break points to locate the one closest to the source
   // position.
   int closest_break_point = 0;
   int distance = kMaxInt;
+
   while (!Done()) {
+    int next_position;
+    switch (alignment) {
+    case STATEMENT_ALIGNED:
+      next_position = this->statement_position();
+      break;
+    case BREAK_POSITION_ALIGNED:
+      next_position = this->position();
+      break;
+    default:
+      UNREACHABLE();
+      next_position = this->statement_position();
+    }
     // Check if this break point is closer that what was previously found.
-    if (position <= statement_position() &&
-        statement_position() - position < distance) {
+    if (position <= next_position && next_position - position < distance) {
       closest_break_point = break_point();
-      distance = statement_position() - position;
+      distance = next_position - position;
       // Check whether we can't get any closer.
       if (distance == 0) break;
     }
@@ -1190,7 +1203,7 @@
 
   // Find the break point and change it.
   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
-  it.FindBreakLocationFromPosition(*source_position);
+  it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
   it.SetBreakPoint(break_point_object);
 
   *source_position = it.position();
@@ -1202,7 +1215,8 @@
 
 bool Debug::SetBreakPointForScript(Handle<Script> script,
                                    Handle<Object> break_point_object,
-                                   int* source_position) {
+                                   int* source_position,
+                                   BreakPositionAlignment alignment) {
   HandleScope scope(isolate_);
 
   PrepareForBreakPoints();
@@ -1233,7 +1247,7 @@
 
   // Find the break point and change it.
   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
-  it.FindBreakLocationFromPosition(position);
+  it.FindBreakLocationFromPosition(position, alignment);
   it.SetBreakPoint(break_point_object);
 
   *source_position = it.position() + shared->start_position();
@@ -1687,7 +1701,8 @@
 
 // Simple function for returning the source positions for active break points.
 Handle<Object> Debug::GetSourceBreakLocations(
-    Handle<SharedFunctionInfo> shared) {
+    Handle<SharedFunctionInfo> shared,
+    BreakPositionAlignment position_alignment) {
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
   if (!HasDebugInfo(shared)) {
@@ -1705,7 +1720,20 @@
       BreakPointInfo* break_point_info =
           BreakPointInfo::cast(debug_info->break_points()->get(i));
       if (break_point_info->GetBreakPointCount() > 0) {
-        locations->set(count++, break_point_info->statement_position());
+        Smi* position;
+        switch (position_alignment) {
+        case STATEMENT_ALIGNED:
+          position = break_point_info->statement_position();
+          break;
+        case BREAK_POSITION_ALIGNED:
+          position = break_point_info->source_position();
+          break;
+        default:
+          UNREACHABLE();
+          position = break_point_info->statement_position();
+        }
+
+        locations->set(count++, position);
       }
     }
   }
diff --git a/src/debug.h b/src/debug.h
index 209d8db..67debc7 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -79,6 +79,14 @@
 };
 
 
+// The different types of breakpoint position alignments.
+// Must match Debug.BreakPositionAlignment in debug-debugger.js
+enum BreakPositionAlignment {
+  STATEMENT_ALIGNED = 0,
+  BREAK_POSITION_ALIGNED = 1
+};
+
+
 // Class for iterating through the break points in a function and changing
 // them.
 class BreakLocationIterator {
@@ -90,7 +98,8 @@
   void Next();
   void Next(int count);
   void FindBreakLocationFromAddress(Address pc);
-  void FindBreakLocationFromPosition(int position);
+  void FindBreakLocationFromPosition(int position,
+      BreakPositionAlignment alignment);
   void Reset();
   bool Done() const;
   void SetBreakPoint(Handle<Object> break_point_object);
@@ -241,7 +250,8 @@
                      int* source_position);
   bool SetBreakPointForScript(Handle<Script> script,
                               Handle<Object> break_point_object,
-                              int* source_position);
+                              int* source_position,
+                              BreakPositionAlignment alignment);
   void ClearBreakPoint(Handle<Object> break_point_object);
   void ClearAllBreakPoints();
   void FloodWithOneShot(Handle<JSFunction> function);
@@ -284,7 +294,8 @@
   static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode);
 
   static Handle<Object> GetSourceBreakLocations(
-      Handle<SharedFunctionInfo> shared);
+      Handle<SharedFunctionInfo> shared,
+      BreakPositionAlignment position_aligment);
 
   // Getter for the debug_context.
   inline Handle<Context> debug_context() { return debug_context_; }
diff --git a/src/execution.h b/src/execution.h
index 3cdbf63..c6bf63d 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -253,7 +253,7 @@
   void EnableInterrupts();
   void DisableInterrupts();
 
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
   static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8);
 #else
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 91186de..b07354a 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -214,6 +214,7 @@
 DEFINE_bool(use_gvn, true, "use hydrogen global value numbering")
 DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction canonicalizing")
 DEFINE_bool(use_inlining, true, "use function inlining")
+DEFINE_bool(use_escape_analysis, false, "use hydrogen escape analysis")
 DEFINE_int(max_inlined_source_size, 600,
            "maximum source size in bytes considered for a single inlining")
 DEFINE_int(max_inlined_nodes, 196,
@@ -234,6 +235,7 @@
 DEFINE_bool(trace_range, false, "trace range analysis")
 DEFINE_bool(trace_gvn, false, "trace global value numbering")
 DEFINE_bool(trace_representation, false, "trace representation types")
+DEFINE_bool(trace_escape_analysis, false, "trace hydrogen escape analysis")
 DEFINE_bool(trace_track_allocation_sites, false,
             "trace the tracking of allocation sites")
 DEFINE_bool(trace_migration, false, "trace object migration")
diff --git a/src/flags.cc b/src/flags.cc
index 282bf20..855e207 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -34,7 +34,7 @@
 #include "smart-pointers.h"
 #include "string-stream.h"
 
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
 #include "arm/assembler-arm-inl.h"
 #endif
 
@@ -520,7 +520,7 @@
 
 // static
 void FlagList::PrintHelp() {
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
   CpuFeatures::PrintTarget();
   CpuFeatures::Probe();
   CpuFeatures::PrintFeatures();
diff --git a/src/frames.cc b/src/frames.cc
index edd5ddd..e883c98 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -423,7 +423,7 @@
 
 
 Address StackFrame::UnpaddedFP() const {
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
   if (!is_optimized()) return fp();
   int32_t alignment_state = Memory::int32_at(
     fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset);
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 7336261..c1350a1 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -940,6 +940,11 @@
 }
 
 
+void FullCodeGenerator::EmitDebugBreakInOptimizedCode(CallRuntime* expr) {
+  context()->Plug(handle(Smi::FromInt(0), isolate()));
+}
+
+
 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   switch (expr->op()) {
     case Token::COMMA:
diff --git a/src/full-codegen.h b/src/full-codegen.h
index dc5ac6a..7e64506 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -332,7 +332,7 @@
 
   // Helper function to split control flow and avoid a branch to the
   // fall-through label if it is set up.
-#ifdef V8_TARGET_ARCH_MIPS
+#if V8_TARGET_ARCH_MIPS
   void Split(Condition cc,
              Register lhs,
              const Operand&  rhs,
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index dee115c..f4a7c2d 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -217,7 +217,7 @@
 struct MachOSectionHeader {
   char sectname[16];
   char segname[16];
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
   uint32_t addr;
   uint32_t size;
 #else
@@ -525,7 +525,7 @@
     uint32_t ncmds;
     uint32_t sizeofcmds;
     uint32_t flags;
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
     uint32_t reserved;
 #endif
   };
@@ -534,7 +534,7 @@
     uint32_t cmd;
     uint32_t cmdsize;
     char segname[16];
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
     uint32_t vmaddr;
     uint32_t vmsize;
     uint32_t fileoff;
@@ -560,11 +560,11 @@
   Writer::Slot<MachOHeader> WriteHeader(Writer* w) {
     ASSERT(w->position() == 0);
     Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
     header->magic = 0xFEEDFACEu;
     header->cputype = 7;  // i386
     header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
     header->magic = 0xFEEDFACFu;
     header->cputype = 7 | 0x01000000;  // i386 | 64-bit ABI
     header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
@@ -585,7 +585,7 @@
                                                         uintptr_t code_size) {
     Writer::Slot<MachOSegmentCommand> cmd =
         w->CreateSlotHere<MachOSegmentCommand>();
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
     cmd->cmd = LC_SEGMENT_32;
 #else
     cmd->cmd = LC_SEGMENT_64;
@@ -672,10 +672,10 @@
   void WriteHeader(Writer* w) {
     ASSERT(w->position() == 0);
     Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
-#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM
     const uint8_t ident[16] =
         { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
     const uint8_t ident[16] =
         { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 #else
@@ -683,14 +683,14 @@
 #endif
     OS::MemCopy(header->ident, ident, 16);
     header->type = 1;
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
     header->machine = 3;
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
     // Processor identification value for x64 is 62 as defined in
     //    System V ABI, AMD64 Supplement
     //    http://www.x86-64.org/documentation/abi.pdf
     header->machine = 62;
-#elif defined(V8_TARGET_ARCH_ARM)
+#elif V8_TARGET_ARCH_ARM
     // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at
     // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf
     header->machine = 40;
@@ -784,7 +784,7 @@
   Binding binding() const {
     return static_cast<Binding>(info >> 4);
   }
-#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
+#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM
   struct SerializedLayout {
     SerializedLayout(uint32_t name,
                      uintptr_t value,
@@ -807,7 +807,7 @@
     uint8_t other;
     uint16_t section;
   };
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
   struct SerializedLayout {
     SerializedLayout(uint32_t name,
                      uintptr_t value,
@@ -921,7 +921,7 @@
 
 class CodeDescription BASE_EMBEDDED {
  public:
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   enum StackState {
     POST_RBP_PUSH,
     POST_RBP_SET,
@@ -984,7 +984,7 @@
         lineinfo_ != NULL;
   }
 
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   uintptr_t GetStackStateStartAddress(StackState state) const {
     ASSERT(state < STACK_STATE_MAX);
     return stack_state_start_addresses_[state];
@@ -1012,7 +1012,7 @@
   GDBJITLineInfo* lineinfo_;
   GDBJITInterface::CodeTag tag_;
   CompilationInfo* info_;
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
 #endif
 };
@@ -1106,13 +1106,13 @@
       w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
       Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
       uintptr_t fb_block_start = w->position();
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
       w->Write<uint8_t>(DW_OP_reg5);  // The frame pointer's here on ia32
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
       w->Write<uint8_t>(DW_OP_reg6);  // and here on x64.
-#elif defined(V8_TARGET_ARCH_ARM)
+#elif V8_TARGET_ARCH_ARM
       UNIMPLEMENTED();
-#elif defined(V8_TARGET_ARCH_MIPS)
+#elif V8_TARGET_ARCH_MIPS
       UNIMPLEMENTED();
 #else
 #error Unsupported target architecture.
@@ -1563,7 +1563,7 @@
 };
 
 
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
 
 class UnwindInfoSection : public DebugSection {
  public:
@@ -1797,7 +1797,7 @@
     obj->AddSection(new(zone) DebugAbbrevSection(desc), zone);
     obj->AddSection(new(zone) DebugLineSection(desc), zone);
   }
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   obj->AddSection(new(zone) UnwindInfoSection(desc), zone);
 #endif
 }
@@ -2015,7 +2015,7 @@
 }
 
 static void AddUnwindInfo(CodeDescription* desc) {
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
   if (desc->tag() == GDBJITInterface::FUNCTION) {
     // To avoid propagating unwinding information through
     // compilation pipeline we use an approximation.
diff --git a/src/globals.h b/src/globals.h
index 573e19a..baacf52 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -105,8 +105,8 @@
 // Target architecture detection. This may be set externally. If not, detect
 // in the same way as the host architecture, that is, target the native
 // environment as presented by the compiler.
-#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_IA32) && \
-    !defined(V8_TARGET_ARCH_ARM) && !defined(V8_TARGET_ARCH_MIPS)
+#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && \
+    !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
 #if defined(_M_X64) || defined(__x86_64__)
 #define V8_TARGET_ARCH_X64 1
 #elif defined(_M_IX86) || defined(__i386__)
@@ -121,18 +121,16 @@
 #endif
 
 // Check for supported combinations of host and target architectures.
-#if defined(V8_TARGET_ARCH_IA32) && !defined(V8_HOST_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32
 #error Target architecture ia32 is only supported on ia32 host
 #endif
-#if defined(V8_TARGET_ARCH_X64) && !defined(V8_HOST_ARCH_X64)
+#if V8_TARGET_ARCH_X64 && !V8_HOST_ARCH_X64
 #error Target architecture x64 is only supported on x64 host
 #endif
-#if (defined(V8_TARGET_ARCH_ARM) && \
-    !(defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_ARM)))
+#if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM))
 #error Target architecture arm is only supported on arm and ia32 host
 #endif
-#if (defined(V8_TARGET_ARCH_MIPS) && \
-    !(defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_MIPS)))
+#if (V8_TARGET_ARCH_MIPS && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_MIPS))
 #error Target architecture mips is only supported on mips and ia32 host
 #endif
 
@@ -140,22 +138,22 @@
 // Setting USE_SIMULATOR explicitly from the build script will force
 // the use of a simulated environment.
 #if !defined(USE_SIMULATOR)
-#if (defined(V8_TARGET_ARCH_ARM) && !defined(V8_HOST_ARCH_ARM))
+#if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM)
 #define USE_SIMULATOR 1
 #endif
-#if (defined(V8_TARGET_ARCH_MIPS) && !defined(V8_HOST_ARCH_MIPS))
+#if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS)
 #define USE_SIMULATOR 1
 #endif
 #endif
 
 // Determine architecture endiannes (we only support little-endian).
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 #define V8_TARGET_LITTLE_ENDIAN 1
-#elif defined(V8_TARGET_ARCH_X64)
+#elif V8_TARGET_ARCH_X64
 #define V8_TARGET_LITTLE_ENDIAN 1
-#elif defined(V8_TARGET_ARCH_ARM)
+#elif V8_TARGET_ARCH_ARM
 #define V8_TARGET_LITTLE_ENDIAN 1
-#elif defined(V8_TARGET_ARCH_MIPS)
+#elif V8_TARGET_ARCH_MIPS
 #define V8_TARGET_LITTLE_ENDIAN 1
 #else
 #error Unknown target architecture endiannes
diff --git a/src/heap.cc b/src/heap.cc
index 6196228..3fac601 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -66,7 +66,7 @@
     : isolate_(NULL),
 // semispace_size_ should be a power of 2 and old_generation_size_ should be
 // a multiple of Page::kPageSize.
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 #define LUMP_OF_MEMORY (2 * MB)
       code_range_size_(512*MB),
 #else
diff --git a/src/heap.h b/src/heap.h
index b3a4205..d254b60 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1955,7 +1955,7 @@
 
   int scan_on_scavenge_pages_;
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
   static const int kMaxObjectSizeInNewSpace = 1024*KB;
 #else
   static const int kMaxObjectSizeInNewSpace = 512*KB;
@@ -2952,6 +2952,10 @@
     for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL;
   }
 
+  ~TranscendentalCache() {
+    for (int i = 0; i < kNumberOfCaches; ++i) delete caches_[i];
+  }
+
   // Used to create an external reference.
   inline Address cache_array_address();
 
diff --git a/src/hydrogen-escape-analysis.cc b/src/hydrogen-escape-analysis.cc
new file mode 100644
index 0000000..e852fb8
--- /dev/null
+++ b/src/hydrogen-escape-analysis.cc
@@ -0,0 +1,66 @@
+// 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.
+
+#include "hydrogen-escape-analysis.h"
+
+namespace v8 {
+namespace internal {
+
+
+void HEscapeAnalysisPhase::CollectIfNoEscapingUses(HInstruction* instr) {
+  for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+    HValue* use = it.value();
+    if (use->HasEscapingOperandAt(it.index())) {
+      if (FLAG_trace_escape_analysis) {
+        PrintF("#%d (%s) escapes through #%d (%s) @%d\n", instr->id(),
+               instr->Mnemonic(), use->id(), use->Mnemonic(), it.index());
+      }
+      return;
+    }
+  }
+  if (FLAG_trace_escape_analysis) {
+    PrintF("#%d (%s) is being captured\n", instr->id(), instr->Mnemonic());
+  }
+  captured_.Add(instr, zone());
+}
+
+
+void HEscapeAnalysisPhase::CollectCapturedValues() {
+  int block_count = graph()->blocks()->length();
+  for (int i = 0; i < block_count; ++i) {
+    HBasicBlock* block = graph()->blocks()->at(i);
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
+      if (instr->IsAllocate() || instr->IsAllocateObject()) {
+        CollectIfNoEscapingUses(instr);
+      }
+    }
+  }
+}
+
+
+} }  // namespace v8::internal
diff --git a/src/hydrogen-escape-analysis.h b/src/hydrogen-escape-analysis.h
new file mode 100644
index 0000000..6ba6e82
--- /dev/null
+++ b/src/hydrogen-escape-analysis.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef V8_HYDROGEN_ESCAPE_ANALYSIS_H_
+#define V8_HYDROGEN_ESCAPE_ANALYSIS_H_
+
+#include "allocation.h"
+#include "hydrogen.h"
+
+namespace v8 {
+namespace internal {
+
+
+class HEscapeAnalysisPhase : public HPhase {
+ public:
+  explicit HEscapeAnalysisPhase(HGraph* graph)
+      : HPhase("H_Escape analysis", graph), captured_(0, zone()) { }
+
+  void Run() {
+    CollectCapturedValues();
+  }
+
+ private:
+  void CollectCapturedValues();
+  void CollectIfNoEscapingUses(HInstruction* instr);
+
+  ZoneList<HValue*> captured_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_HYDROGEN_ESCAPE_ANALYSIS_H_
diff --git a/src/hydrogen-gvn.cc b/src/hydrogen-gvn.cc
index a277da8..7ea2f16 100644
--- a/src/hydrogen-gvn.cc
+++ b/src/hydrogen-gvn.cc
@@ -394,17 +394,16 @@
   for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
     // Compute side effects for the block.
     HBasicBlock* block = graph()->blocks()->at(i);
-    HInstruction* instr = block->first();
     int id = block->block_id();
     GVNFlagSet side_effects;
-    while (instr != NULL) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       side_effects.Add(instr->ChangesFlags());
       if (instr->IsSoftDeoptimize()) {
         block_side_effects_[id].RemoveAll();
         side_effects.RemoveAll();
         break;
       }
-      instr = instr->next();
     }
     block_side_effects_[id].Add(side_effects);
 
diff --git a/src/hydrogen-infer-representation.cc b/src/hydrogen-infer-representation.cc
index 8439ad8..95c3412 100644
--- a/src/hydrogen-infer-representation.cc
+++ b/src/hydrogen-infer-representation.cc
@@ -131,10 +131,9 @@
       AddToWorklist(phis->at(j));
     }
 
-    HInstruction* current = block->first();
-    while (current != NULL) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* current = it.Current();
       AddToWorklist(current);
-      current = current->next();
     }
   }
 
@@ -156,8 +155,8 @@
         phi->ChangeRepresentation(Representation::Tagged());
       }
     }
-    for (HInstruction* current = block->first();
-         current != NULL; current = current->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* current = it.Current();
       if (current->representation().IsNone() &&
           current->CheckFlag(HInstruction::kFlexibleRepresentation)) {
         if (current->CheckFlag(HInstruction::kCannotBeTagged)) {
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 98fa93f..932fd47 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1566,7 +1566,7 @@
       HValue* new_right =
           LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
       if (new_right == NULL &&
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
           CpuFeatures::IsSupported(SUDIV) &&
 #endif
           hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index bb74687..ed6ab15 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1062,6 +1062,9 @@
   void RemoveLastAddedRange();
   void ComputeInitialRange(Zone* zone);
 
+  // Escape analysis helpers.
+  virtual bool HasEscapingOperandAt(int index) { return true; }
+
   // Representation helpers.
   virtual Representation observed_input_representation(int index) {
     return Representation::None();
@@ -1433,6 +1436,7 @@
 
   HValue* value() { return OperandAt(0); }
 
+  virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
   }
@@ -1892,6 +1896,7 @@
   virtual int OperandCount() { return values_.length(); }
   virtual HValue* OperandAt(int index) const { return values_[index]; }
 
+  virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
   }
@@ -2801,6 +2806,7 @@
     return check_map;
   }
 
+  virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
@@ -3228,6 +3234,7 @@
   virtual int OperandCount() { return values_.length(); }
   virtual HValue* OperandAt(int index) const { return values_[index]; }
 
+  virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
   }
@@ -5431,6 +5438,7 @@
   HObjectAccess access() const { return access_; }
   Representation field_representation() const { return representation_; }
 
+  virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
@@ -5763,6 +5771,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
 
+  virtual bool HasEscapingOperandAt(int index) { return index == 1; }
   virtual Representation RequiredInputRepresentation(int index) {
     if (FLAG_track_double_fields &&
         index == 1 && field_representation_.IsDouble()) {
@@ -5895,6 +5904,7 @@
     }
   }
 
+  virtual bool HasEscapingOperandAt(int index) { return index != 0; }
   virtual Representation RequiredInputRepresentation(int index) {
     // kind_fast:       tagged[int32] = tagged
     // kind_double:     tagged[int32] = double
diff --git a/src/hydrogen-uint32-analysis.cc b/src/hydrogen-uint32-analysis.cc
new file mode 100644
index 0000000..67219f5
--- /dev/null
+++ b/src/hydrogen-uint32-analysis.cc
@@ -0,0 +1,231 @@
+// 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.
+
+#include "hydrogen-uint32-analysis.h"
+
+namespace v8 {
+namespace internal {
+
+
+bool HUint32AnalysisPhase::IsSafeUint32Use(HValue* val, HValue* use) {
+  // Operations that operate on bits are safe.
+  if (use->IsBitwise() ||
+      use->IsShl() ||
+      use->IsSar() ||
+      use->IsShr() ||
+      use->IsBitNot()) {
+    return true;
+  } else if (use->IsChange() || use->IsSimulate()) {
+    // Conversions and deoptimization have special support for unt32.
+    return true;
+  } else if (use->IsStoreKeyed()) {
+    HStoreKeyed* store = HStoreKeyed::cast(use);
+    if (store->is_external()) {
+      // Storing a value into an external integer array is a bit level
+      // operation.
+      if (store->value() == val) {
+        // Clamping or a conversion to double should have beed inserted.
+        ASSERT(store->elements_kind() != EXTERNAL_PIXEL_ELEMENTS);
+        ASSERT(store->elements_kind() != EXTERNAL_FLOAT_ELEMENTS);
+        ASSERT(store->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+
+// Iterate over all uses and verify that they are uint32 safe: either don't
+// distinguish between int32 and uint32 due to their bitwise nature or
+// have special support for uint32 values.
+// Encountered phis are optimistically treated as safe uint32 uses,
+// marked with kUint32 flag and collected in the phis_ list. A separate
+// pass will be performed later by UnmarkUnsafePhis to clear kUint32 from
+// phis that are not actually uint32-safe (it requires fix point iteration).
+bool HUint32AnalysisPhase::Uint32UsesAreSafe(HValue* uint32val) {
+  bool collect_phi_uses = false;
+  for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
+    HValue* use = it.value();
+
+    if (use->IsPhi()) {
+      if (!use->CheckFlag(HInstruction::kUint32)) {
+        // There is a phi use of this value from a phi that is not yet
+        // collected in phis_ array. Separate pass is required.
+        collect_phi_uses = true;
+      }
+
+      // Optimistically treat phis as uint32 safe.
+      continue;
+    }
+
+    if (!IsSafeUint32Use(uint32val, use)) {
+      return false;
+    }
+  }
+
+  if (collect_phi_uses) {
+    for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
+      HValue* use = it.value();
+
+      // There is a phi use of this value from a phi that is not yet
+      // collected in phis_ array. Separate pass is required.
+      if (use->IsPhi() && !use->CheckFlag(HInstruction::kUint32)) {
+        use->SetFlag(HInstruction::kUint32);
+        phis_.Add(HPhi::cast(use), zone());
+      }
+    }
+  }
+
+  return true;
+}
+
+
+// Check if all operands to the given phi are marked with kUint32 flag.
+bool HUint32AnalysisPhase::CheckPhiOperands(HPhi* phi) {
+  if (!phi->CheckFlag(HInstruction::kUint32)) {
+    // This phi is not uint32 safe. No need to check operands.
+    return false;
+  }
+
+  for (int j = 0; j < phi->OperandCount(); j++) {
+    HValue* operand = phi->OperandAt(j);
+    if (!operand->CheckFlag(HInstruction::kUint32)) {
+      // Lazily mark constants that fit into uint32 range with kUint32 flag.
+      if (operand->IsInteger32Constant() &&
+          operand->GetInteger32Constant() >= 0) {
+        operand->SetFlag(HInstruction::kUint32);
+        continue;
+      }
+
+      // This phi is not safe, some operands are not uint32 values.
+      return false;
+    }
+  }
+
+  return true;
+}
+
+
+// Remove kUint32 flag from the phi itself and its operands. If any operand
+// was a phi marked with kUint32 place it into a worklist for
+// transitive clearing of kUint32 flag.
+void HUint32AnalysisPhase::UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist) {
+  phi->ClearFlag(HInstruction::kUint32);
+  for (int j = 0; j < phi->OperandCount(); j++) {
+    HValue* operand = phi->OperandAt(j);
+    if (operand->CheckFlag(HInstruction::kUint32)) {
+      operand->ClearFlag(HInstruction::kUint32);
+      if (operand->IsPhi()) {
+        worklist->Add(HPhi::cast(operand), zone());
+      }
+    }
+  }
+}
+
+
+void HUint32AnalysisPhase::UnmarkUnsafePhis() {
+  // No phis were collected. Nothing to do.
+  if (phis_.length() == 0) return;
+
+  // Worklist used to transitively clear kUint32 from phis that
+  // are used as arguments to other phis.
+  ZoneList<HPhi*> worklist(phis_.length(), zone());
+
+  // Phi can be used as a uint32 value if and only if
+  // all its operands are uint32 values and all its
+  // uses are uint32 safe.
+
+  // Iterate over collected phis and unmark those that
+  // are unsafe. When unmarking phi unmark its operands
+  // and add it to the worklist if it is a phi as well.
+  // Phis that are still marked as safe are shifted down
+  // so that all safe phis form a prefix of the phis_ array.
+  int phi_count = 0;
+  for (int i = 0; i < phis_.length(); i++) {
+    HPhi* phi = phis_[i];
+
+    if (CheckPhiOperands(phi) && Uint32UsesAreSafe(phi)) {
+      phis_[phi_count++] = phi;
+    } else {
+      UnmarkPhi(phi, &worklist);
+    }
+  }
+
+  // Now phis array contains only those phis that have safe
+  // non-phi uses. Start transitively clearing kUint32 flag
+  // from phi operands of discovered non-safe phis until
+  // only safe phis are left.
+  while (!worklist.is_empty())  {
+    while (!worklist.is_empty()) {
+      HPhi* phi = worklist.RemoveLast();
+      UnmarkPhi(phi, &worklist);
+    }
+
+    // Check if any operands to safe phis were unmarked
+    // turning a safe phi into unsafe. The same value
+    // can flow into several phis.
+    int new_phi_count = 0;
+    for (int i = 0; i < phi_count; i++) {
+      HPhi* phi = phis_[i];
+
+      if (CheckPhiOperands(phi)) {
+        phis_[new_phi_count++] = phi;
+      } else {
+        UnmarkPhi(phi, &worklist);
+      }
+    }
+    phi_count = new_phi_count;
+  }
+}
+
+
+void HUint32AnalysisPhase::Run() {
+  if (!graph()->has_uint32_instructions()) return;
+
+  ZoneList<HInstruction*>* uint32_instructions = graph()->uint32_instructions();
+  for (int i = 0; i < uint32_instructions->length(); ++i) {
+    // Analyze instruction and mark it with kUint32 if all
+    // its uses are uint32 safe.
+    HInstruction* current = uint32_instructions->at(i);
+    if (current->IsLinked() &&
+        current->representation().IsInteger32() &&
+        Uint32UsesAreSafe(current)) {
+      current->SetFlag(HInstruction::kUint32);
+    }
+  }
+
+  // Some phis might have been optimistically marked with kUint32 flag.
+  // Remove this flag from those phis that are unsafe and propagate
+  // this information transitively potentially clearing kUint32 flag
+  // from some non-phi operations that are used as operands to unsafe phis.
+  UnmarkUnsafePhis();
+}
+
+
+} }  // namespace v8::internal
diff --git a/src/hydrogen-uint32-analysis.h b/src/hydrogen-uint32-analysis.h
new file mode 100644
index 0000000..59739d1
--- /dev/null
+++ b/src/hydrogen-uint32-analysis.h
@@ -0,0 +1,59 @@
+// 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.
+
+#ifndef V8_HYDROGEN_UINT32_ANALYSIS_H_
+#define V8_HYDROGEN_UINT32_ANALYSIS_H_
+
+#include "hydrogen.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Discover instructions that can be marked with kUint32 flag allowing
+// them to produce full range uint32 values.
+class HUint32AnalysisPhase : public HPhase {
+ public:
+  explicit HUint32AnalysisPhase(HGraph* graph)
+      : HPhase("H_Compute safe UInt32 operations", graph), phis_(4, zone()) { }
+
+  void Run();
+
+ private:
+  INLINE(bool IsSafeUint32Use(HValue* val, HValue* use));
+  INLINE(bool Uint32UsesAreSafe(HValue* uint32val));
+  INLINE(bool CheckPhiOperands(HPhi* phi));
+  INLINE(void UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist));
+  INLINE(void UnmarkUnsafePhis());
+
+  ZoneList<HPhi*> phis_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_HYDROGEN_UINT32_ANALYSIS_H_
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index d3b9aa8..432a6bc 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -26,7 +26,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "hydrogen.h"
-#include "hydrogen-gvn.h"
 
 #include <algorithm>
 
@@ -35,7 +34,10 @@
 #include "full-codegen.h"
 #include "hashmap.h"
 #include "hydrogen-environment-liveness.h"
+#include "hydrogen-escape-analysis.h"
 #include "hydrogen-infer-representation.h"
+#include "hydrogen-gvn.h"
+#include "hydrogen-uint32-analysis.h"
 #include "lithium-allocator.h"
 #include "parser.h"
 #include "scopeinfo.h"
@@ -2008,10 +2010,8 @@
   DisallowHeapAllocation no_gc;
   ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
   for (int i = 0; i < blocks()->length(); ++i) {
-    for (HInstruction* instr = blocks()->at(i)->first();
-        instr != NULL;
-        instr = instr->next()) {
-      instr->FinalizeUniqueValueId();
+    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
+      it.Current()->FinalizeUniqueValueId();
     }
   }
 }
@@ -2023,24 +2023,22 @@
   // We must be careful not to set the flag unnecessarily, because GVN
   // cannot identify two instructions when their flag value differs.
   for (int i = 0; i < blocks()->length(); ++i) {
-    HInstruction* instr = blocks()->at(i)->first();
-    while (instr != NULL) {
+    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       if (instr->IsArithmeticBinaryOperation() &&
           instr->representation().IsInteger32() &&
           instr->HasAtLeastOneUseWithFlagAndNoneWithout(
               HInstruction::kTruncatingToInt32)) {
         instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
       }
-      instr = instr->next();
     }
   }
   // Perform actual Canonicalization pass.
   for (int i = 0; i < blocks()->length(); ++i) {
-    HInstruction* instr = blocks()->at(i)->first();
-    while (instr != NULL) {
+    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       HValue* value = instr->Canonicalize();
       if (value != instr) instr->DeleteAndReplaceWith(value);
-      instr = instr->next();
     }
   }
 }
@@ -2415,8 +2413,8 @@
       }
     }
     if (all_predecessors_deoptimizing) nullify = true;
-    for (HInstruction* instr = block->first(); instr != NULL;
-         instr = instr->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       // Leave the basic structure of the graph intact.
       if (instr->IsBlockEntry()) continue;
       if (instr->IsControlInstruction()) continue;
@@ -2628,10 +2626,8 @@
   }
 
   // Go through all instructions of the current block.
-  HInstruction* instr = block->first();
-  while (instr != block->end()) {
-    InferRange(instr);
-    instr = instr->next();
+  for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+    InferRange(it.Current());
   }
 
   // Continue analysis in all dominated blocks.
@@ -2758,13 +2754,11 @@
       HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge();
       HBasicBlock* dominator = back_edge;
       while (true) {
-        HInstruction* instr = dominator->first();
-        while (instr != NULL) {
-          if (instr->IsCall()) {
+        for (HInstructionIterator it(dominator); !it.Done(); it.Advance()) {
+          if (it.Current()->IsCall()) {
             block->loop_information()->stack_check()->Eliminate();
             break;
           }
-          instr = instr->next();
         }
 
         // Done when the loop header is processed.
@@ -2788,8 +2782,8 @@
     // Nasty heuristic: Never remove the first simulate in a block. This
     // just so happens to have a beneficial effect on register allocation.
     bool first = true;
-    for (HInstruction* current = block->first();
-         current != NULL; current = current->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* current = it.Current();
       if (current->IsLeaveInlined()) {
         // Never fold simulates from inlined environments into simulates
         // in the outer environment.
@@ -2856,10 +2850,8 @@
       phis->at(j)->UpdateInferredType();
     }
 
-    HInstruction* current = block->first();
-    while (current != NULL) {
-      current->UpdateInferredType();
-      current = current->next();
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      it.Current()->UpdateInferredType();
     }
 
     if (block->IsLoopHeader()) {
@@ -3087,235 +3079,12 @@
 }
 
 
-// Discover instructions that can be marked with kUint32 flag allowing
-// them to produce full range uint32 values.
-class Uint32Analysis BASE_EMBEDDED {
- public:
-  explicit Uint32Analysis(Zone* zone) : zone_(zone), phis_(4, zone) { }
-
-  void Analyze(HInstruction* current);
-
-  void UnmarkUnsafePhis();
-
- private:
-  bool IsSafeUint32Use(HValue* val, HValue* use);
-  bool Uint32UsesAreSafe(HValue* uint32val);
-  bool CheckPhiOperands(HPhi* phi);
-  void UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist);
-
-  Zone* zone_;
-  ZoneList<HPhi*> phis_;
-};
-
-
-bool Uint32Analysis::IsSafeUint32Use(HValue* val, HValue* use) {
-  // Operations that operatate on bits are safe.
-  if (use->IsBitwise() ||
-      use->IsShl() ||
-      use->IsSar() ||
-      use->IsShr() ||
-      use->IsBitNot()) {
-    return true;
-  } else if (use->IsChange() || use->IsSimulate()) {
-    // Conversions and deoptimization have special support for unt32.
-    return true;
-  } else if (use->IsStoreKeyed()) {
-    HStoreKeyed* store = HStoreKeyed::cast(use);
-    if (store->is_external()) {
-      // Storing a value into an external integer array is a bit level
-      // operation.
-      if (store->value() == val) {
-        // Clamping or a conversion to double should have beed inserted.
-        ASSERT(store->elements_kind() != EXTERNAL_PIXEL_ELEMENTS);
-        ASSERT(store->elements_kind() != EXTERNAL_FLOAT_ELEMENTS);
-        ASSERT(store->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS);
-        return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-
-// Iterate over all uses and verify that they are uint32 safe: either don't
-// distinguish between int32 and uint32 due to their bitwise nature or
-// have special support for uint32 values.
-// Encountered phis are optimisitically treated as safe uint32 uses,
-// marked with kUint32 flag and collected in the phis_ list. A separate
-// path will be performed later by UnmarkUnsafePhis to clear kUint32 from
-// phis that are not actually uint32-safe (it requries fix point iteration).
-bool Uint32Analysis::Uint32UsesAreSafe(HValue* uint32val) {
-  bool collect_phi_uses = false;
-  for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
-    HValue* use = it.value();
-
-    if (use->IsPhi()) {
-      if (!use->CheckFlag(HInstruction::kUint32)) {
-        // There is a phi use of this value from a phis that is not yet
-        // collected in phis_ array. Separate pass is required.
-        collect_phi_uses = true;
-      }
-
-      // Optimistically treat phis as uint32 safe.
-      continue;
-    }
-
-    if (!IsSafeUint32Use(uint32val, use)) {
-      return false;
-    }
-  }
-
-  if (collect_phi_uses) {
-    for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
-      HValue* use = it.value();
-
-      // There is a phi use of this value from a phis that is not yet
-      // collected in phis_ array. Separate pass is required.
-      if (use->IsPhi() && !use->CheckFlag(HInstruction::kUint32)) {
-        use->SetFlag(HInstruction::kUint32);
-        phis_.Add(HPhi::cast(use), zone_);
-      }
-    }
-  }
-
-  return true;
-}
-
-
-// Analyze instruction and mark it with kUint32 if all its uses are uint32
-// safe.
-void Uint32Analysis::Analyze(HInstruction* current) {
-  if (Uint32UsesAreSafe(current)) current->SetFlag(HInstruction::kUint32);
-}
-
-
-// Check if all operands to the given phi are marked with kUint32 flag.
-bool Uint32Analysis::CheckPhiOperands(HPhi* phi) {
-  if (!phi->CheckFlag(HInstruction::kUint32)) {
-    // This phi is not uint32 safe. No need to check operands.
-    return false;
-  }
-
-  for (int j = 0; j < phi->OperandCount(); j++) {
-    HValue* operand = phi->OperandAt(j);
-    if (!operand->CheckFlag(HInstruction::kUint32)) {
-      // Lazyly mark constants that fit into uint32 range with kUint32 flag.
-      if (operand->IsInteger32Constant() &&
-          operand->GetInteger32Constant() >= 0) {
-        operand->SetFlag(HInstruction::kUint32);
-        continue;
-      }
-
-      // This phi is not safe, some operands are not uint32 values.
-      return false;
-    }
-  }
-
-  return true;
-}
-
-
-// Remove kUint32 flag from the phi itself and its operands. If any operand
-// was a phi marked with kUint32 place it into a worklist for
-// transitive clearing of kUint32 flag.
-void Uint32Analysis::UnmarkPhi(HPhi* phi, ZoneList<HPhi*>* worklist) {
-  phi->ClearFlag(HInstruction::kUint32);
-  for (int j = 0; j < phi->OperandCount(); j++) {
-    HValue* operand = phi->OperandAt(j);
-    if (operand->CheckFlag(HInstruction::kUint32)) {
-      operand->ClearFlag(HInstruction::kUint32);
-      if (operand->IsPhi()) {
-        worklist->Add(HPhi::cast(operand), zone_);
-      }
-    }
-  }
-}
-
-
-void Uint32Analysis::UnmarkUnsafePhis() {
-  // No phis were collected. Nothing to do.
-  if (phis_.length() == 0) return;
-
-  // Worklist used to transitively clear kUint32 from phis that
-  // are used as arguments to other phis.
-  ZoneList<HPhi*> worklist(phis_.length(), zone_);
-
-  // Phi can be used as a uint32 value if and only if
-  // all its operands are uint32 values and all its
-  // uses are uint32 safe.
-
-  // Iterate over collected phis and unmark those that
-  // are unsafe. When unmarking phi unmark its operands
-  // and add it to the worklist if it is a phi as well.
-  // Phis that are still marked as safe are shifted down
-  // so that all safe phis form a prefix of the phis_ array.
-  int phi_count = 0;
-  for (int i = 0; i < phis_.length(); i++) {
-    HPhi* phi = phis_[i];
-
-    if (CheckPhiOperands(phi) && Uint32UsesAreSafe(phi)) {
-      phis_[phi_count++] = phi;
-    } else {
-      UnmarkPhi(phi, &worklist);
-    }
-  }
-
-  // Now phis array contains only those phis that have safe
-  // non-phi uses. Start transitively clearing kUint32 flag
-  // from phi operands of discovered non-safe phies until
-  // only safe phies are left.
-  while (!worklist.is_empty())  {
-    while (!worklist.is_empty()) {
-      HPhi* phi = worklist.RemoveLast();
-      UnmarkPhi(phi, &worklist);
-    }
-
-    // Check if any operands to safe phies were unmarked
-    // turning a safe phi into unsafe. The same value
-    // can flow into several phis.
-    int new_phi_count = 0;
-    for (int i = 0; i < phi_count; i++) {
-      HPhi* phi = phis_[i];
-
-      if (CheckPhiOperands(phi)) {
-        phis_[new_phi_count++] = phi;
-      } else {
-        UnmarkPhi(phi, &worklist);
-      }
-    }
-    phi_count = new_phi_count;
-  }
-}
-
-
-void HGraph::ComputeSafeUint32Operations() {
-  HPhase phase("H_Compute safe UInt32 operations", this);
-  if (uint32_instructions_ == NULL) return;
-
-  Uint32Analysis analysis(zone());
-  for (int i = 0; i < uint32_instructions_->length(); ++i) {
-    HInstruction* current = uint32_instructions_->at(i);
-    if (current->IsLinked() && current->representation().IsInteger32()) {
-      analysis.Analyze(current);
-    }
-  }
-
-  // Some phis might have been optimistically marked with kUint32 flag.
-  // Remove this flag from those phis that are unsafe and propagate
-  // this information transitively potentially clearing kUint32 flag
-  // from some non-phi operations that are used as operands to unsafe phis.
-  analysis.UnmarkUnsafePhis();
-}
-
-
 void HGraph::ComputeMinusZeroChecks() {
   HPhase phase("H_Compute minus zero checks", this);
   BitVector visited(GetMaximumValueID(), zone());
   for (int i = 0; i < blocks_.length(); ++i) {
-    for (HInstruction* current = blocks_[i]->first();
-         current != NULL;
-         current = current->next()) {
+    for (HInstructionIterator it(blocks_[i]); !it.Done(); it.Advance()) {
+      HInstruction* current = it.Current();
       if (current->IsChange()) {
         HChange* change = HChange::cast(current);
         // Propagate flags for negative zero checks upwards from conversions
@@ -3821,15 +3590,17 @@
   // Must be performed before canonicalization to ensure that Canonicalize
   // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
   // zero.
-  if (FLAG_opt_safe_uint32_operations) ComputeSafeUint32Operations();
+  if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>();
 
   if (FLAG_use_canonicalizing) Canonicalize();
 
+  if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
+
   if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
 
   if (FLAG_use_range) {
-    HRangeAnalysis rangeAnalysis(this);
-    rangeAnalysis.Analyze();
+    HRangeAnalysis range_analysis(this);
+    range_analysis.Analyze();
   }
   ComputeMinusZeroChecks();
 
@@ -3861,7 +3632,8 @@
     ASSERT(!phi->IsInformativeDefinition());
   }
 
-  for (HInstruction* i = block->first(); i != NULL; i = i->next()) {
+  for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+    HInstruction* i = it.Current();
     i->AddInformativeDefinitions();
     i->SetFlag(HValue::kIDefsProcessingDone);
     i->UpdateRedefinedUsesWhileSettingUpInformativeDefinitions();
@@ -3879,7 +3651,8 @@
     SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i));
   }
 
-  for (HInstruction* i = block->first(); i != NULL; i = i->next()) {
+  for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+    HInstruction* i = it.Current();
     if (i->IsBoundsCheck()) {
       HBoundsCheck* check = HBoundsCheck::cast(i);
       check->ApplyIndexChange();
@@ -4182,7 +3955,8 @@
                                             BoundsCheckTable* table) {
   BoundsCheckBbData* bb_data_list = NULL;
 
-  for (HInstruction* i = bb->first(); i != NULL; i = i->next()) {
+  for (HInstructionIterator it(bb); !it.Done(); it.Advance()) {
+    HInstruction* i = it.Current();
     if (!i->IsBoundsCheck()) continue;
 
     HBoundsCheck* check = HBoundsCheck::cast(i);
@@ -4304,9 +4078,8 @@
 void HGraph::DehoistSimpleArrayIndexComputations() {
   HPhase phase("H_Dehoist index computations", this);
   for (int i = 0; i < blocks()->length(); ++i) {
-    for (HInstruction* instr = blocks()->at(i)->first();
-        instr != NULL;
-        instr = instr->next()) {
+    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       ArrayInstructionInterface* array_instruction = NULL;
       if (instr->IsLoadKeyed()) {
         HLoadKeyed* op = HLoadKeyed::cast(instr);
@@ -4336,9 +4109,8 @@
   // Mark initial root instructions for dead code elimination.
   for (int i = 0; i < blocks()->length(); ++i) {
     HBasicBlock* block = blocks()->at(i);
-    for (HInstruction* instr = block->first();
-         instr != NULL;
-         instr = instr->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       if (instr->CannotBeEliminated()) MarkLive(NULL, instr, &worklist);
     }
     for (int j = 0; j < block->phis()->length(); j++) {
@@ -4384,9 +4156,8 @@
   // Remove any instruction not marked kIsLive.
   for (int i = 0; i < blocks()->length(); ++i) {
     HBasicBlock* block = blocks()->at(i);
-    for (HInstruction* instr = block->first();
-         instr != NULL;
-         instr = instr->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instr = it.Current();
       if (!instr->CheckFlag(HValue::kIsLive)) {
         // Instruction has not been marked live; assume it is dead and remove.
         // TODO(titzer): we don't remove constants because some special ones
@@ -4431,9 +4202,8 @@
     }
 #endif
 
-    for (HInstruction* instruction = block->first();
-        instruction != NULL;
-        instruction = instruction->next()) {
+    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+      HInstruction* instruction = it.Current();
       if (instruction->ActualValue() != instruction) {
         ASSERT(instruction->IsInformativeDefinition());
         if (instruction->IsPurelyInformativeDefinition()) {
@@ -7632,7 +7402,7 @@
     return false;
   }
 
-#if !defined(V8_TARGET_ARCH_IA32)
+#if !V8_TARGET_ARCH_IA32
   // Target must be able to use caller's context.
   CompilationInfo* outer_info = current_info();
   if (target->context() != outer_info->closure()->context() ||
@@ -7781,7 +7551,7 @@
                                      undefined,
                                      function_state()->inlining_kind(),
                                      undefined_receiver);
-#ifdef V8_TARGET_ARCH_IA32
+#if V8_TARGET_ARCH_IA32
   // IA32 only, overwrite the caller's context in the deoptimization
   // environment with the correct one.
   //
@@ -9127,7 +8897,7 @@
   HValue* context = environment()->LookupContext();
   Handle<Type> left_type = expr->left()->lower_type();
   Handle<Type> right_type = expr->right()->lower_type();
-  Handle<Type> result_type = expr->lower_type();
+  Handle<Type> result_type = expr->result_type();
   Maybe<int> fixed_right_arg = expr->fixed_right_arg();
   Representation left_rep = ToRepresentation(left_type);
   Representation right_rep = ToRepresentation(right_type);
@@ -10635,6 +10405,13 @@
 }
 
 
+void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode(
+    CallRuntime* call) {
+  AddInstruction(new(zone()) HDebugBreak());
+  return ast_context()->ReturnValue(graph()->GetConstant0());
+}
+
+
 #undef CHECK_BAILOUT
 #undef CHECK_ALIVE
 
@@ -11045,8 +10822,8 @@
 
     {
       Tag HIR_tag(this, "HIR");
-      HInstruction* instruction = current->first();
-      while (instruction != NULL) {
+      for (HInstructionIterator it(current); !it.Done(); it.Advance()) {
+        HInstruction* instruction = it.Current();
         int bci = 0;
         int uses = instruction->UseCount();
         PrintIndent();
@@ -11055,7 +10832,6 @@
         trace_.Add(" ");
         instruction->PrintTo(&trace_);
         trace_.Add(" <|@\n");
-        instruction = instruction->next();
       }
     }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 7442b5f..3ea3262 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -230,6 +230,19 @@
 };
 
 
+class HInstructionIterator BASE_EMBEDDED {
+ public:
+  explicit HInstructionIterator(HBasicBlock* block) : instr_(block->first()) { }
+
+  bool Done() { return instr_ == NULL; }
+  HInstruction* Current() { return instr_; }
+  void Advance() { instr_ = instr_->next(); }
+
+ private:
+  HInstruction* instr_;
+};
+
+
 class HLoopInformation: public ZoneObject {
  public:
   HLoopInformation(HBasicBlock* loop_header, Zone* zone)
@@ -283,7 +296,6 @@
   void InsertRepresentationChanges();
   void MarkDeoptimizeOnUndefined();
   void ComputeMinusZeroChecks();
-  void ComputeSafeUint32Operations();
   bool ProcessArgumentsObject();
   void EliminateRedundantPhis();
   void Canonicalize();
@@ -416,7 +428,18 @@
     return depends_on_empty_array_proto_elements_;
   }
 
+  bool has_uint32_instructions() {
+    ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
+    return uint32_instructions_ != NULL;
+  }
+
+  ZoneList<HInstruction*>* uint32_instructions() {
+    ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
+    return uint32_instructions_;
+  }
+
   void RecordUint32Instruction(HInstruction* instr) {
+    ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
     if (uint32_instructions_ == NULL) {
       uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
     }
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index c0b2abd..7bb643a 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -36,7 +36,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "disassembler.h"
 #include "macro-assembler.h"
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 93400ae..8aa6e4a 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "codegen.h"
 #include "deoptimizer.h"
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 8cd4685..29a4be2 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "bootstrapper.h"
 #include "code-stubs.h"
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index d562238..da32c50 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "codegen.h"
 #include "heap.h"
diff --git a/src/ia32/cpu-ia32.cc b/src/ia32/cpu-ia32.cc
index 2d83cab..77ff169 100644
--- a/src/ia32/cpu-ia32.cc
+++ b/src/ia32/cpu-ia32.cc
@@ -33,7 +33,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "cpu.h"
 #include "macro-assembler.h"
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index a4c6bcc..db1d5a6 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "codegen.h"
 #include "debug.h"
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 16befa9..6af2445 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "codegen.h"
 #include "deoptimizer.h"
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index 9eb0d29..14e5800 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -31,7 +31,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "disasm.h"
 
diff --git a/src/ia32/frames-ia32.cc b/src/ia32/frames-ia32.cc
index 61d6876..5570811 100644
--- a/src/ia32/frames-ia32.cc
+++ b/src/ia32/frames-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "assembler.h"
 #include "assembler-ia32.h"
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index d04fdd4..cf3132d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "code-stubs.h"
 #include "codegen.h"
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 10d6c86..eb6ccd9 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "codegen.h"
 #include "ic-inl.h"
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 694ae13..96fb98e 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "ia32/lithium-codegen-ia32.h"
 #include "ic.h"
diff --git a/src/ia32/lithium-gap-resolver-ia32.cc b/src/ia32/lithium-gap-resolver-ia32.cc
index 3da8f32..86bfe2f 100644
--- a/src/ia32/lithium-gap-resolver-ia32.cc
+++ b/src/ia32/lithium-gap-resolver-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "ia32/lithium-gap-resolver-ia32.h"
 #include "ia32/lithium-codegen-ia32.h"
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 04b8934..c01cf8c 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "lithium-allocator-inl.h"
 #include "ia32/lithium-ia32.h"
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 31e9e53..63477aa 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "bootstrapper.h"
 #include "codegen.h"
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index 9a166d7..54fe8bf 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "unicode.h"
 #include "log.h"
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 1a51016..28e043d 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 
 #include "ic-inl.h"
 #include "codegen.h"
diff --git a/src/isolate.cc b/src/isolate.cc
index 2383399..fec3dc6 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -29,6 +29,7 @@
 
 #include "v8.h"
 
+#include "allocation-inl.h"
 #include "ast.h"
 #include "bootstrapper.h"
 #include "codegen.h"
@@ -107,6 +108,7 @@
   // is complete.
   pending_exception_ = NULL;
   has_pending_message_ = false;
+  rethrowing_message_ = false;
   pending_message_obj_ = NULL;
   pending_message_script_ = NULL;
   scheduled_exception_ = NULL;
@@ -116,7 +118,7 @@
 void ThreadLocalTop::Initialize() {
   InitializeInternal();
 #ifdef USE_SIMULATOR
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
   simulator_ = Simulator::current(isolate_);
 #elif V8_TARGET_ARCH_MIPS
   simulator_ = Simulator::current(isolate_);
@@ -486,7 +488,8 @@
        block != NULL;
        block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
     v->VisitPointer(BitCast<Object**>(&(block->exception_)));
-    v->VisitPointer(BitCast<Object**>(&(block->message_)));
+    v->VisitPointer(BitCast<Object**>(&(block->message_obj_)));
+    v->VisitPointer(BitCast<Object**>(&(block->message_script_)));
   }
 
   // Iterate over pointers on native execution stack.
@@ -1162,6 +1165,22 @@
 }
 
 
+void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
+  ASSERT(handler == try_catch_handler());
+  ASSERT(handler->HasCaught());
+  ASSERT(handler->rethrow_);
+  ASSERT(handler->capture_message_);
+  Object* message = reinterpret_cast<Object*>(handler->message_obj_);
+  Object* script = reinterpret_cast<Object*>(handler->message_script_);
+  ASSERT(message->IsJSMessageObject() || message->IsTheHole());
+  ASSERT(script->IsScript() || script->IsTheHole());
+  thread_local_top()->pending_message_obj_ = message;
+  thread_local_top()->pending_message_script_ = script;
+  thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_;
+  thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_;
+}
+
+
 Failure* Isolate::PromoteScheduledException() {
   MaybeObject* thrown = scheduled_exception();
   clear_scheduled_exception();
@@ -1280,9 +1299,12 @@
       ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
   bool report_exception = catchable_by_javascript && should_report_exception;
   bool try_catch_needs_message =
-      can_be_caught_externally && try_catch_handler()->capture_message_;
+      can_be_caught_externally && try_catch_handler()->capture_message_ &&
+      !thread_local_top()->rethrowing_message_;
   bool bootstrapping = bootstrapper()->IsActive();
 
+  thread_local_top()->rethrowing_message_ = false;
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger of exception.
   if (catchable_by_javascript) {
@@ -1464,8 +1486,9 @@
         HandleScope scope(this);
         Handle<Object> message_obj(thread_local_top_.pending_message_obj_,
                                    this);
-        if (thread_local_top_.pending_message_script_ != NULL) {
-          Handle<Script> script(thread_local_top_.pending_message_script_);
+        if (!thread_local_top_.pending_message_script_->IsTheHole()) {
+          Handle<Script> script(
+              Script::cast(thread_local_top_.pending_message_script_));
           int start_pos = thread_local_top_.pending_message_start_pos_;
           int end_pos = thread_local_top_.pending_message_end_pos_;
           MessageLocation location(script, start_pos, end_pos);
@@ -1487,8 +1510,9 @@
       thread_local_top_.pending_exception_ != heap()->termination_exception() &&
       thread_local_top_.has_pending_message_ &&
       !thread_local_top_.pending_message_obj_->IsTheHole() &&
-      thread_local_top_.pending_message_script_ != NULL) {
-    Handle<Script> script(thread_local_top_.pending_message_script_);
+      !thread_local_top_.pending_message_obj_->IsTheHole()) {
+    Handle<Script> script(
+        Script::cast(thread_local_top_.pending_message_script_));
     int start_pos = thread_local_top_.pending_message_start_pos_;
     int end_pos = thread_local_top_.pending_message_end_pos_;
     return MessageLocation(script, start_pos, end_pos);
@@ -1625,7 +1649,7 @@
   // This might be just paranoia, but it seems to be needed in case a
   // thread_local_top_ is restored on a separate OS thread.
 #ifdef USE_SIMULATOR
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
   thread_local_top()->simulator_ = Simulator::current(this);
 #elif V8_TARGET_ARCH_MIPS
   thread_local_top()->simulator_ = Simulator::current(this);
@@ -1776,8 +1800,8 @@
   thread_manager_ = new ThreadManager();
   thread_manager_->isolate_ = this;
 
-#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
-    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
+#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
+    V8_TARGET_ARCH_MIPS && !defined(__mips__)
   simulator_initialized_ = false;
   simulator_i_cache_ = NULL;
   simulator_redirection_ = NULL;
@@ -1936,6 +1960,15 @@
 Isolate::~Isolate() {
   TRACE_ISOLATE(destructor);
 
+  // The entry stack must be empty when we get here,
+  // except for the default isolate, where it can
+  // still contain up to one entry stack item
+  ASSERT(entry_stack_ == NULL || this == default_isolate_);
+  ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL);
+
+  delete entry_stack_;
+  entry_stack_ = NULL;
+
   delete[] assembler_spare_buffer_;
   assembler_spare_buffer_ = NULL;
 
@@ -2002,6 +2035,9 @@
   delete global_handles_;
   global_handles_ = NULL;
 
+  delete string_stream_debug_object_cache_;
+  string_stream_debug_object_cache_ = NULL;
+
   delete external_reference_table_;
   external_reference_table_ = NULL;
 
@@ -2039,15 +2075,24 @@
     try_catch_handler()->has_terminated_ = true;
     try_catch_handler()->exception_ = heap()->null_value();
   } else {
+    v8::TryCatch* handler = try_catch_handler();
     // At this point all non-object (failure) exceptions have
     // been dealt with so this shouldn't fail.
     ASSERT(!pending_exception()->IsFailure());
-    try_catch_handler()->can_continue_ = true;
-    try_catch_handler()->has_terminated_ = false;
-    try_catch_handler()->exception_ = pending_exception();
-    if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
-      try_catch_handler()->message_ = thread_local_top_.pending_message_obj_;
-    }
+    ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() ||
+           thread_local_top_.pending_message_obj_->IsTheHole());
+    ASSERT(thread_local_top_.pending_message_script_->IsScript() ||
+           thread_local_top_.pending_message_script_->IsTheHole());
+    handler->can_continue_ = true;
+    handler->has_terminated_ = false;
+    handler->exception_ = pending_exception();
+    // Propagate to the external try-catch only if we got an actual message.
+    if (thread_local_top_.pending_message_obj_->IsTheHole()) return;
+
+    handler->message_obj_ = thread_local_top_.pending_message_obj_;
+    handler->message_script_ = thread_local_top_.pending_message_script_;
+    handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_;
+    handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_;
   }
 }
 
@@ -2134,7 +2179,7 @@
 
   // Initialize other runtime facilities
 #if defined(USE_SIMULATOR)
-#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
   Simulator::Initialize(this);
 #endif
 #endif
diff --git a/src/isolate.h b/src/isolate.h
index 981f81c..f7d40dd 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -101,8 +101,8 @@
 class DebuggerAgent;
 #endif
 
-#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
-    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
+#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
+    !defined(__mips__) && V8_TARGET_ARCH_MIPS
 class Redirection;
 class Simulator;
 #endif
@@ -246,8 +246,9 @@
   ThreadId thread_id_;
   MaybeObject* pending_exception_;
   bool has_pending_message_;
+  bool rethrowing_message_;
   Object* pending_message_obj_;
-  Script* pending_message_script_;
+  Object* pending_message_script_;
   int pending_message_start_pos_;
   int pending_message_end_pos_;
   // Use a separate value for scheduled exceptions to preserve the
@@ -263,7 +264,7 @@
   Address handler_;   // try-blocks are chained through the stack
 
 #ifdef USE_SIMULATOR
-#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
   Simulator* simulator_;
 #endif
 #endif  // USE_SIMULATOR
@@ -391,8 +392,8 @@
           thread_id_(thread_id),
           stack_limit_(0),
           thread_state_(NULL),
-#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
-    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
+#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
+    !defined(__mips__) && V8_TARGET_ARCH_MIPS
           simulator_(NULL),
 #endif
           next_(NULL),
@@ -404,8 +405,8 @@
     ThreadState* thread_state() const { return thread_state_; }
     void set_thread_state(ThreadState* value) { thread_state_ = value; }
 
-#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
-    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
+#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
+    !defined(__mips__) && V8_TARGET_ARCH_MIPS
     Simulator* simulator() const { return simulator_; }
     void set_simulator(Simulator* simulator) {
       simulator_ = simulator;
@@ -422,8 +423,8 @@
     uintptr_t stack_limit_;
     ThreadState* thread_state_;
 
-#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
-    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
+#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
+    !defined(__mips__) && V8_TARGET_ARCH_MIPS
     Simulator* simulator_;
 #endif
 
@@ -582,7 +583,7 @@
   void clear_pending_message() {
     thread_local_top_.has_pending_message_ = false;
     thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
-    thread_local_top_.pending_message_script_ = NULL;
+    thread_local_top_.pending_message_script_ = heap_.the_hole_value();
   }
   v8::TryCatch* try_catch_handler() {
     return thread_local_top_.TryCatchHandler();
@@ -760,6 +761,9 @@
   // originally.
   Failure* ReThrow(MaybeObject* exception);
   void ScheduleThrow(Object* exception);
+  // Re-set pending message, script and positions reported to the TryCatch
+  // back to the TLS for re-use when rethrowing.
+  void RestorePendingMessageFromTryCatch(v8::TryCatch* handler);
   void ReportPendingMessages();
   // Return pending location if any or unfilled structure.
   MessageLocation GetMessageLocation();
@@ -994,8 +998,8 @@
   int* code_kind_statistics() { return code_kind_statistics_; }
 #endif
 
-#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
-    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
+#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
+    V8_TARGET_ARCH_MIPS && !defined(__mips__)
   bool simulator_initialized() { return simulator_initialized_; }
   void set_simulator_initialized(bool initialized) {
     simulator_initialized_ = initialized;
@@ -1301,8 +1305,8 @@
   // Time stamp at initialization.
   double time_millis_at_init_;
 
-#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
-    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
+#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
+    V8_TARGET_ARCH_MIPS && !defined(__mips__)
   bool simulator_initialized_;
   HashMap* simulator_i_cache_;
   Redirection* simulator_redirection_;
diff --git a/src/marking-thread.cc b/src/marking-thread.cc
index 574485a..ac9f944 100644
--- a/src/marking-thread.cc
+++ b/src/marking-thread.cc
@@ -73,6 +73,7 @@
   Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
   start_marking_semaphore_->Signal();
   stop_semaphore_->Wait();
+  Join();
 }
 
 
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index eee79a2..c4fefcc 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -35,7 +35,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "mips/assembler-mips-inl.h"
 #include "serialize.h"
@@ -1475,7 +1475,7 @@
 void Assembler::stop(const char* msg, uint32_t code) {
   ASSERT(code > kMaxWatchpointCode);
   ASSERT(code <= kMaxStopCode);
-#if defined(V8_HOST_ARCH_MIPS)
+#if V8_HOST_ARCH_MIPS
   break_(0x54321);
 #else  // V8_HOST_ARCH_MIPS
   BlockTrampolinePoolFor(2);
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index dddf045..fd35a35 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -29,7 +29,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "codegen.h"
 #include "debug.h"
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 3e42309..69b957a 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "bootstrapper.h"
 #include "code-stubs.h"
@@ -7530,12 +7530,16 @@
   const int32_t kReturnAddressDistanceFromFunctionStart =
       Assembler::kCallTargetAddressOffset + (2 * Assembler::kInstrSize);
 
-  // Save live volatile registers.
+  // This should contain all kJSCallerSaved registers.
+  const RegList kSavedRegs =
+     kJSCallerSaved |  // Caller saved registers.
+     s5.bit();         // Saved stack pointer.
+
   // We also save ra, so the count here is one higher than the mask indicates.
-  const int32_t kNumSavedRegs = kNumJSCallerSaved + 1;
+  const int32_t kNumSavedRegs = kNumJSCallerSaved + 2;
 
   // Save all caller-save registers as this may be called from anywhere.
-  __ MultiPush(kJSCallerSaved | ra.bit());
+  __ MultiPush(kSavedRegs | ra.bit());
 
   // Compute the function's address for the first argument.
   __ Subu(a0, ra, Operand(kReturnAddressDistanceFromFunctionStart));
@@ -7547,7 +7551,7 @@
   // Align the stack if necessary.
   int frame_alignment = masm->ActivationFrameAlignment();
   if (frame_alignment > kPointerSize) {
-    __ mov(t1, sp);
+    __ mov(s5, sp);
     ASSERT(IsPowerOf2(frame_alignment));
     __ And(sp, sp, Operand(-frame_alignment));
   }
@@ -7568,11 +7572,11 @@
 
   // Restore the stack pointer if needed.
   if (frame_alignment > kPointerSize) {
-    __ mov(sp, t1);
+    __ mov(sp, s5);
   }
 
   // Also pop ra to get Ret(0).
-  __ MultiPop(kJSCallerSaved | ra.bit());
+  __ MultiPop(kSavedRegs | ra.bit());
   __ Ret();
 }
 
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 72eb00b..7a95bc4 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "codegen.h"
 #include "macro-assembler.h"
diff --git a/src/mips/constants-mips.cc b/src/mips/constants-mips.cc
index ddfa891..a20ec54 100644
--- a/src/mips/constants-mips.cc
+++ b/src/mips/constants-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "constants-mips.h"
 
diff --git a/src/mips/cpu-mips.cc b/src/mips/cpu-mips.cc
index 93ebeda..d13b233 100644
--- a/src/mips/cpu-mips.cc
+++ b/src/mips/cpu-mips.cc
@@ -36,7 +36,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "cpu.h"
 #include "macro-assembler.h"
diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc
index 0ae0187..30cc4db 100644
--- a/src/mips/debug-mips.cc
+++ b/src/mips/debug-mips.cc
@@ -29,7 +29,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "codegen.h"
 #include "debug.h"
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index b787f13..708df39 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -56,7 +56,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "mips/constants-mips.h"
 #include "disasm.h"
diff --git a/src/mips/frames-mips.cc b/src/mips/frames-mips.cc
index d070b56..1bd5116 100644
--- a/src/mips/frames-mips.cc
+++ b/src/mips/frames-mips.cc
@@ -28,7 +28,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "assembler.h"
 #include "assembler-mips.h"
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index d416a3b..032c1f5 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 // Note on Mips implementation:
 //
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 8a00f60..896e030 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -29,7 +29,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "codegen.h"
 #include "code-stubs.h"
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 3e3314a..5890347 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -29,7 +29,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "bootstrapper.h"
 #include "codegen.h"
@@ -4723,19 +4723,19 @@
 
 
 int MacroAssembler::ActivationFrameAlignment() {
-#if defined(V8_HOST_ARCH_MIPS)
+#if V8_HOST_ARCH_MIPS
   // Running on the real platform. Use the alignment as mandated by the local
   // environment.
   // Note: This will break if we ever start generating snapshots on one Mips
   // platform for another Mips platform with a different alignment.
   return OS::ActivationFrameAlignment();
-#else  // defined(V8_HOST_ARCH_MIPS)
+#else  // V8_HOST_ARCH_MIPS
   // If we are using the simulator then we should always align to the expected
   // alignment. As the simulator is used to generate snapshots we do not know
   // if the target platform will need alignment, so this is controlled from a
   // flag.
   return FLAG_sim_stack_alignment;
-#endif  // defined(V8_HOST_ARCH_MIPS)
+#endif  // V8_HOST_ARCH_MIPS
 }
 
 
@@ -5066,7 +5066,7 @@
   // The argument stots are presumed to have been set up by
   // PrepareCallCFunction. The C function must be called via t9, for mips ABI.
 
-#if defined(V8_HOST_ARCH_MIPS)
+#if V8_HOST_ARCH_MIPS
   if (emit_debug_code()) {
     int frame_alignment = OS::ActivationFrameAlignment();
     int frame_alignment_mask = frame_alignment - 1;
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index 2961519..7b67a7b 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "unicode.h"
 #include "log.h"
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 8771bd2..914a758 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -31,7 +31,7 @@
 #include <cstdarg>
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "cpu.h"
 #include "disasm.h"
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index caddb76..5221190 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
 #include "ic-inl.h"
 #include "codegen.h"
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index dbf9ad7..21ef237 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -115,8 +115,11 @@
     InstallOptimizedFunctions();
   } else {
     OptimizingCompiler* optimizing_compiler;
+    // The optimizing compiler is allocated in the CompilationInfo's zone.
     while (input_queue_.Dequeue(&optimizing_compiler)) {
-      // The optimizing compiler is allocated in the CompilationInfo's zone.
+      delete optimizing_compiler->info();
+    }
+    while (output_queue_.Dequeue(&optimizing_compiler)) {
       delete optimizing_compiler->info();
     }
   }
@@ -127,6 +130,8 @@
     double percentage = (compile_time * 100) / total_time;
     PrintF("  ** Compiler thread did %.2f%% useful work\n", percentage);
   }
+
+  Join();
 }
 
 
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index 59c94cb..699c76d 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -83,8 +83,12 @@
 #endif
 
   ~OptimizingCompilerThread() {
+    delete install_mutex_;
     delete input_queue_semaphore_;
     delete stop_semaphore_;
+#ifdef DEBUG
+    delete thread_id_mutex_;
+#endif
   }
 
  private:
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 4a9bb7e..2c6a36c 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -295,7 +295,7 @@
 
 
 int OS::ActivationFrameAlignment() {
-#ifdef V8_TARGET_ARCH_ARM
+#if V8_TARGET_ARCH_ARM
   // On EABI ARM targets this is required for fp correctness in the
   // runtime system.
   return 8;
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index b21166d..21e9c7f 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -583,7 +583,7 @@
   if (kernel_version_major < 11) {
     // 8.x.x (Tiger), 9.x.x (Leopard), 10.x.x (Snow Leopard) have the
     // same offsets.
-#if defined(V8_HOST_ARCH_IA32)
+#if V8_HOST_ARCH_IA32
     kMacTlsBaseOffset = 0x48;
 #else
     kMacTlsBaseOffset = 0x60;
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index f2d9dd4..b722e31 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -79,7 +79,7 @@
   // CpuFeatures::Probe. We don't care about randomization in this case because
   // the code page is immediately freed.
   if (isolate != NULL) {
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
     uint64_t rnd1 = V8::RandomPrivate(isolate);
     uint64_t rnd2 = V8::RandomPrivate(isolate);
     uint64_t raw_addr = (rnd1 << 32) ^ rnd2;
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index f76ec44..e72a5d9 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -105,7 +105,7 @@
   // CpuFeatures::Probe. We don't care about randomization in this case because
   // the code page is immediately freed.
   if (isolate != NULL) {
-#ifdef V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
     uint64_t rnd1 = V8::RandomPrivate(isolate);
     uint64_t rnd2 = V8::RandomPrivate(isolate);
     uint64_t raw_addr = (rnd1 << 32) ^ rnd2;
@@ -321,7 +321,7 @@
 }
 
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 static void MemMoveWrapper(void* dest, const void* src, size_t size) {
   memmove(dest, src, size);
 }
@@ -344,7 +344,7 @@
 
 
 void POSIXPostSetUp() {
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
   OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
   if (generated_memmove != NULL) {
     memmove_function = generated_memmove;
diff --git a/src/platform-tls-mac.h b/src/platform-tls-mac.h
index 728524e..d1c5907 100644
--- a/src/platform-tls-mac.h
+++ b/src/platform-tls-mac.h
@@ -33,7 +33,7 @@
 namespace v8 {
 namespace internal {
 
-#if defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)
+#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
 
 #define V8_FAST_TLS_SUPPORTED 1
 
@@ -43,7 +43,7 @@
 
 inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
   intptr_t result;
-#if defined(V8_HOST_ARCH_IA32)
+#if V8_HOST_ARCH_IA32
   asm("movl %%gs:(%1,%2,4), %0;"
       :"=r"(result)  // Output must be a writable register.
       :"r"(kMacTlsBaseOffset), "r"(index));
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 600962e..1913760 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -147,7 +147,7 @@
 
 static Mutex* limit_mutex = NULL;
 
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
 static void MemMoveWrapper(void* dest, const void* src, size_t size) {
   memmove(dest, src, size);
 }
@@ -580,7 +580,7 @@
   // Math functions depend on CPU features therefore they are initialized after
   // CPU.
   MathSetup();
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
   OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
   if (generated_memmove != NULL) {
     memmove_function = generated_memmove;
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 6f9a601..20c1aec 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -44,17 +44,19 @@
 
 
 CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
-                     const char* name_prefix,
                      const char* name,
                      int security_token_id,
+                     const char* name_prefix,
                      const char* resource_name,
                      int line_number)
     : tag_(tag),
+      builtin_id_(Builtins::builtin_count),
       name_prefix_(name_prefix),
       name_(name),
       resource_name_(resource_name),
       line_number_(line_number),
       shared_id_(0),
+      script_id_(v8::Script::kNoScriptId),
       security_token_id_(security_token_id),
       no_frame_ranges_(NULL) {
 }
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 8505b5b..aeb80a3 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -235,6 +235,12 @@
 }
 
 
+void CodeEntry::SetBuiltinId(Builtins::Name id) {
+  tag_ = Logger::BUILTIN_TAG;
+  builtin_id_ = id;
+}
+
+
 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
   HashMap::Entry* map_entry =
       children_.Lookup(entry, CodeEntryHash(entry), false);
@@ -267,12 +273,13 @@
 
 
 void ProfileNode::Print(int indent) {
-  OS::Print("%5u %5u %*c %s%s [%d] #%d",
+  OS::Print("%5u %5u %*c %s%s [%d] #%d %d",
             total_ticks_, self_ticks_,
             indent, ' ',
             entry_->name_prefix(),
             entry_->name(),
             entry_->security_token_id(),
+            entry_->script_id(),
             id());
   if (entry_->resource_name()[0] != '\0')
     OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number());
@@ -298,7 +305,7 @@
 
 
 ProfileTree::ProfileTree()
-    : root_entry_(Logger::FUNCTION_TAG, "", "(root)"),
+    : root_entry_(Logger::FUNCTION_TAG, "(root)"),
       next_node_id_(1),
       root_(new ProfileNode(this, &root_entry_)) {
 }
@@ -787,54 +794,6 @@
 }
 
 
-CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
-                                               Name* name,
-                                               String* resource_name,
-                                               int line_number) {
-  CodeEntry* entry = new CodeEntry(tag,
-                                   CodeEntry::kEmptyNamePrefix,
-                                   GetFunctionName(name),
-                                   TokenEnumerator::kNoSecurityToken,
-                                   GetName(resource_name),
-                                   line_number);
-  code_entries_.Add(entry);
-  return entry;
-}
-
-
-CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
-                                               const char* name) {
-  CodeEntry* entry = new CodeEntry(tag,
-                                   CodeEntry::kEmptyNamePrefix,
-                                   GetFunctionName(name));
-  code_entries_.Add(entry);
-  return entry;
-}
-
-
-CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
-                                               const char* name_prefix,
-                                               Name* name) {
-  CodeEntry* entry = new CodeEntry(tag,
-                                   name_prefix,
-                                   GetName(name),
-                                   TokenEnumerator::kInheritsSecurityToken);
-  code_entries_.Add(entry);
-  return entry;
-}
-
-
-CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
-                                               int args_count) {
-  CodeEntry* entry = new CodeEntry(tag,
-                                   "args_count: ",
-                                   GetName(args_count),
-                                   TokenEnumerator::kInheritsSecurityToken);
-  code_entries_.Add(entry);
-  return entry;
-}
-
-
 void CpuProfilesCollection::AddPathToCurrentProfiles(
     const Vector<CodeEntry*>& path) {
   // As starting / stopping profiles is rare relatively to this
@@ -848,6 +807,24 @@
 }
 
 
+CodeEntry* CpuProfilesCollection::NewCodeEntry(
+      Logger::LogEventsAndTags tag,
+      const char* name,
+      int security_token_id,
+      const char* name_prefix,
+      const char* resource_name,
+      int line_number) {
+  CodeEntry* code_entry = new CodeEntry(tag,
+                                        name,
+                                        security_token_id,
+                                        name_prefix,
+                                        resource_name,
+                                        line_number);
+  code_entries_.Add(code_entry);
+  return code_entry;
+}
+
+
 void SampleRateCalculator::Tick() {
   if (--wall_time_query_countdown_ == 0)
     UpdateMeasurements(OS::TimeCurrentMillis());
@@ -877,6 +854,8 @@
     "(program)";
 const char* const ProfileGenerator::kGarbageCollectorEntryName =
     "(garbage collector)";
+const char* const ProfileGenerator::kUnresolvedFunctionName =
+    "(unresolved function)";
 
 
 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
@@ -885,7 +864,10 @@
           profiles->NewCodeEntry(Logger::FUNCTION_TAG, kProgramEntryName)),
       gc_entry_(
           profiles->NewCodeEntry(Logger::BUILTIN_TAG,
-                                 kGarbageCollectorEntryName)) {
+                                 kGarbageCollectorEntryName)),
+      unresolved_entry_(
+          profiles->NewCodeEntry(Logger::FUNCTION_TAG,
+                                 kUnresolvedFunctionName)) {
 }
 
 
@@ -897,33 +879,40 @@
   CodeEntry** entry = entries.start();
   memset(entry, 0, entries.length() * sizeof(*entry));
   if (sample.pc != NULL) {
-    Address start;
-    CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start);
-    // If pc is in the function code before it set up stack frame or after the
-    // frame was destroyed SafeStackFrameIterator incorrectly thinks that
-    // ebp contains return address of the current function and skips caller's
-    // frame. Check for this case and just skip such samples.
-    if (pc_entry) {
-      List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
-      if (ranges) {
-        Code* code = Code::cast(HeapObject::FromAddress(start));
-        int pc_offset = static_cast<int>(sample.pc - code->instruction_start());
-        for (int i = 0; i < ranges->length(); i++) {
-          OffsetRange& range = ranges->at(i);
-          if (range.from <= pc_offset && pc_offset < range.to) {
-            return;
-          }
-        }
-      }
-    }
-    *entry++ = pc_entry;
-
     if (sample.has_external_callback) {
       // Don't use PC when in external callback code, as it can point
       // inside callback's code, and we will erroneously report
       // that a callback calls itself.
-      *(entries.start()) = NULL;
       *entry++ = code_map_.FindEntry(sample.external_callback);
+    } else {
+      Address start;
+      CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start);
+      // If pc is in the function code before it set up stack frame or after the
+      // frame was destroyed SafeStackFrameIterator incorrectly thinks that
+      // ebp contains return address of the current function and skips caller's
+      // frame. Check for this case and just skip such samples.
+      if (pc_entry) {
+        List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
+        if (ranges) {
+          Code* code = Code::cast(HeapObject::FromAddress(start));
+          int pc_offset = static_cast<int>(
+              sample.pc - code->instruction_start());
+          for (int i = 0; i < ranges->length(); i++) {
+            OffsetRange& range = ranges->at(i);
+            if (range.from <= pc_offset && pc_offset < range.to) {
+              return;
+            }
+          }
+        }
+        *entry++ = pc_entry;
+
+        if (pc_entry->builtin_id() == Builtins::kFunctionCall) {
+          // When current function is FunctionCall builtin tos is sometimes
+          // address of the function that invoked it but sometimes it's one
+          // of the arguments. We simply replace the frame with 'unknown' entry.
+          *entry++ = unresolved_entry_;
+        }
+      }
     }
 
     for (const Address* stack_pos = sample.stack,
diff --git a/src/profile-generator.h b/src/profile-generator.h
index f8534e4..411cbdb 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -97,9 +97,9 @@
  public:
   // CodeEntry doesn't own name strings, just references them.
   INLINE(CodeEntry(Logger::LogEventsAndTags tag,
-                   const char* name_prefix,
                    const char* name,
                    int security_token_id = TokenEnumerator::kNoSecurityToken,
+                   const char* name_prefix = CodeEntry::kEmptyNamePrefix,
                    const char* resource_name = CodeEntry::kEmptyResourceName,
                    int line_number = v8::CpuProfileNode::kNoLineNumberInfo));
   ~CodeEntry();
@@ -111,6 +111,8 @@
   INLINE(const char* resource_name() const) { return resource_name_; }
   INLINE(int line_number() const) { return line_number_; }
   INLINE(void set_shared_id(int shared_id)) { shared_id_ = shared_id; }
+  INLINE(int script_id() const) { return script_id_; }
+  INLINE(void set_script_id(int script_id)) { script_id_ = script_id; }
   INLINE(int security_token_id() const) { return security_token_id_; }
 
   INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag));
@@ -120,6 +122,9 @@
     no_frame_ranges_ = ranges;
   }
 
+  void SetBuiltinId(Builtins::Name id);
+  Builtins::Name builtin_id() const { return builtin_id_; }
+
   void CopyData(const CodeEntry& source);
   uint32_t GetCallUid() const;
   bool IsSameAs(CodeEntry* entry) const;
@@ -128,12 +133,14 @@
   static const char* const kEmptyResourceName;
 
  private:
-  Logger::LogEventsAndTags tag_;
+  Logger::LogEventsAndTags tag_ : 8;
+  Builtins::Name builtin_id_ : 8;
   const char* name_prefix_;
   const char* name_;
   const char* resource_name_;
   int line_number_;
   int shared_id_;
+  int script_id_;
   int security_token_id_;
   List<OffsetRange>* no_frame_ranges_;
 
@@ -318,18 +325,24 @@
   const char* GetName(int args_count) {
     return function_and_resource_names_.GetName(args_count);
   }
+  const char* GetFunctionName(Name* name) {
+    return function_and_resource_names_.GetFunctionName(name);
+  }
+  const char* GetFunctionName(const char* name) {
+    return function_and_resource_names_.GetFunctionName(name);
+  }
   CpuProfile* GetProfile(int security_token_id, unsigned uid);
   bool IsLastProfile(const char* title);
   void RemoveProfile(CpuProfile* profile);
   bool HasDetachedProfiles() { return detached_profiles_.length() > 0; }
 
-  CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
-                          Name* name, String* resource_name, int line_number);
-  CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name);
-  CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
-                          const char* name_prefix, Name* name);
-  CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count);
-  CodeEntry* NewCodeEntry(int security_token_id);
+  CodeEntry* NewCodeEntry(
+      Logger::LogEventsAndTags tag,
+      const char* name,
+      int security_token_id = TokenEnumerator::kNoSecurityToken,
+      const char* name_prefix = CodeEntry::kEmptyNamePrefix,
+      const char* resource_name = CodeEntry::kEmptyResourceName,
+      int line_number = v8::CpuProfileNode::kNoLineNumberInfo);
 
   // Called from profile generator thread.
   void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path);
@@ -338,12 +351,6 @@
   static const int kMaxSimultaneousProfiles = 100;
 
  private:
-  const char* GetFunctionName(Name* name) {
-    return function_and_resource_names_.GetFunctionName(name);
-  }
-  const char* GetFunctionName(const char* name) {
-    return function_and_resource_names_.GetFunctionName(name);
-  }
   int GetProfileIndex(unsigned uid);
   List<CpuProfile*>* GetProfilesList(int security_token_id);
   int TokenToIndex(int security_token_id);
@@ -422,6 +429,9 @@
   static const char* const kAnonymousFunctionName;
   static const char* const kProgramEntryName;
   static const char* const kGarbageCollectorEntryName;
+  // Used to represent frames for which we have no reliable way to
+  // detect function.
+  static const char* const kUnresolvedFunctionName;
 
  private:
   INLINE(CodeEntry* EntryForVMState(StateTag tag));
@@ -430,6 +440,7 @@
   CodeMap code_map_;
   CodeEntry* program_entry_;
   CodeEntry* gc_entry_;
+  CodeEntry* unresolved_entry_;
   SampleRateCalculator sample_rate_calc_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
diff --git a/src/runtime.cc b/src/runtime.cc
index 081774f..4691e18 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -8314,8 +8314,13 @@
   ASSERT(args.length() == 1);
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   if (FLAG_parallel_recompilation && V8::UseCrankshaft()) {
-    // While function is in optimization pipeline, it is marked with builtins.
-    while (function->code()->kind() == Code::BUILTIN) {
+    // While function is in optimization pipeline, it is marked accordingly.
+    // Note that if the debugger is activated during parallel recompilation,
+    // the function will be marked with the lazy-recompile builtin, which is
+    // not related to parallel recompilation.
+    while (function->IsMarkedForParallelRecompilation() ||
+           function->IsInRecompileQueue() ||
+           function->IsMarkedForInstallingRecompiledCode()) {
       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
       OS::Sleep(50);
     }
@@ -12097,14 +12102,28 @@
 }
 
 
+static bool IsPositionAlignmentCodeCorrect(int alignment) {
+  return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 2);
 
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
+
+  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
+    return isolate->ThrowIllegalOperation();
+  }
+  BreakPositionAlignment alignment =
+      static_cast<BreakPositionAlignment>(statement_aligned_code);
+
   Handle<SharedFunctionInfo> shared(fun->shared());
   // Find the number of break points
-  Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared);
+  Handle<Object> break_locations =
+      Debug::GetSourceBreakLocations(shared, alignment);
   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   // Return array as JS array
   return *isolate->factory()->NewJSArrayWithElements(
@@ -12137,14 +12156,22 @@
 // GetScriptFromScriptData.
 // args[0]: script to set break point in
 // args[1]: number: break source position (within the script source)
-// args[2]: number: break point object
+// args[2]: number, breakpoint position alignment
+// args[3]: number: break point object
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
+  ASSERT(args.length() == 4);
   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   RUNTIME_ASSERT(source_position >= 0);
-  Handle<Object> break_point_object_arg = args.at<Object>(2);
+  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
+  Handle<Object> break_point_object_arg = args.at<Object>(3);
+
+  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
+    return isolate->ThrowIllegalOperation();
+  }
+  BreakPositionAlignment alignment =
+      static_cast<BreakPositionAlignment>(statement_aligned_code);
 
   // Get the script from the script wrapper.
   RUNTIME_ASSERT(wrapper->value()->IsScript());
@@ -12152,7 +12179,8 @@
 
   // Set break point.
   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
-                                                &source_position)) {
+                                                &source_position,
+                                                alignment)) {
     return  isolate->heap()->undefined_value();
   }
 
diff --git a/src/runtime.h b/src/runtime.h
index 4928e78..70568f9 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -499,9 +499,9 @@
   F(GetThreadCount, 1, 1) \
   F(GetThreadDetails, 2, 1) \
   F(SetDisableBreak, 1, 1) \
-  F(GetBreakLocations, 1, 1) \
+  F(GetBreakLocations, 2, 1) \
   F(SetFunctionBreakPoint, 3, 1) \
-  F(SetScriptBreakPoint, 3, 1) \
+  F(SetScriptBreakPoint, 4, 1) \
   F(ClearBreakPoint, 1, 1) \
   F(ChangeBreakOnException, 2, 1) \
   F(IsBreakOnException, 1, 1) \
@@ -597,7 +597,8 @@
   F(GetCachedArrayIndex, 1, 1)                                               \
   F(FastAsciiArrayJoin, 2, 1)                                                \
   F(GeneratorNext, 2, 1)                                                     \
-  F(GeneratorThrow, 2, 1)
+  F(GeneratorThrow, 2, 1)                                                    \
+  F(DebugBreakInOptimizedCode, 0, 1)
 
 
 // ----------------------------------------------------------------------------
diff --git a/src/strtod.cc b/src/strtod.cc
index dfe2fb7..a1774b6 100644
--- a/src/strtod.cc
+++ b/src/strtod.cc
@@ -175,7 +175,7 @@
 static bool DoubleStrtod(Vector<const char> trimmed,
                          int exponent,
                          double* result) {
-#if (defined(V8_TARGET_ARCH_IA32) || defined(USE_SIMULATOR)) \
+#if (V8_TARGET_ARCH_IA32 || defined(USE_SIMULATOR)) \
     && !defined(_MSC_VER)
   // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
   // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
diff --git a/src/sweeper-thread.cc b/src/sweeper-thread.cc
index 099f5d1..ede567a 100644
--- a/src/sweeper-thread.cc
+++ b/src/sweeper-thread.cc
@@ -93,6 +93,7 @@
   Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
   start_sweeping_semaphore_->Signal();
   stop_semaphore_->Wait();
+  Join();
 }
 
 
diff --git a/src/third_party/vtune/v8vtune.gyp b/src/third_party/vtune/v8vtune.gyp
index cabd37a..6c3de3e 100644
--- a/src/third_party/vtune/v8vtune.gyp
+++ b/src/third_party/vtune/v8vtune.gyp
@@ -26,6 +26,9 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 {
+  'variables': {
+    'v8_code': 1,
+  },
   'includes': ['../../../build/common.gypi'],
   'targets': [
     {
diff --git a/src/type-info.h b/src/type-info.h
index aa1f509..a1c1f54 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -303,9 +303,9 @@
                   Maybe<int>* fixed_right_arg);
 
   void CompareType(TypeFeedbackId id,
-                   Handle<Type>* left,
-                   Handle<Type>* right,
-                   Handle<Type>* combined);
+                   Handle<Type>* left_type,
+                   Handle<Type>* right_type,
+                   Handle<Type>* combined_type);
 
   Handle<Type> ClauseType(TypeFeedbackId id);
 
diff --git a/src/typing.cc b/src/typing.cc
index 3f3ff60..7c11612 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -432,13 +432,13 @@
   CHECK_ALIVE(Visit(expr->right()));
 
   // Collect type feedback.
-  Handle<Type> type, left_type, right_type;
+  Handle<Type> left_type, right_type, result_type;
   Maybe<int> fixed_right_arg;
   oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
-      &left_type, &right_type, &type, &fixed_right_arg);
-  MergeLowerType(expr, type);
+      &left_type, &right_type, &result_type, &fixed_right_arg);
   MergeLowerType(expr->left(), left_type);
   MergeLowerType(expr->right(), right_type);
+  expr->set_result_type(result_type);
   expr->set_fixed_right_arg(fixed_right_arg);
   if (expr->op() == Token::OR || expr->op() == Token::AND) {
     expr->left()->RecordToBooleanTypeFeedback(oracle());
diff --git a/src/v8utils.h b/src/v8utils.h
index 8661f9b..ff9f8f2 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -257,9 +257,9 @@
   a = b;  // Fake assignment to check assignability.
   USE(a);
 #endif  // DEBUG
-#if defined(V8_HOST_ARCH_IA32)
+#if V8_HOST_ARCH_IA32
 #define STOS "stosl"
-#elif defined(V8_HOST_ARCH_X64)
+#elif V8_HOST_ARCH_X64
 #define STOS "stosq"
 #endif
 #if defined(__native_client__)
diff --git a/src/version.cc b/src/version.cc
index 84cafc8..c634509 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     20
-#define BUILD_NUMBER      0
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      1
+#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/assembler-x64.cc b/src/x64/assembler-x64.cc
index f547e79..3a3ee9c 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "macro-assembler.h"
 #include "serialize.h"
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 9376cc7..378217b 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "codegen.h"
 #include "deoptimizer.h"
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 1be60ab..9774638 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "bootstrapper.h"
 #include "code-stubs.h"
@@ -1558,7 +1558,8 @@
     char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
     char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
     // Two uint_32's and a pointer per element.
-    CHECK_EQ(16, static_cast<int>(elem2_start - elem_start));
+    CHECK_EQ(2 * kIntSize + 1 * kPointerSize,
+             static_cast<int>(elem2_start - elem_start));
     CHECK_EQ(0, static_cast<int>(elem_in0 - elem_start));
     CHECK_EQ(kIntSize, static_cast<int>(elem_in1 - elem_start));
     CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start));
@@ -5111,17 +5112,17 @@
 
   // Don't enter the rep movs if there are less than 4 bytes to copy.
   Label last_bytes;
-  __ testl(count, Immediate(~7));
+  __ testl(count, Immediate(~(kPointerSize - 1)));
   __ j(zero, &last_bytes, Label::kNear);
 
   // Copy from edi to esi using rep movs instruction.
   __ movl(kScratchRegister, count);
-  __ shr(count, Immediate(3));  // Number of doublewords to copy.
+  __ shr(count, Immediate(kPointerSizeLog2));  // Number of doublewords to copy.
   __ repmovsq();
 
   // Find number of bytes left.
   __ movl(count, kScratchRegister);
-  __ and_(count, Immediate(7));
+  __ and_(count, Immediate(kPointerSize - 1));
 
   // Check if there are more bytes to copy.
   __ bind(&last_bytes);
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 7a7ec7b..9643872 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "codegen.h"
 #include "macro-assembler.h"
@@ -735,7 +735,11 @@
     Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length);
     patcher.masm()->call(stub->instruction_start());
-    patcher.masm()->nop();
+    for (int i = 0;
+         i < kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength;
+         i++) {
+      patcher.masm()->nop();
+    }
   }
 }
 
diff --git a/src/x64/cpu-x64.cc b/src/x64/cpu-x64.cc
index 80e22c6..96c5330 100644
--- a/src/x64/cpu-x64.cc
+++ b/src/x64/cpu-x64.cc
@@ -33,7 +33,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "cpu.h"
 #include "macro-assembler.h"
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index 750d929..a337b0d 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "assembler.h"
 #include "codegen.h"
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 60e676a..f2f7ed0 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "codegen.h"
 #include "deoptimizer.h"
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index fb0914d..d787775 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -31,7 +31,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "disasm.h"
 #include "lazy-instance.h"
diff --git a/src/x64/frames-x64.cc b/src/x64/frames-x64.cc
index 21cb79c..5cc27a6 100644
--- a/src/x64/frames-x64.cc
+++ b/src/x64/frames-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "assembler.h"
 #include "assembler-x64.h"
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 7732a1d..9ad7f58 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "code-stubs.h"
 #include "codegen.h"
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 82112a0..a0f3ead 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "codegen.h"
 #include "ic-inl.h"
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index f3045d5..c97475a 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "x64/lithium-codegen-x64.h"
 #include "code-stubs.h"
diff --git a/src/x64/lithium-gap-resolver-x64.cc b/src/x64/lithium-gap-resolver-x64.cc
index fd74e0a..aed4f36 100644
--- a/src/x64/lithium-gap-resolver-x64.cc
+++ b/src/x64/lithium-gap-resolver-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "x64/lithium-gap-resolver-x64.h"
 #include "x64/lithium-codegen-x64.h"
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 7a475a7..9c2373a 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "lithium-allocator-inl.h"
 #include "x64/lithium-x64.h"
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index a4d64b9..fdeee31 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "bootstrapper.h"
 #include "codegen.h"
@@ -4216,12 +4216,12 @@
   // we keep source aligned for the rep movs operation by copying the odd bytes
   // at the end of the ranges.
   movq(scratch, length);
-  shrl(length, Immediate(3));
+  shrl(length, Immediate(kPointerSizeLog2));
   repmovsq();
   // Move remaining bytes of length.
-  andl(scratch, Immediate(0x7));
-  movq(length, Operand(source, scratch, times_1, -8));
-  movq(Operand(destination, scratch, times_1, -8), length);
+  andl(scratch, Immediate(kPointerSize - 1));
+  movq(length, Operand(source, scratch, times_1, -kPointerSize));
+  movq(Operand(destination, scratch, times_1, -kPointerSize), length);
   addq(destination, scratch);
 
   if (min_length <= kLongStringLimit) {
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index efb2a65..e1d4a2d 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "serialize.h"
 #include "unicode.h"
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 9dddd79..1a992b4 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -27,7 +27,7 @@
 
 #include "v8.h"
 
-#if defined(V8_TARGET_ARCH_X64)
+#if V8_TARGET_ARCH_X64
 
 #include "ic-inl.h"
 #include "codegen.h"