Push version 1.2.0 to trunk.

Optimized floating-point operations on ARM.

Added a number of extensions to the debugger API.

Changed the enumeration order for unsigned integer keys to always be numerical order.

Added a "read" extension to the shell sample.

Added support for Array.prototype.reduce and Array.prototype.reduceRight.

Added an option to the SCons build to control Microsoft Visual C++ link-time code generation.

Fixed a number of bugs (in particular issue 315, issue 316, issue 317 and issue 318).


git-svn-id: http://v8.googlecode.com/svn/trunk@1781 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/accessors.cc b/src/accessors.cc
index d779eb2..2d6a3a1 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -252,6 +252,24 @@
 
 
 //
+// Accessors::ScriptData
+//
+
+
+Object* Accessors::ScriptGetData(Object* object, void*) {
+  Object* script = JSValue::cast(object)->value();
+  return Script::cast(script)->data();
+}
+
+
+const AccessorDescriptor Accessors::ScriptData = {
+  ScriptGetData,
+  IllegalSetter,
+  0
+};
+
+
+//
 // Accessors::ScriptType
 //
 
diff --git a/src/accessors.h b/src/accessors.h
index 938b014..d174c90 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -45,6 +45,7 @@
   V(ScriptId)            \
   V(ScriptLineOffset)    \
   V(ScriptColumnOffset)  \
+  V(ScriptData)          \
   V(ScriptType)          \
   V(ScriptLineEnds)      \
   V(ObjectPrototype)
@@ -84,6 +85,7 @@
   static Object* ScriptGetSource(Object* object, void*);
   static Object* ScriptGetLineOffset(Object* object, void*);
   static Object* ScriptGetColumnOffset(Object* object, void*);
+  static Object* ScriptGetData(Object* object, void*);
   static Object* ScriptGetType(Object* object, void*);
   static Object* ScriptGetLineEnds(Object* object, void*);
   static Object* ObjectGetPrototype(Object* receiver, void*);
diff --git a/src/api.cc b/src/api.cc
index a190b9c..449926c 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1108,6 +1108,19 @@
 }
 
 
+void Script::SetData(v8::Handle<Value> data) {
+  ON_BAILOUT("v8::Script::SetData()", return);
+  LOG_API("Script::SetData");
+  {
+    HandleScope scope;
+    i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
+    i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
+    i::Handle<i::Script> script(i::Script::cast(fun->shared()->script()));
+    script->set_data(*raw_data);
+  }
+}
+
+
 // --- E x c e p t i o n s ---
 
 
@@ -1199,6 +1212,22 @@
 }
 
 
+v8::Handle<Value> Message::GetScriptData() const {
+  if (IsDeadCheck("v8::Message::GetScriptResourceData()")) {
+    return Local<Value>();
+  }
+  ENTER_V8;
+  HandleScope scope;
+  i::Handle<i::JSObject> obj =
+      i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
+  // Return this.script.data.
+  i::Handle<i::JSValue> script =
+      i::Handle<i::JSValue>::cast(GetProperty(obj, "script"));
+  i::Handle<i::Object> data(i::Script::cast(script->value())->data());
+  return scope.Close(Utils::ToLocal(data));
+}
+
+
 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
                                                i::Handle<i::Object> recv,
                                                int argc,
@@ -1806,6 +1835,26 @@
 }
 
 
+bool v8::Object::ForceSet(v8::Handle<Value> key,
+                          v8::Handle<Value> value,
+                          v8::PropertyAttribute attribs) {
+  ON_BAILOUT("v8::Object::ForceSet()", return false);
+  ENTER_V8;
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
+  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> obj = i::ForceSetProperty(
+      self,
+      key_obj,
+      value_obj,
+      static_cast<PropertyAttributes>(attribs));
+  has_pending_exception = obj.is_null();
+  EXCEPTION_BAILOUT_CHECK(false);
+  return true;
+}
+
+
 Local<Value> v8::Object::Get(v8::Handle<Value> key) {
   ON_BAILOUT("v8::Object::Get()", return Local<v8::Value>());
   ENTER_V8;
@@ -2373,7 +2422,7 @@
 
 
 const char* v8::V8::GetVersion() {
-  return "1.1.10.4";
+  return "1.2.0";
 }
 
 
@@ -3180,8 +3229,8 @@
 
 // --- D e b u g   S u p p o r t ---
 
-
-bool Debug::SetDebugEventListener(DebugEventCallback that, Handle<Value> data) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
+bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
   EnsureInitialized("v8::Debug::SetDebugEventListener()");
   ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false);
   ENTER_V8;
@@ -3211,31 +3260,27 @@
 }
 
 
-void Debug::SetMessageHandler(v8::DebugMessageHandler handler, void* data,
+void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
                               bool message_handler_thread) {
   EnsureInitialized("v8::Debug::SetMessageHandler");
   ENTER_V8;
-  i::Debugger::SetMessageHandler(handler, data, message_handler_thread);
+  i::Debugger::SetMessageHandler(handler, message_handler_thread);
 }
 
 
-void Debug::SendCommand(const uint16_t* command, int length) {
+void Debug::SendCommand(const uint16_t* command, int length,
+                        ClientData* client_data) {
   if (!i::V8::HasBeenSetup()) return;
-  i::Debugger::ProcessCommand(i::Vector<const uint16_t>(command, length));
+  i::Debugger::ProcessCommand(i::Vector<const uint16_t>(command, length),
+                              client_data);
 }
 
 
-void Debug::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
-                                   void* data) {
+void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
+                                   int period) {
   EnsureInitialized("v8::Debug::SetHostDispatchHandler");
   ENTER_V8;
-  i::Debugger::SetHostDispatchHandler(handler, data);
-}
-
-
-void Debug::SendHostDispatch(void* dispatch) {
-  if (!i::V8::HasBeenSetup()) return;
-  i::Debugger::ProcessHostDispatch(dispatch);
+  i::Debugger::SetHostDispatchHandler(handler, period);
 }
 
 
@@ -3263,7 +3308,7 @@
 bool Debug::EnableAgent(const char* name, int port) {
   return i::Debugger::StartAgent(name, port);
 }
-
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 namespace internal {
 
diff --git a/src/array.js b/src/array.js
index d30a989..0adbf9d 100644
--- a/src/array.js
+++ b/src/array.js
@@ -879,6 +879,62 @@
 }
 
 
+function ArrayReduce(callback, current) {
+  if (!IS_FUNCTION(callback)) {
+    throw MakeTypeError('called_non_callable', [callback]);
+  }
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping.
+  var length = this.length;
+  var i = 0;
+
+  find_initial: if (%_ArgumentsLength() < 2) {
+    for (; i < length; i++) {
+      current = this[i];
+      if (!IS_UNDEFINED(current) || i in this) {
+        i++;
+        break find_initial;
+      }
+    }
+    throw MakeTypeError('reduce_no_initial', []);
+  }
+
+  for (; i < length; i++) {
+    var element = this[i];
+    if (!IS_UNDEFINED(element) || i in this) {
+      current = callback.call(null, current, element, i, this);
+    }
+  }
+  return current;
+}
+
+function ArrayReduceRight(callback, current) {
+  if (!IS_FUNCTION(callback)) {
+    throw MakeTypeError('called_non_callable', [callback]);
+  }
+  var i = this.length - 1;
+
+  find_initial: if (%_ArgumentsLength() < 2) {
+    for (; i >= 0; i--) {
+      current = this[i];
+      if (!IS_UNDEFINED(current) || i in this) {
+        i--;
+        break find_initial;
+      }
+    }
+    throw MakeTypeError('reduce_no_initial', []);
+  }
+
+  for (; i >= 0; i--) {
+    var element = this[i];
+    if (!IS_UNDEFINED(element) || i in this) {
+      current = callback.call(null, current, element, i, this);
+    }
+  }
+  return current;
+}
+
+
 // -------------------------------------------------------------------
 
 
@@ -917,7 +973,9 @@
     "every", ArrayEvery,
     "map", ArrayMap,
     "indexOf", ArrayIndexOf,
-    "lastIndexOf", ArrayLastIndexOf
+    "lastIndexOf", ArrayLastIndexOf,
+    "reduce", ArrayReduce,
+    "reduceRight", ArrayReduceRight
   ));
 
   // Manipulate the length of some of the functions to meet
@@ -930,7 +988,9 @@
     ArrayMap: 1,
     ArrayIndexOf: 1,
     ArrayLastIndexOf: 1,
-    ArrayPush: 1
+    ArrayPush: 1,
+    ArrayReduce: 1,
+    ArrayReduceRight: 1
   });
 }
 
diff --git a/src/assembler-ia32.cc b/src/assembler-ia32.cc
index 8549261..3a2d3f8 100644
--- a/src/assembler-ia32.cc
+++ b/src/assembler-ia32.cc
@@ -283,6 +283,10 @@
   *pc_++ = (x)
 
 
+#ifdef GENERATED_CODE_COVERAGE
+static void InitCoverageLog();
+#endif
+
 // spare_buffer_
 static byte* spare_buffer_ = NULL;
 
@@ -315,9 +319,11 @@
   // Clear the buffer in debug mode unless it was provided by the
   // caller in which case we can't be sure it's okay to overwrite
   // existing code in it; see CodePatcher::CodePatcher(...).
-  if (kDebug && own_buffer_) {
+#ifdef DEBUG
+  if (own_buffer_) {
     memset(buffer_, 0xCC, buffer_size);  // int3
   }
+#endif
 
   // setup buffer pointers
   ASSERT(buffer_ != NULL);
@@ -329,6 +335,9 @@
   current_position_ = RelocInfo::kNoPosition;
   written_statement_position_ = current_statement_position_;
   written_position_ = current_position_;
+#ifdef GENERATED_CODE_COVERAGE
+  InitCoverageLog();
+#endif
 }
 
 
@@ -2073,9 +2082,9 @@
 
   // Clear the buffer in debug mode. Use 'int3' instructions to make
   // sure to get into problems if we ever run uninitialized code.
-  if (kDebug) {
-    memset(desc.buffer, 0xCC, desc.buffer_size);
-  }
+#ifdef DEBUG
+  memset(desc.buffer, 0xCC, desc.buffer_size);
+#endif
 
   // copy the data
   int pc_delta = desc.buffer - buffer_;
@@ -2202,4 +2211,30 @@
   long_at_put(position, label_loc);
 }
 
+
+#ifdef GENERATED_CODE_COVERAGE
+static FILE* coverage_log = NULL;
+
+
+static void InitCoverageLog() {
+  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
+  if (file_name != NULL) {
+    coverage_log = fopen(file_name, "aw+");
+  }
+}
+
+
+void LogGeneratedCodeCoverage(const char* file_line) {
+  const char* return_address = (&file_line)[-1];
+  char* push_insn = const_cast<char*>(return_address - 12);
+  push_insn[0] = 0xeb;  // Relative branch insn.
+  push_insn[1] = 13;    // Skip over coverage insns.
+  if (coverage_log != NULL) {
+    fprintf(coverage_log, "%s\n", file_line);
+    fflush(coverage_log);
+  }
+}
+
+#endif
+
 } }  // namespace v8::internal
diff --git a/src/assembler.cc b/src/assembler.cc
index ad4b24c..ec0e4fd 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -521,10 +521,10 @@
 ExternalReference::ExternalReference(const IC_Utility& ic_utility)
   : address_(ic_utility.address()) {}
 
-
+#ifdef ENABLE_DEBUGGER_SUPPORT
 ExternalReference::ExternalReference(const Debug_Address& debug_address)
   : address_(debug_address.address()) {}
-
+#endif
 
 ExternalReference::ExternalReference(StatsCounter* counter)
   : address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
@@ -557,29 +557,71 @@
 }
 
 
-ExternalReference ExternalReference::debug_break() {
-  return ExternalReference(FUNCTION_ADDR(Debug::Break));
-}
-
-
 ExternalReference ExternalReference::new_space_start() {
   return ExternalReference(Heap::NewSpaceStart());
 }
 
+
 ExternalReference ExternalReference::new_space_allocation_top_address() {
   return ExternalReference(Heap::NewSpaceAllocationTopAddress());
 }
 
+
 ExternalReference ExternalReference::heap_always_allocate_scope_depth() {
   return ExternalReference(Heap::always_allocate_scope_depth_address());
 }
 
+
 ExternalReference ExternalReference::new_space_allocation_limit_address() {
   return ExternalReference(Heap::NewSpaceAllocationLimitAddress());
 }
 
+
+static double add_two_doubles(double x, double y) {
+  return x + y;
+}
+
+
+static double sub_two_doubles(double x, double y) {
+  return x - y;
+}
+
+
+static double mul_two_doubles(double x, double y) {
+  return x * y;
+}
+
+
+ExternalReference ExternalReference::double_fp_operation(
+    Token::Value operation) {
+  typedef double BinaryFPOperation(double x, double y);
+  BinaryFPOperation* function = NULL;
+  switch (operation) {
+    case Token::ADD:
+      function = &add_two_doubles;
+      break;
+    case Token::SUB:
+      function = &sub_two_doubles;
+      break;
+    case Token::MUL:
+      function = &mul_two_doubles;
+      break;
+    default:
+      UNREACHABLE();
+  }
+  return ExternalReference(FUNCTION_ADDR(function));
+}
+
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ExternalReference ExternalReference::debug_break() {
+  return ExternalReference(FUNCTION_ADDR(Debug::Break));
+}
+
+
 ExternalReference ExternalReference::debug_step_in_fp_address() {
   return ExternalReference(Debug::step_in_fp_addr());
 }
+#endif
 
 } }  // namespace v8::internal
diff --git a/src/assembler.h b/src/assembler.h
index 49c9b90..8abdbc7 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -38,6 +38,7 @@
 #include "runtime.h"
 #include "top.h"
 #include "zone-inl.h"
+#include "token.h"
 
 namespace v8 { namespace internal {
 
@@ -340,29 +341,15 @@
 };
 
 
-// A stack-allocated code region logs a name for the code generated
-// while the region is in effect.  This information is used by the
-// profiler to categorize ticks within generated code.
-class CodeRegion BASE_EMBEDDED {
- public:
-  inline CodeRegion(Assembler* assm, const char *name) : assm_(assm) {
-    LOG(BeginCodeRegionEvent(this, assm, name));
-  }
-  inline ~CodeRegion() {
-    LOG(EndCodeRegionEvent(this, assm_));
-  }
- private:
-  Assembler* assm_;
-};
-
-
 //------------------------------------------------------------------------------
 // External function
 
 //----------------------------------------------------------------------------
 class IC_Utility;
-class Debug_Address;
 class SCTableReference;
+#ifdef ENABLE_DEBUGGER_SUPPORT
+class Debug_Address;
+#endif
 
 // An ExternalReference represents a C++ address called from the generated
 // code. All references to C++ functions and must be encapsulated in an
@@ -380,7 +367,9 @@
 
   explicit ExternalReference(const IC_Utility& ic_utility);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   explicit ExternalReference(const Debug_Address& debug_address);
+#endif
 
   explicit ExternalReference(StatsCounter* counter);
 
@@ -403,9 +392,6 @@
   // Static variable RegExpStack::limit_address()
   static ExternalReference address_of_regexp_stack_limit();
 
-  // Function Debug::Break()
-  static ExternalReference debug_break();
-
   // Static variable Heap::NewSpaceStart()
   static ExternalReference new_space_start();
   static ExternalReference heap_always_allocate_scope_depth();
@@ -414,11 +400,18 @@
   static ExternalReference new_space_allocation_top_address();
   static ExternalReference new_space_allocation_limit_address();
 
-  // Used to check if single stepping is enabled in generated code.
-  static ExternalReference debug_step_in_fp_address();
+  static ExternalReference double_fp_operation(Token::Value operation);
 
   Address address() const {return address_;}
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  // Function Debug::Break()
+  static ExternalReference debug_break();
+
+  // Used to check if single stepping is enabled in generated code.
+  static ExternalReference debug_step_in_fp_address();
+#endif
+
  private:
   explicit ExternalReference(void* address)
     : address_(reinterpret_cast<Address>(address)) {}
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 0a0ed83..eebec74 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -832,12 +832,16 @@
 
 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
   HandleScope scope;
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Debugger::set_compiling_natives(true);
+#endif
   bool result =
       CompileScriptCached(name, source, &natives_cache, NULL, true);
   ASSERT(Top::has_pending_exception() != result);
   if (!result) Top::clear_pending_exception();
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Debugger::set_compiling_natives(false);
+#endif
   return result;
 }
 
@@ -1015,6 +1019,13 @@
             Factory::LookupAsciiSymbol("column_offset"),
             proxy_column_offset,
             common_attributes);
+    Handle<Proxy> proxy_data = Factory::NewProxy(&Accessors::ScriptData);
+    script_descriptors =
+        Factory::CopyAppendProxyDescriptor(
+            script_descriptors,
+            Factory::LookupAsciiSymbol("data"),
+            proxy_data,
+            common_attributes);
     Handle<Proxy> proxy_type = Factory::NewProxy(&Accessors::ScriptType);
     script_descriptors =
         Factory::CopyAppendProxyDescriptor(
@@ -1132,6 +1143,7 @@
                 Handle<JSObject>(js_global->builtins()), DONT_ENUM);
   }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Expose the debug global object in global if a name for it is specified.
   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
     // If loading fails we just bail out without installing the
@@ -1149,6 +1161,7 @@
     SetProperty(js_global, debug_string,
         Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM);
   }
+#endif
 
   return true;
 }
diff --git a/src/builtins-arm.cc b/src/builtins-arm.cc
index 2e6f255..58eeca8 100644
--- a/src/builtins-arm.cc
+++ b/src/builtins-arm.cc
@@ -34,7 +34,7 @@
 namespace v8 { namespace internal {
 
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
@@ -218,8 +218,9 @@
   __ mov(r5, Operand(r4));
   __ mov(r6, Operand(r4));
   __ mov(r7, Operand(r4));
-  if (kR9Available == 1)
+  if (kR9Available == 1) {
     __ mov(r9, Operand(r4));
+  }
 
   // Invoke the code and pass argc as r0.
   __ mov(r0, Operand(r3));
diff --git a/src/builtins-ia32.cc b/src/builtins-ia32.cc
index 0e9de8c..9baeb5e 100644
--- a/src/builtins-ia32.cc
+++ b/src/builtins-ia32.cc
@@ -32,7 +32,7 @@
 namespace v8 { namespace internal {
 
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
@@ -69,10 +69,12 @@
   Label rt_call, allocated;
   if (FLAG_inline_new) {
     Label undo_allocation;
+#ifdef ENABLE_DEBUGGER_SUPPORT
     ExternalReference debug_step_in_fp =
         ExternalReference::debug_step_in_fp_address();
     __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));
     __ j(not_equal, &rt_call);
+#endif
     // Check that function is not a Smi.
     __ test(edi, Immediate(kSmiTagMask));
     __ j(zero, &rt_call);
diff --git a/src/builtins.cc b/src/builtins.cc
index c3935f1..b27974f 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -559,6 +559,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
   Debug::GenerateLoadICDebugBreak(masm);
 }
@@ -597,7 +598,7 @@
 static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {
   Debug::GenerateStubNoRegistersDebugBreak(masm);
 }
-
+#endif
 
 Object* Builtins::builtins_[builtin_count] = { NULL, };
 const char* Builtins::names_[builtin_count] = { NULL, };
diff --git a/src/builtins.h b/src/builtins.h
index 853c90e..4e74a3c 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -83,6 +83,7 @@
   V(FunctionApply,              BUILTIN, UNINITIALIZED)
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 // Define list of builtins used by the debugger implemented in assembly.
 #define BUILTIN_LIST_DEBUG_A(V)                                \
   V(Return_DebugBreak,          BUILTIN, DEBUG_BREAK)          \
@@ -93,7 +94,9 @@
   V(KeyedLoadIC_DebugBreak,     KEYED_LOAD_IC, DEBUG_BREAK)    \
   V(StoreIC_DebugBreak,         STORE_IC, DEBUG_BREAK)         \
   V(KeyedStoreIC_DebugBreak,    KEYED_STORE_IC, DEBUG_BREAK)
-
+#else
+#define BUILTIN_LIST_DEBUG_A(V)
+#endif
 
 // Define list of builtins implemented in JavaScript.
 #define BUILTINS_LIST_JS(V)    \
diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc
index 6fdabc3..9337454 100644
--- a/src/codegen-arm.cc
+++ b/src/codegen-arm.cc
@@ -38,7 +38,8 @@
 
 namespace v8 { namespace internal {
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
+
 
 // -------------------------------------------------------------------------
 // CodeGenState implementation.
@@ -146,13 +147,13 @@
       frame_->EmitPush(r0);
       frame_->CallRuntime(Runtime::kNewContext, 1);  // r0 holds the result
 
-      if (kDebug) {
-        JumpTarget verified_true(this);
-        __ cmp(r0, Operand(cp));
-        verified_true.Branch(eq);
-        __ stop("NewContext: r0 is expected to be the same as cp");
-        verified_true.Bind();
-      }
+#ifdef DEBUG
+      JumpTarget verified_true(this);
+      __ cmp(r0, Operand(cp));
+      verified_true.Branch(eq);
+      __ stop("NewContext: r0 is expected to be the same as cp");
+      verified_true.Bind();
+#endif
       // Update context local.
       __ str(cp, frame_->Context());
     }
@@ -653,37 +654,27 @@
 }
 
 
-class GetPropertyStub : public CodeStub {
- public:
-  GetPropertyStub() { }
-
- private:
-  Major MajorKey() { return GetProperty; }
-  int MinorKey() { return 0; }
-  void Generate(MacroAssembler* masm);
-};
-
-
-class SetPropertyStub : public CodeStub {
- public:
-  SetPropertyStub() { }
-
- private:
-  Major MajorKey() { return SetProperty; }
-  int MinorKey() { return 0; }
-  void Generate(MacroAssembler* masm);
-};
-
-
 class GenericBinaryOpStub : public CodeStub {
  public:
-  explicit GenericBinaryOpStub(Token::Value op) : op_(op) { }
+  GenericBinaryOpStub(Token::Value op,
+                      OverwriteMode mode)
+      : op_(op), mode_(mode) { }
 
  private:
   Token::Value op_;
+  OverwriteMode mode_;
+
+  // Minor key encoding in 16 bits.
+  class ModeBits: public BitField<OverwriteMode, 0, 2> {};
+  class OpBits: public BitField<Token::Value, 2, 14> {};
 
   Major MajorKey() { return GenericBinaryOp; }
-  int MinorKey() { return static_cast<int>(op_); }
+  int MinorKey() {
+    // Encode the parameters in a unique 16 bit value.
+    return OpBits::encode(op_)
+           | ModeBits::encode(mode_);
+  }
+
   void Generate(MacroAssembler* masm);
 
   const char* GetName() {
@@ -708,7 +699,8 @@
 };
 
 
-void CodeGenerator::GenericBinaryOperation(Token::Value op) {
+void CodeGenerator::GenericBinaryOperation(Token::Value op,
+                                           OverwriteMode overwrite_mode) {
   VirtualFrame::SpilledScope spilled_scope(this);
   // sp[0] : y
   // sp[1] : x
@@ -727,7 +719,7 @@
     case Token::SAR: {
       frame_->EmitPop(r0);  // r0 : y
       frame_->EmitPop(r1);  // r1 : x
-      GenericBinaryOpStub stub(op);
+      GenericBinaryOpStub stub(op, overwrite_mode);
       frame_->CallStub(&stub, 0);
       break;
     }
@@ -767,11 +759,13 @@
   DeferredInlineSmiOperation(CodeGenerator* generator,
                              Token::Value op,
                              int value,
-                             bool reversed)
+                             bool reversed,
+                             OverwriteMode overwrite_mode)
       : DeferredCode(generator),
         op_(op),
         value_(value),
-        reversed_(reversed) {
+        reversed_(reversed),
+        overwrite_mode_(overwrite_mode) {
     set_comment("[ DeferredInlinedSmiOperation");
   }
 
@@ -781,6 +775,7 @@
   Token::Value op_;
   int value_;
   bool reversed_;
+  OverwriteMode overwrite_mode_;
 };
 
 
@@ -844,7 +839,7 @@
       break;
   }
 
-  GenericBinaryOpStub igostub(op_);
+  GenericBinaryOpStub igostub(op_, overwrite_mode_);
   Result arg0 = generator()->allocator()->Allocate(r1);
   ASSERT(arg0.is_valid());
   Result arg1 = generator()->allocator()->Allocate(r0);
@@ -856,7 +851,8 @@
 
 void CodeGenerator::SmiOperation(Token::Value op,
                                  Handle<Object> value,
-                                 bool reversed) {
+                                 bool reversed,
+                                 OverwriteMode mode) {
   VirtualFrame::SpilledScope spilled_scope(this);
   // NOTE: This is an attempt to inline (a bit) more of the code for
   // some possible smi operations (like + and -) when (at least) one
@@ -875,7 +871,7 @@
   switch (op) {
     case Token::ADD: {
       DeferredCode* deferred =
-        new DeferredInlineSmiOperation(this, op, int_value, reversed);
+        new DeferredInlineSmiOperation(this, op, int_value, reversed, mode);
 
       __ add(r0, r0, Operand(value), SetCC);
       deferred->enter()->Branch(vs);
@@ -887,7 +883,7 @@
 
     case Token::SUB: {
       DeferredCode* deferred =
-        new DeferredInlineSmiOperation(this, op, int_value, reversed);
+        new DeferredInlineSmiOperation(this, op, int_value, reversed, mode);
 
       if (!reversed) {
         __ sub(r0, r0, Operand(value), SetCC);
@@ -905,7 +901,7 @@
     case Token::BIT_XOR:
     case Token::BIT_AND: {
       DeferredCode* deferred =
-        new DeferredInlineSmiOperation(this, op, int_value, reversed);
+        new DeferredInlineSmiOperation(this, op, int_value, reversed, mode);
       __ tst(r0, Operand(kSmiTagMask));
       deferred->enter()->Branch(ne);
       switch (op) {
@@ -925,12 +921,12 @@
         __ mov(ip, Operand(value));
         frame_->EmitPush(ip);
         frame_->EmitPush(r0);
-        GenericBinaryOperation(op);
+        GenericBinaryOperation(op, mode);
 
       } else {
         int shift_value = int_value & 0x1f;  // least significant 5 bits
         DeferredCode* deferred =
-          new DeferredInlineSmiOperation(this, op, shift_value, false);
+          new DeferredInlineSmiOperation(this, op, shift_value, false, mode);
         __ tst(r0, Operand(kSmiTagMask));
         deferred->enter()->Branch(ne);
         __ mov(r2, Operand(r0, ASR, kSmiTagSize));  // remove tags
@@ -982,7 +978,7 @@
         frame_->EmitPush(ip);
         frame_->EmitPush(r0);
       }
-      GenericBinaryOperation(op);
+      GenericBinaryOperation(op, mode);
       break;
   }
 
@@ -1427,13 +1423,13 @@
   } else {
     frame_->CallRuntime(Runtime::kPushContext, 1);
   }
-  if (kDebug) {
-    JumpTarget verified_true(this);
-    __ cmp(r0, Operand(cp));
-    verified_true.Branch(eq);
-    __ stop("PushContext: r0 is expected to be the same as cp");
-    verified_true.Bind();
-  }
+#ifdef DEBUG
+  JumpTarget verified_true(this);
+  __ cmp(r0, Operand(cp));
+  verified_true.Branch(eq);
+  __ stop("PushContext: r0 is expected to be the same as cp");
+  verified_true.Bind();
+#endif
   // Update context local.
   __ str(cp, frame_->Context());
   ASSERT(frame_->height() == original_height);
@@ -1487,8 +1483,8 @@
   // Test for a Smi value in a HeapNumber.
   __ tst(r0, Operand(kSmiTagMask));
   is_smi.Branch(eq);
-  __ ldr(r1, MemOperand(r0, HeapObject::kMapOffset - kHeapObjectTag));
-  __ ldrb(r1, MemOperand(r1, Map::kInstanceTypeOffset - kHeapObjectTag));
+  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
   __ cmp(r1, Operand(HEAP_NUMBER_TYPE));
   default_target->Branch(ne);
   frame_->EmitPush(r0);
@@ -2339,7 +2335,9 @@
   VirtualFrame::SpilledScope spilled_scope(this);
   Comment cmnt(masm_, "[ DebuggerStatament");
   CodeForStatementPosition(node);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   frame_->CallRuntime(Runtime::kDebugBreak, 0);
+#endif
   // Ignore the return value.
   ASSERT(frame_->height() == original_height);
 }
@@ -2523,7 +2521,9 @@
 
   if (s->is_eval_scope()) {
     Label next, fast;
-    if (!context.is(tmp)) __ mov(tmp, Operand(context));
+    if (!context.is(tmp)) {
+      __ mov(tmp, Operand(context));
+    }
     __ bind(&next);
     // Terminate at global context.
     __ ldr(tmp2, FieldMemOperand(tmp, HeapObject::kMapOffset));
@@ -2934,15 +2934,24 @@
       LoadAndSpill(node->value());
 
     } else {
+      // +=, *= and similar binary assignments.
+      // Get the old value of the lhs.
       target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
       Literal* literal = node->value()->AsLiteral();
+      bool overwrite =
+          (node->value()->AsBinaryOperation() != NULL &&
+           node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
       if (literal != NULL && literal->handle()->IsSmi()) {
-        SmiOperation(node->binary_op(), literal->handle(), false);
+        SmiOperation(node->binary_op(),
+                     literal->handle(),
+                     false,
+                     overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
         frame_->EmitPush(r0);
 
       } else {
         LoadAndSpill(node->value());
-        GenericBinaryOperation(node->binary_op());
+        GenericBinaryOperation(node->binary_op(),
+                               overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
         frame_->EmitPush(r0);
       }
     }
@@ -3822,19 +3831,39 @@
     // is a literal small integer.
     Literal* lliteral = node->left()->AsLiteral();
     Literal* rliteral = node->right()->AsLiteral();
+    // NOTE: The code below assumes that the slow cases (calls to runtime)
+    // never return a constant/immutable object.
+    bool overwrite_left =
+        (node->left()->AsBinaryOperation() != NULL &&
+         node->left()->AsBinaryOperation()->ResultOverwriteAllowed());
+    bool overwrite_right =
+        (node->right()->AsBinaryOperation() != NULL &&
+         node->right()->AsBinaryOperation()->ResultOverwriteAllowed());
 
     if (rliteral != NULL && rliteral->handle()->IsSmi()) {
       LoadAndSpill(node->left());
-      SmiOperation(node->op(), rliteral->handle(), false);
+      SmiOperation(node->op(),
+                   rliteral->handle(),
+                   false,
+                   overwrite_right ? OVERWRITE_RIGHT : NO_OVERWRITE);
 
     } else if (lliteral != NULL && lliteral->handle()->IsSmi()) {
       LoadAndSpill(node->right());
-      SmiOperation(node->op(), lliteral->handle(), true);
+      SmiOperation(node->op(),
+                   lliteral->handle(),
+                   true,
+                   overwrite_left ? OVERWRITE_LEFT : NO_OVERWRITE);
 
     } else {
+      OverwriteMode overwrite_mode = NO_OVERWRITE;
+      if (overwrite_left) {
+        overwrite_mode = OVERWRITE_LEFT;
+      } else if (overwrite_right) {
+        overwrite_mode = OVERWRITE_RIGHT;
+      }
       LoadAndSpill(node->left());
       LoadAndSpill(node->right());
-      GenericBinaryOperation(node->op());
+      GenericBinaryOperation(node->op(), overwrite_mode);
     }
     frame_->EmitPush(r0);
   }
@@ -4067,7 +4096,8 @@
 
 
 #undef __
-#define __ masm->
+#define __ ACCESS_MASM(masm)
+
 
 Handle<String> Reference::GetName() {
   ASSERT(type_ == NAMED);
@@ -4305,167 +4335,80 @@
 }
 
 
-void GetPropertyStub::Generate(MacroAssembler* masm) {
-  // sp[0]: key
-  // sp[1]: receiver
-  Label slow, fast;
-  // Get the key and receiver object from the stack.
-  __ ldm(ia, sp, r0.bit() | r1.bit());
-  // Check that the key is a smi.
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(ne, &slow);
-  __ mov(r0, Operand(r0, ASR, kSmiTagSize));
-  // Check that the object isn't a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &slow);
-
-  // Check that the object is some kind of JS object EXCEPT JS Value type.
-  // In the case that the object is a value-wrapper object,
-  // we enter the runtime system to make sure that indexing into string
-  // objects work as intended.
-  ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
-  __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
-  __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
-  __ cmp(r2, Operand(JS_OBJECT_TYPE));
-  __ b(lt, &slow);
-
-  // Get the elements array of the object.
-  __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
-  // Check that the object is in fast mode (not dictionary).
-  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
-  __ cmp(r3, Operand(Factory::hash_table_map()));
-  __ b(eq, &slow);
-  // Check that the key (index) is within bounds.
-  __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset));
-  __ cmp(r0, Operand(r3));
-  __ b(lo, &fast);
-
-  // Slow case: Push extra copies of the arguments (2).
+static void HandleBinaryOpSlowCases(MacroAssembler* masm,
+                                    Label* not_smi,
+                                    const Builtins::JavaScript& builtin,
+                                    Token::Value operation,
+                                    int swi_number,
+                                    OverwriteMode mode) {
+  Label slow;
+  if (mode == NO_OVERWRITE) {
+    __ bind(not_smi);
+  }
   __ bind(&slow);
-  __ ldm(ia, sp, r0.bit() | r1.bit());
-  __ stm(db_w, sp, r0.bit() | r1.bit());
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
+  __ push(r1);
+  __ push(r0);
+  __ mov(r0, Operand(1));  // Set number of arguments.
+  __ InvokeBuiltin(builtin, JUMP_JS);  // Tail call.
 
-  // Fast case: Do the load.
-  __ bind(&fast);
-  __ add(r3, r1, Operand(Array::kHeaderSize - kHeapObjectTag));
-  __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2));
-  __ cmp(r0, Operand(Factory::the_hole_value()));
-  // In case the loaded value is the_hole we have to consult GetProperty
-  // to ensure the prototype chain is searched.
-  __ b(eq, &slow);
-
-  __ StubReturn(1);
-}
-
-
-void SetPropertyStub::Generate(MacroAssembler* masm) {
-  // r0 : value
-  // sp[0] : key
-  // sp[1] : receiver
-
-  Label slow, fast, array, extra, exit;
-  // Get the key and the object from the stack.
-  __ ldm(ia, sp, r1.bit() | r3.bit());  // r1 = key, r3 = receiver
-  // Check that the key is a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(ne, &slow);
-  // Check that the object isn't a smi.
-  __ tst(r3, Operand(kSmiTagMask));
-  __ b(eq, &slow);
-  // Get the type of the object from its map.
-  __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
-  __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
-  // Check if the object is a JS array or not.
-  __ cmp(r2, Operand(JS_ARRAY_TYPE));
-  __ b(eq, &array);
-  // Check that the object is some kind of JS object.
-  __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
-  __ b(lt, &slow);
-
-
-  // Object case: Check key against length in the elements array.
-  __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset));
-  // Check that the object is in fast mode (not dictionary).
-  __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
-  __ cmp(r2, Operand(Factory::hash_table_map()));
-  __ b(eq, &slow);
-  // Untag the key (for checking against untagged length in the fixed array).
-  __ mov(r1, Operand(r1, ASR, kSmiTagSize));
-  // Compute address to store into and check array bounds.
-  __ add(r2, r3, Operand(Array::kHeaderSize - kHeapObjectTag));
-  __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2));
-  __ ldr(ip, FieldMemOperand(r3, Array::kLengthOffset));
-  __ cmp(r1, Operand(ip));
-  __ b(lo, &fast);
-
-
-  // Slow case: Push extra copies of the arguments (3).
-  __ bind(&slow);
-  __ ldm(ia, sp, r1.bit() | r3.bit());  // r0 == value, r1 == key, r3 == object
-  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
-
-
-  // Extra capacity case: Check if there is extra capacity to
-  // perform the store and update the length. Used for adding one
-  // element to the array by writing to array[array.length].
-  // r0 == value, r1 == key, r2 == elements, r3 == object
-  __ bind(&extra);
-  __ b(ne, &slow);  // do not leave holes in the array
-  __ mov(r1, Operand(r1, ASR, kSmiTagSize));  // untag
-  __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset));
-  __ cmp(r1, Operand(ip));
-  __ b(hs, &slow);
-  __ mov(r1, Operand(r1, LSL, kSmiTagSize));  // restore tag
-  __ add(r1, r1, Operand(1 << kSmiTagSize));  // and increment
-  __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset));
-  __ mov(r3, Operand(r2));
-  // NOTE: Computing the address to store into must take the fact
-  // that the key has been incremented into account.
-  int displacement = Array::kHeaderSize - kHeapObjectTag -
-      ((1 << kSmiTagSize) * 2);
-  __ add(r2, r2, Operand(displacement));
-  __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
-  __ b(&fast);
-
-
-  // Array case: Get the length and the elements array from the JS
-  // array. Check that the array is in fast mode; if it is the
-  // length is always a smi.
-  // r0 == value, r3 == object
-  __ bind(&array);
-  __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset));
-  __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
-  __ cmp(r1, Operand(Factory::hash_table_map()));
-  __ b(eq, &slow);
-
-  // Check the key against the length in the array, compute the
-  // address to store into and fall through to fast case.
-  __ ldr(r1, MemOperand(sp));
-  // r0 == value, r1 == key, r2 == elements, r3 == object.
-  __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset));
-  __ cmp(r1, Operand(ip));
-  __ b(hs, &extra);
-  __ mov(r3, Operand(r2));
-  __ add(r2, r2, Operand(Array::kHeaderSize - kHeapObjectTag));
-  __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
-
-
-  // Fast case: Do the store.
-  // r0 == value, r2 == address to store into, r3 == elements
-  __ bind(&fast);
-  __ str(r0, MemOperand(r2));
-  // Skip write barrier if the written value is a smi.
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &exit);
-  // Update write barrier for the elements array address.
-  __ sub(r1, r2, Operand(r3));
-  __ RecordWrite(r3, r1, r2);
-  __ bind(&exit);
-  __ StubReturn(1);
+  // Could it be a double-double op?  If we already have a place to put
+  // the answer then we can do the op and skip the builtin and runtime call.
+  if (mode != NO_OVERWRITE) {
+    __ bind(not_smi);
+    __ tst(r0, Operand(kSmiTagMask));
+    __ b(eq, &slow);  // We can't handle a Smi-double combination yet.
+    __ tst(r1, Operand(kSmiTagMask));
+    __ b(eq, &slow);  // We can't handle a Smi-double combination yet.
+    // Get map of r0 into r2.
+    __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
+    // Get type of r0 into r3.
+    __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset));
+    __ cmp(r3, Operand(HEAP_NUMBER_TYPE));
+    __ b(ne, &slow);
+    // Get type of r1 into r3.
+    __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+    // Check they are both the same map (heap number map).
+    __ cmp(r2, r3);
+    __ b(ne, &slow);
+    // Both are doubles.
+    // Calling convention says that second double is in r2 and r3.
+    __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
+    __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
+    __ push(lr);
+    if (mode == OVERWRITE_LEFT) {
+      __ push(r1);
+    } else {
+      __ push(r0);
+    }
+    // Calling convention says that first double is in r0 and r1.
+    __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
+    __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
+    // Call C routine that may not cause GC or other trouble.
+    __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
+#if !defined(__arm__)
+    // Notify the simulator that we are calling an add routine in C.
+    __ swi(swi_number);
+#else
+    // Actually call the add routine written in C.
+    __ Call(r5);
+#endif
+    // Store answer in the overwritable heap number.
+    __ pop(r4);
+#if !defined(__ARM_EABI__) && defined(__arm__)
+    // Double returned in fp coprocessor register 0 and 1, encoded as register
+    // cr8.  Offsets must be divisible by 4 for coprocessor so we need to
+    // substract the tag from r4.
+    __ sub(r5, r4, Operand(kHeapObjectTag));
+    __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
+#else
+    // Double returned in fp coprocessor register 0 and 1.
+    __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
+    __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize));
+#endif
+    __ mov(r0, Operand(r4));
+    // And we are done.
+    __ pop(pc);
+  }
 }
 
 
@@ -4474,89 +4417,84 @@
   // r0 : y
   // result : r0
 
+  // All ops need to know whether we are dealing with two Smis.  Set up r2 to
+  // tell us that.
+  __ orr(r2, r1, Operand(r0));  // r2 = x | y;
+
   switch (op_) {
     case Token::ADD: {
-      Label slow, exit;
-      // fast path
-      __ orr(r2, r1, Operand(r0));  // r2 = x | y;
-      __ add(r0, r1, Operand(r0), SetCC);  // add y optimistically
-      // go slow-path in case of overflow
-      __ b(vs, &slow);
-      // go slow-path in case of non-smi operands
-      ASSERT(kSmiTag == 0);  // adjust code below
+      Label not_smi;
+      // Fast path.
+      ASSERT(kSmiTag == 0);  // Adjust code below.
       __ tst(r2, Operand(kSmiTagMask));
-      __ b(eq, &exit);
-      // slow path
-      __ bind(&slow);
-      __ sub(r0, r0, Operand(r1));  // revert optimistic add
-      __ push(r1);
-      __ push(r0);
-      __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin(Builtins::ADD, JUMP_JS);
-      // done
-      __ bind(&exit);
+      __ b(ne, &not_smi);
+      __ add(r0, r1, Operand(r0), SetCC);  // Add y optimistically.
+      // Return if no overflow.
+      __ Ret(vc);
+      __ sub(r0, r0, Operand(r1));  // Revert optimistic add.
+
+      HandleBinaryOpSlowCases(masm,
+                              &not_smi,
+                              Builtins::ADD,
+                              Token::ADD,
+                              assembler::arm::simulator_fp_add,
+                              mode_);
       break;
     }
 
     case Token::SUB: {
-      Label slow, exit;
-      // fast path
-      __ orr(r2, r1, Operand(r0));  // r2 = x | y;
-      __ sub(r3, r1, Operand(r0), SetCC);  // subtract y optimistically
-      // go slow-path in case of overflow
-      __ b(vs, &slow);
-      // go slow-path in case of non-smi operands
-      ASSERT(kSmiTag == 0);  // adjust code below
+      Label not_smi;
+      // Fast path.
+      ASSERT(kSmiTag == 0);  // Adjust code below.
       __ tst(r2, Operand(kSmiTagMask));
-      __ mov(r0, Operand(r3), LeaveCC, eq);  // conditionally set r0 to result
-      __ b(eq, &exit);
-      // slow path
-      __ bind(&slow);
-      __ push(r1);
-      __ push(r0);
-      __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin(Builtins::SUB, JUMP_JS);
-      // done
-      __ bind(&exit);
+      __ b(ne, &not_smi);
+      __ sub(r0, r1, Operand(r0), SetCC);  // Subtract y optimistically.
+      // Return if no overflow.
+      __ Ret(vc);
+      __ sub(r0, r1, Operand(r0));  // Revert optimistic subtract.
+
+      HandleBinaryOpSlowCases(masm,
+                              &not_smi,
+                              Builtins::SUB,
+                              Token::SUB,
+                              assembler::arm::simulator_fp_sub,
+                              mode_);
       break;
     }
 
     case Token::MUL: {
-      Label slow, exit;
-      // tag check
-      __ orr(r2, r1, Operand(r0));  // r2 = x | y;
+      Label not_smi, slow;
       ASSERT(kSmiTag == 0);  // adjust code below
       __ tst(r2, Operand(kSmiTagMask));
-      __ b(ne, &slow);
-      // remove tag from one operand (but keep sign), so that result is smi
+      __ b(ne, &not_smi);
+      // Remove tag from one operand (but keep sign), so that result is Smi.
       __ mov(ip, Operand(r0, ASR, kSmiTagSize));
-      // do multiplication
-      __ smull(r3, r2, r1, ip);  // r3 = lower 32 bits of ip*r1
-      // go slow on overflows (overflow bit is not set)
+      // Do multiplication
+      __ smull(r3, r2, r1, ip);  // r3 = lower 32 bits of ip*r1.
+      // Go slow on overflows (overflow bit is not set).
       __ mov(ip, Operand(r3, ASR, 31));
       __ cmp(ip, Operand(r2));  // no overflow if higher 33 bits are identical
       __ b(ne, &slow);
-      // go slow on zero result to handle -0
+      // Go slow on zero result to handle -0.
       __ tst(r3, Operand(r3));
       __ mov(r0, Operand(r3), LeaveCC, ne);
-      __ b(ne, &exit);
-      // slow case
+      __ Ret(ne);
+      // Slow case.
       __ bind(&slow);
-      __ push(r1);
-      __ push(r0);
-      __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin(Builtins::MUL, JUMP_JS);
-      // done
-      __ bind(&exit);
+
+      HandleBinaryOpSlowCases(masm,
+                              &not_smi,
+                              Builtins::MUL,
+                              Token::MUL,
+                              assembler::arm::simulator_fp_mul,
+                              mode_);
       break;
     }
 
     case Token::BIT_OR:
     case Token::BIT_AND:
     case Token::BIT_XOR: {
-      Label slow, exit;
-      // tag check
-      __ orr(r2, r1, Operand(r0));  // r2 = x | y;
+      Label slow;
       ASSERT(kSmiTag == 0);  // adjust code below
       __ tst(r2, Operand(kSmiTagMask));
       __ b(ne, &slow);
@@ -4566,7 +4504,7 @@
         case Token::BIT_XOR: __ eor(r0, r0, Operand(r1)); break;
         default: UNREACHABLE();
       }
-      __ b(&exit);
+      __ Ret();
       __ bind(&slow);
       __ push(r1);  // restore stack
       __ push(r0);
@@ -4584,16 +4522,13 @@
         default:
           UNREACHABLE();
       }
-      __ bind(&exit);
       break;
     }
 
     case Token::SHL:
     case Token::SHR:
     case Token::SAR: {
-      Label slow, exit;
-      // tag check
-      __ orr(r2, r1, Operand(r0));  // r2 = x | y;
+      Label slow;
       ASSERT(kSmiTag == 0);  // adjust code below
       __ tst(r2, Operand(kSmiTagMask));
       __ b(ne, &slow);
@@ -4633,7 +4568,7 @@
       // tag result and store it in r0
       ASSERT(kSmiTag == 0);  // adjust code below
       __ mov(r0, Operand(r3, LSL, kSmiTagSize));
-      __ b(&exit);
+      __ Ret();
       // slow case
       __ bind(&slow);
       __ push(r1);  // restore stack
@@ -4645,13 +4580,13 @@
         case Token::SHL: __ InvokeBuiltin(Builtins::SHL, JUMP_JS); break;
         default: UNREACHABLE();
       }
-      __ bind(&exit);
       break;
     }
 
     default: UNREACHABLE();
   }
-  __ Ret();
+  // This code should be unreachable.
+  __ stop("Unreachable");
 }
 
 
@@ -4721,7 +4656,11 @@
   __ mov(cp, Operand(0), LeaveCC, eq);
   // Restore cp otherwise.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
-  if (kDebug && FLAG_debug_code) __ mov(lr, Operand(pc));
+#ifdef DEBUG
+  if (FLAG_debug_code) {
+    __ mov(lr, Operand(pc));
+  }
+#endif
   __ pop(pc);
 }
 
@@ -4784,7 +4723,11 @@
   __ mov(cp, Operand(0), LeaveCC, eq);
   // Restore cp otherwise.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
-  if (kDebug && FLAG_debug_code) __ mov(lr, Operand(pc));
+#ifdef DEBUG
+  if (FLAG_debug_code) {
+    __ mov(lr, Operand(pc));
+  }
+#endif
   __ pop(pc);
 }
 
@@ -5043,9 +4986,11 @@
   }
   __ ldr(ip, MemOperand(ip));  // deref address
 
-  // Branch and link to JSEntryTrampoline
+  // Branch and link to JSEntryTrampoline.  We don't use the double underscore
+  // macro for the add instruction because we don't want the coverage tool
+  // inserting instructions here after we read the pc.
   __ mov(lr, Operand(pc));
-  __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+  masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
 
   // Unlink this frame from the handler chain. When reading the
   // address of the next handler, there is no need to use the address
@@ -5057,6 +5002,7 @@
   // No need to restore registers
   __ add(sp, sp, Operand(StackHandlerConstants::kSize));
 
+
   __ bind(&exit);  // r0 holds result
   // Restore the top frame descriptors from the stack.
   __ pop(r3);
@@ -5068,7 +5014,9 @@
 
   // Restore callee-saved registers and return.
 #ifdef DEBUG
-  if (FLAG_debug_code) __ mov(lr, Operand(pc));
+  if (FLAG_debug_code) {
+    __ mov(lr, Operand(pc));
+  }
 #endif
   __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
 }
diff --git a/src/codegen-arm.h b/src/codegen-arm.h
index b072f75..48b92ea 100644
--- a/src/codegen-arm.h
+++ b/src/codegen-arm.h
@@ -35,9 +35,6 @@
 class RegisterAllocator;
 class RegisterFile;
 
-// Mode to overwrite BinaryExpression values.
-enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
-
 enum InitState { CONST_INIT, NOT_CONST_INIT };
 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
@@ -292,10 +289,13 @@
 
   void ToBoolean(JumpTarget* true_target, JumpTarget* false_target);
 
-  void GenericBinaryOperation(Token::Value op);
+  void GenericBinaryOperation(Token::Value op, OverwriteMode overwrite_mode);
   void Comparison(Condition cc, bool strict = false);
 
-  void SmiOperation(Token::Value op, Handle<Object> value, bool reversed);
+  void SmiOperation(Token::Value op,
+                    Handle<Object> value,
+                    bool reversed,
+                    OverwriteMode mode);
 
   void CallWithArguments(ZoneList<Expression*>* arguments, int position);
 
diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc
index 663f235..fb2f8bf 100644
--- a/src/codegen-ia32.cc
+++ b/src/codegen-ia32.cc
@@ -37,7 +37,7 @@
 
 namespace v8 { namespace internal {
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 // -------------------------------------------------------------------------
 // CodeGenState implementation.
@@ -1274,12 +1274,9 @@
                                                     smi_value,
                                                     overwrite_mode);
         __ Set(answer.reg(), Immediate(value));
-        if (operand->is_register()) {
-          __ sub(answer.reg(), Operand(operand->reg()));
-        } else {
-          ASSERT(operand->is_constant());
-          __ sub(Operand(answer.reg()), Immediate(operand->handle()));
-        }
+        // We are in the reversed case so they can't both be Smi constants.
+        ASSERT(operand->is_register());
+        __ sub(answer.reg(), Operand(operand->reg()));
       } else {
         operand->ToRegister();
         frame_->Spill(operand->reg());
@@ -1374,23 +1371,26 @@
         operand->ToRegister();
         __ test(operand->reg(), Immediate(kSmiTagMask));
         deferred->enter()->Branch(not_zero, operand, not_taken);
-        Result answer = allocator()->Allocate();
-        ASSERT(answer.is_valid());
-        __ mov(answer.reg(), operand->reg());
-        ASSERT(kSmiTag == 0);  // adjust code if not the case
-        // We do no shifts, only the Smi conversion, if shift_value is 1.
-        if (shift_value == 0) {
-          __ sar(answer.reg(), kSmiTagSize);
-        } else if (shift_value > 1) {
-          __ shl(answer.reg(), shift_value - 1);
+        if (shift_value != 0) {
+          Result answer = allocator()->Allocate();
+          ASSERT(answer.is_valid());
+          __ mov(answer.reg(), operand->reg());
+          ASSERT(kSmiTag == 0);  // adjust code if not the case
+          // We do no shifts, only the Smi conversion, if shift_value is 1.
+          if (shift_value > 1) {
+            __ shl(answer.reg(), shift_value - 1);
+          }
+          // Convert int result to Smi, checking that it is in int range.
+          ASSERT(kSmiTagSize == times_2);  // adjust code if not the case
+          __ add(answer.reg(), Operand(answer.reg()));
+          deferred->enter()->Branch(overflow, operand, not_taken);
+          operand->Unuse();
+          deferred->BindExit(&answer);
+          frame_->Push(&answer);
+        } else {
+          deferred->BindExit(operand);
+          frame_->Push(operand);
         }
-        // Convert int result to Smi, checking that it is in int range.
-        ASSERT(kSmiTagSize == times_2);  // adjust code if not the case
-        __ add(answer.reg(), Operand(answer.reg()));
-        deferred->enter()->Branch(overflow, operand, not_taken);
-        operand->Unuse();
-        deferred->BindExit(&answer);
-        frame_->Push(&answer);
       }
       break;
     }
@@ -1411,11 +1411,7 @@
       deferred->enter()->Branch(not_zero, operand, not_taken);
       frame_->Spill(operand->reg());
       if (op == Token::BIT_AND) {
-        if (int_value == 0) {
-          __ xor_(Operand(operand->reg()), operand->reg());
-        } else {
-          __ and_(Operand(operand->reg()), Immediate(value));
-        }
+        __ and_(Operand(operand->reg()), Immediate(value));
       } else if (op == Token::BIT_XOR) {
         if (int_value != 0) {
           __ xor_(Operand(operand->reg()), Immediate(value));
@@ -2009,18 +2005,18 @@
 
   // Add a label for checking the size of the code used for returning.
   Label check_exit_codesize;
-  __ bind(&check_exit_codesize);
+  masm_->bind(&check_exit_codesize);
 
   // Leave the frame and return popping the arguments and the
   // receiver.
   frame_->Exit();
-  __ ret((scope_->num_parameters() + 1) * kPointerSize);
+  masm_->ret((scope_->num_parameters() + 1) * kPointerSize);
   DeleteFrame();
 
   // Check that the size of the code used for returning matches what is
   // expected by the debugger.
   ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
-            __ SizeOfCodeGeneratedSince(&check_exit_codesize));
+            masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
 }
 
 
@@ -2143,7 +2139,7 @@
                  times_1, 0x0, RelocInfo::INTERNAL_REFERENCE));
   smi_value.Unuse();
   // Calculate address to overwrite later with actual address of table.
-  int32_t jump_table_ref = __ pc_offset() - sizeof(int32_t);
+  int32_t jump_table_ref = masm_->pc_offset() - sizeof(int32_t);
   __ Align(4);
   Label table_start;
   __ bind(&table_start);
@@ -3179,10 +3175,12 @@
   ASSERT(!in_spilled_code());
   Comment cmnt(masm_, "[ DebuggerStatement");
   CodeForStatementPosition(node);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Spill everything, even constants, to the frame.
   frame_->SpillAll();
   frame_->CallRuntime(Runtime::kDebugBreak, 0);
   // Ignore the return value.
+#endif
 }
 
 
@@ -3384,7 +3382,9 @@
     // Loop up the context chain.  There is no frame effect so it is
     // safe to use raw labels here.
     Label next, fast;
-    if (!context.reg().is(tmp.reg())) __ mov(tmp.reg(), context.reg());
+    if (!context.reg().is(tmp.reg())) {
+      __ mov(tmp.reg(), context.reg());
+    }
     __ bind(&next);
     // Terminate at global context.
     __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
@@ -3933,6 +3933,9 @@
 
     } else {
       Literal* literal = node->value()->AsLiteral();
+      bool overwrite_value =
+          (node->value()->AsBinaryOperation() != NULL &&
+           node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
       Variable* right_var = node->value()->AsVariableProxy()->AsVariable();
       // There are two cases where the target is not read in the right hand
       // side, that are easy to test for: the right hand side is a literal,
@@ -3945,7 +3948,9 @@
         target.GetValue(NOT_INSIDE_TYPEOF);
       }
       Load(node->value());
-      GenericBinaryOperation(node->binary_op(), node->type());
+      GenericBinaryOperation(node->binary_op(),
+                             node->type(),
+                             overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
     }
 
     if (var != NULL &&
@@ -5268,8 +5273,11 @@
   // instruction.
   ASSERT(value.is_register() && value.reg().is(eax));
   // The delta from the start of the map-compare instruction to the
-  // test eax instruction.
-  int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site());
+  // test eax instruction.  We use masm_ directly here instead of the
+  // double underscore macro because the macro sometimes uses macro
+  // expansion to turn into something that can't return a value.  This
+  // is encountered when doing generated code coverage tests.
+  int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
   __ test(value.reg(), Immediate(-delta_to_patch_site));
   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
 
@@ -5284,7 +5292,7 @@
 
 
 #undef __
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 Handle<String> Reference::GetName() {
   ASSERT(type_ == NAMED);
@@ -5369,7 +5377,9 @@
         // Initially, use an invalid map. The map is patched in the IC
         // initialization code.
         __ bind(deferred->patch_site());
-        __ cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
+        // Use masm-> here instead of the double underscore macro since extra
+        // coverage code can interfere with the patching.
+        masm->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
                Immediate(Factory::null_value()));
         deferred->enter()->Branch(not_equal, &receiver, &key, not_taken);
 
@@ -5566,7 +5576,7 @@
 
 
 #undef __
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left,
                                                          Result* right) {
@@ -5900,7 +5910,7 @@
 
 
 #undef __
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
   // Perform fast-case smi code for the operation (eax <op> ebx) and
@@ -6225,7 +6235,9 @@
       }
 
       // SHR should return uint32 - go to runtime for non-smi/negative result.
-      if (op_ == Token::SHR) __ bind(&non_smi_result);
+      if (op_ == Token::SHR) {
+        __ bind(&non_smi_result);
+      }
       __ mov(eax, Operand(esp, 1 * kPointerSize));
       __ mov(edx, Operand(esp, 2 * kPointerSize));
       break;
diff --git a/src/codegen-ia32.h b/src/codegen-ia32.h
index 24a57a0..a39bc58 100644
--- a/src/codegen-ia32.h
+++ b/src/codegen-ia32.h
@@ -35,9 +35,6 @@
 class RegisterAllocator;
 class RegisterFile;
 
-// Mode to overwrite BinaryExpression values.
-enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
-
 enum InitState { CONST_INIT, NOT_CONST_INIT };
 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
@@ -435,7 +432,7 @@
   void GenericBinaryOperation(
       Token::Value op,
       SmiAnalysis* type,
-      const OverwriteMode overwrite_mode = NO_OVERWRITE);
+      OverwriteMode overwrite_mode);
 
   // If possible, combine two constant smi values using op to produce
   // a smi result, and push it on the virtual frame, all at compile time.
diff --git a/src/codegen.cc b/src/codegen.cc
index edc498d..ed7ee2f 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -304,8 +304,10 @@
                                  node->is_expression(), false, script_,
                                  node->inferred_name());
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger that a new function has been added.
   Debugger::OnNewFunction(function);
+#endif
 
   // Set the expected number of properties for instances and return
   // the resulting function.
diff --git a/src/codegen.h b/src/codegen.h
index dd43cc0..54fe330 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -71,6 +71,11 @@
 //   CodeForStatementPosition
 //   CodeForSourcePosition
 
+
+// Mode to overwrite BinaryExpression values.
+enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
+
+
 #ifdef ARM
 #include "codegen-arm.h"
 #else
diff --git a/src/compiler.cc b/src/compiler.cc
index 63fed4a..62e838e 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -92,8 +92,10 @@
   StackGuard guard;
   PostponeInterruptsScope postpone;
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger
   Debugger::OnBeforeCompile(script);
+#endif
 
   // Only allow non-global compiles for eval.
   ASSERT(is_eval || is_global);
@@ -160,8 +162,10 @@
   // the instances of the function.
   SetExpectedNofPropertiesFromEstimate(fun, lit->expected_property_count());
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger
   Debugger::OnAfterCompile(script, fun);
+#endif
 
   return fun;
 }
diff --git a/src/constants-arm.h b/src/constants-arm.h
index f553963..919a892 100644
--- a/src/constants-arm.h
+++ b/src/constants-arm.h
@@ -106,7 +106,12 @@
   call_rt_r5 = 0x10,
   call_rt_r2 = 0x11,
   // break point
-  break_point = 0x20
+  break_point = 0x20,
+  // FP operations.  These simulate calling into C for a moment to do fp ops.
+  // They should trash all caller-save registers.
+  simulator_fp_add = 0x21,
+  simulator_fp_sub = 0x22,
+  simulator_fp_mul = 0x23
 };
 
 
diff --git a/src/d8.cc b/src/d8.cc
index 9648168..70143c3 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -163,6 +163,22 @@
 }
 
 
+Handle<Value> Shell::Read(const Arguments& args) {
+  if (args.Length() != 1) {
+    return ThrowException(String::New("Bad parameters"));
+  }
+  String::Utf8Value file(args[0]);
+  if (*file == NULL) {
+    return ThrowException(String::New("Error loading file"));
+  }
+  Handle<String> source = ReadFile(*file);
+  if (source.IsEmpty()) {
+    return ThrowException(String::New("Error loading file"));
+  }
+  return source;
+}
+
+
 Handle<Value> Shell::Load(const Arguments& args) {
   for (int i = 0; i < args.Length(); i++) {
     HandleScope handle_scope;
@@ -246,6 +262,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Handle<Object> Shell::DebugMessageDetails(Handle<String> message) {
   Context::Scope context_scope(utility_context_);
   Handle<Object> global = utility_context_->Global();
@@ -266,6 +283,7 @@
   Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
   return val;
 }
+#endif
 
 
 int32_t* Counter::Bind(const char* name, bool is_histogram) {
@@ -381,6 +399,7 @@
   HandleScope scope;
   Handle<ObjectTemplate> global_template = ObjectTemplate::New();
   global_template->Set(String::New("print"), FunctionTemplate::New(Print));
+  global_template->Set(String::New("read"), FunctionTemplate::New(Read));
   global_template->Set(String::New("load"), FunctionTemplate::New(Load));
   global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
   global_template->Set(String::New("version"), FunctionTemplate::New(Version));
@@ -406,11 +425,13 @@
   global_template->Set(String::New("arguments"),
                        Utils::ToLocal(arguments_jsarray));
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Install the debugger object in the utility scope
   i::Debug::Load();
   i::JSObject* debug = i::Debug::debug_context()->global();
   utility_context_->Global()->Set(String::New("$debug"),
                                   Utils::ToLocal(&debug));
+#endif
 
   // Run the d8 shell utility script in the utility context
   int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
@@ -436,8 +457,10 @@
   evaluation_context_ = Context::New(NULL, global_template);
   evaluation_context_->SetSecurityToken(Undefined());
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Set the security token of the debug context to allow access.
   i::Debug::debug_context()->set_security_token(i::Heap::undefined_value());
+#endif
 }
 
 
@@ -555,6 +578,8 @@
   Handle<ObjectTemplate> global_template = ObjectTemplate::New();
   global_template->Set(String::New("print"),
                        FunctionTemplate::New(Shell::Print));
+  global_template->Set(String::New("read"),
+                       FunctionTemplate::New(Shell::Read));
   global_template->Set(String::New("load"),
                        FunctionTemplate::New(Shell::Load));
   global_template->Set(String::New("yield"),
@@ -690,6 +715,7 @@
       Locker::StartPreemption(preemption_interval);
     }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
     // Run the remote debugger if requested.
     if (i::FLAG_remote_debugger) {
       RunRemoteDebugger(i::FLAG_debugger_port);
@@ -705,6 +731,7 @@
     if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
       v8::Debug::SetDebugEventListener(HandleDebugEvent);
     }
+#endif
   }
   if (run_shell)
     RunShell();
diff --git a/src/d8.h b/src/d8.h
index 342a0d2..092e3a3 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -132,13 +132,16 @@
   static int Main(int argc, char* argv[]);
   static Handle<Array> GetCompletions(Handle<String> text,
                                       Handle<String> full);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   static Handle<Object> DebugMessageDetails(Handle<String> message);
   static Handle<Value> DebugCommandToJSONRequest(Handle<String> command);
+#endif
 
   static Handle<Value> Print(const Arguments& args);
   static Handle<Value> Yield(const Arguments& args);
   static Handle<Value> Quit(const Arguments& args);
   static Handle<Value> Version(const Arguments& args);
+  static Handle<Value> Read(const Arguments& args);
   static Handle<Value> Load(const Arguments& args);
   // The OS object on the global object contains methods for performing
   // operating system calls:
diff --git a/src/d8.js b/src/d8.js
index e2766d0..ea2fb44 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -653,17 +653,47 @@
   // Process arguments if any.
   if (args && args.length > 0) {
     var target = args;
+    var type = 'function';
+    var line;
+    var column;
     var condition;
+    var pos;
 
-    var pos = args.indexOf(' ');
+    // Check for breakpoint condition.
+    pos = args.indexOf(' ');
     if (pos > 0) {
       target = args.substring(0, pos);
       condition = args.substring(pos + 1, args.length);
     }
 
+    // Check for script breakpoint (name:line[:column]). If no ':' in break
+    // specification it is considered a function break point.
+    pos = target.indexOf(':');
+    if (pos > 0) {
+      type = 'script';
+      var tmp = target.substring(pos + 1, target.length);
+      target = target.substring(0, pos);
+      
+      // Check for both line and column.
+      pos = tmp.indexOf(':');
+      if (pos > 0) {
+        column = parseInt(tmp.substring(pos + 1, tmp.length)) - 1;
+        line = parseInt(tmp.substring(0, pos)) - 1;
+      } else {
+        line = parseInt(tmp) - 1;
+      }
+    } else if (target[0] == '#' && target[target.length - 1] == '#') {
+      type = 'handle';
+      target = target.substring(1, target.length - 1);
+    } else {
+      type = 'function';
+    }
+  
     request.arguments = {};
-    request.arguments.type = 'function';
+    request.arguments.type = type;
     request.arguments.target = target;
+    request.arguments.line = line;
+    request.arguments.column = column;
     request.arguments.condition = condition;
   } else {
     throw new Error('Invalid break arguments.');
@@ -721,6 +751,9 @@
   }
 
   print('break location [condition]');
+  print('  break on named function: location is a function name');
+  print('  break on function: location is #<id>#');
+  print('  break on script position: location is name:line[:column]');
   print('clear <breakpoint #>');
   print('backtrace [from frame #] [to frame #]]');
   print('frame <frame #>');
diff --git a/src/debug-agent.cc b/src/debug-agent.cc
index e865e0e..9838746 100644
--- a/src/debug-agent.cc
+++ b/src/debug-agent.cc
@@ -29,16 +29,18 @@
 #include "v8.h"
 #include "debug-agent.h"
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 namespace v8 { namespace internal {
 
-
 // Public V8 debugger API message handler function. This function just delegates
 // to the debugger agent through it's data parameter.
 void DebuggerAgentMessageHandler(const uint16_t* message, int length,
-                                 void *data) {
-  reinterpret_cast<DebuggerAgent*>(data)->DebuggerMessage(message, length);
+                                 v8::Debug::ClientData* client_data) {
+  DebuggerAgent::instance_->DebuggerMessage(message, length);
 }
 
+// static
+DebuggerAgent* DebuggerAgent::instance_ = NULL;
 
 // Debugger agent main thread.
 void DebuggerAgent::Run() {
@@ -410,5 +412,6 @@
   return total_received;
 }
 
-
 } }  // namespace v8::internal
+
+#endif  // ENABLE_DEBUGGER_SUPPORT
diff --git a/src/debug-agent.h b/src/debug-agent.h
index 177af0c..08f1372 100644
--- a/src/debug-agent.h
+++ b/src/debug-agent.h
@@ -28,12 +28,12 @@
 #ifndef V8_V8_DEBUG_AGENT_H_
 #define V8_V8_DEBUG_AGENT_H_
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 #include "../include/v8-debug.h"
 #include "platform.h"
 
 namespace v8 { namespace internal {
 
-
 // Forward decelrations.
 class DebuggerAgentSession;
 
@@ -46,8 +46,14 @@
       : name_(StrDup(name)), port_(port),
         server_(OS::CreateSocket()), terminate_(false),
         session_access_(OS::CreateMutex()), session_(NULL),
-        terminate_now_(OS::CreateSemaphore(0)) {}
-  ~DebuggerAgent() { delete server_; }
+        terminate_now_(OS::CreateSemaphore(0)) {
+    ASSERT(instance_ == NULL);
+    instance_ = this;
+  }
+  ~DebuggerAgent() {
+     instance_ = NULL;
+     delete server_;
+  }
 
   void Shutdown();
 
@@ -66,9 +72,11 @@
   DebuggerAgentSession* session_;  // Current active session if any.
   Semaphore* terminate_now_;  // Semaphore to signal termination.
 
+  static DebuggerAgent* instance_;
+
   friend class DebuggerAgentSession;
   friend void DebuggerAgentMessageHandler(const uint16_t* message, int length,
-                                          void *data);
+                                          v8::Debug::ClientData* client_data);
 
   DISALLOW_COPY_AND_ASSIGN(DebuggerAgent);
 };
@@ -111,7 +119,8 @@
   static int ReceiveAll(const Socket* conn, char* data, int len);
 };
 
-
 } }  // namespace v8::internal
 
+#endif  // ENABLE_DEBUGGER_SUPPORT
+
 #endif  // V8_V8_DEBUG_AGENT_H_
diff --git a/src/debug-arm.cc b/src/debug-arm.cc
index 9fb77b7..f86f981 100644
--- a/src/debug-arm.cc
+++ b/src/debug-arm.cc
@@ -32,7 +32,7 @@
 
 namespace v8 { namespace internal {
 
-
+#ifdef ENABLE_DEBUGGER_SUPPORT
 // Currently debug break is not supported in frame exit code on ARM.
 bool BreakLocationIterator::IsDebugBreakAtReturn() {
   return false;
@@ -58,7 +58,7 @@
 }
 
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
@@ -191,5 +191,6 @@
 
 #undef __
 
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 } }  // namespace v8::internal
diff --git a/src/debug-delay.js b/src/debug-delay.js
index 9944fb3..6cb5e7f 100644
--- a/src/debug-delay.js
+++ b/src/debug-delay.js
@@ -1021,6 +1021,9 @@
             columnOffset: script.columnOffset(),
             lineCount: script.lineCount(),
           };
+  if (!IS_UNDEFINED(script.data())) {
+    o.data = script.data();
+  }
   if (include_source) {
     o.source = script.source();
   }
@@ -1270,11 +1273,12 @@
   var ignoreCount = request.arguments.ignoreCount;
 
   // Check for legal arguments.
-  if (!type || !target) {
+  if (!type || IS_UNDEFINED(target)) {
     response.failed('Missing argument "type" or "target"');
     return;
   }
-  if (type != 'function' && type != 'script' && type != 'scriptId') {
+  if (type != 'function' && type != 'handle' &&
+      type != 'script' && type != 'scriptId') {
     response.failed('Illegal type "' + type + '"');
     return;
   }
@@ -1303,6 +1307,20 @@
 
     // Set function break point.
     break_point_number = Debug.setBreakPoint(f, line, column, condition);
+  } else if (type == 'handle') {
+    // Find the object pointed by the specified handle.
+    var handle = parseInt(target, 10);
+    var mirror = LookupMirror(handle);
+    if (!mirror) {
+      return response.failed('Object #' + handle + '# not found');
+    }
+    if (!mirror.isFunction()) {
+      return response.failed('Object #' + handle + '# is not a function');
+    }
+
+    // Set function break point.
+    break_point_number = Debug.setBreakPoint(mirror.value(),
+                                             line, column, condition);
   } else if (type == 'script') {
     // set script break point.
     break_point_number =
@@ -1547,20 +1565,24 @@
   }
 
   // Pull out arguments.
-  var handle = request.arguments.handle;
+  var handles = request.arguments.handles;
 
   // Check for legal arguments.
-  if (IS_UNDEFINED(handle)) {
-    return response.failed('Argument "handle" missing');
+  if (IS_UNDEFINED(handles)) {
+    return response.failed('Argument "handles" missing');
   }
 
-  // Lookup handle.
-  var mirror = LookupMirror(handle);
-  if (mirror) {
-    response.body = mirror;
-  } else {
-    return response.failed('Object #' + handle + '# not found');
+  // Lookup handles.
+  var mirrors = {};
+  for (var i = 0; i < handles.length; i++) {
+    var handle = handles[i];
+    var mirror = LookupMirror(handle);
+    if (!mirror) {
+      return response.failed('Object #' + handle + '# not found');
+    }
+    mirrors[handle] = mirror;
   }
+  response.body = mirrors;
 };
 
 
@@ -1675,6 +1697,9 @@
       script.lineOffset = scripts[i].line_offset;
       script.columnOffset = scripts[i].column_offset;
       script.lineCount = scripts[i].lineCount();
+      if (scripts[i].data) {
+        script.data = scripts[i].data;
+      }
       if (includeSource) {
         script.source = scripts[i].source;
       } else {
diff --git a/src/debug-ia32.cc b/src/debug-ia32.cc
index 6d59889..9503cfc 100644
--- a/src/debug-ia32.cc
+++ b/src/debug-ia32.cc
@@ -33,6 +33,7 @@
 
 namespace v8 { namespace internal {
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 
 // A debug break in the frame exit code is identified by a call instruction.
 bool BreakLocationIterator::IsDebugBreakAtReturn() {
@@ -67,7 +68,7 @@
 }
 
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
@@ -214,5 +215,6 @@
 
 #undef __
 
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 } }  // namespace v8::internal
diff --git a/src/debug.cc b/src/debug.cc
index a4bb04d..32a96a8 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -35,12 +35,15 @@
 #include "debug.h"
 #include "execution.h"
 #include "global-handles.h"
+#include "ic.h"
+#include "ic-inl.h"
 #include "natives.h"
 #include "stub-cache.h"
 #include "log.h"
 
 namespace v8 { namespace internal {
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 static void PrintLn(v8::Local<v8::Value> value) {
   v8::Local<v8::String> s = value->ToString();
   char* data = NewArray<char>(s->Length() + 1);
@@ -288,14 +291,8 @@
     // Patch the frame exit code with a break point.
     SetDebugBreakAtReturn();
   } else {
-    // Patch the original code with the current address as the current address
-    // might have changed by the inline caching since the code was copied.
-    original_rinfo()->set_target_address(rinfo()->target_address());
-
-    // Patch the code to invoke the builtin debug break function matching the
-    // calling convention used by the call site.
-    Handle<Code> dbgbrk_code(Debug::FindDebugBreak(rinfo()));
-    rinfo()->set_target_address(dbgbrk_code->entry());
+    // Patch the IC call.
+    SetDebugBreakAtIC();
   }
   ASSERT(IsDebugBreak());
 }
@@ -306,8 +303,8 @@
     // Restore the frame exit code.
     ClearDebugBreakAtReturn();
   } else {
-    // Patch the code to the original invoke.
-    rinfo()->set_target_address(original_rinfo()->target_address());
+    // Patch the IC call.
+    ClearDebugBreakAtIC();
   }
   ASSERT(!IsDebugBreak());
 }
@@ -360,6 +357,39 @@
 }
 
 
+void BreakLocationIterator::SetDebugBreakAtIC() {
+  // Patch the original code with the current address as the current address
+  // might have changed by the inline caching since the code was copied.
+  original_rinfo()->set_target_address(rinfo()->target_address());
+
+  RelocInfo::Mode mode = rmode();
+  if (RelocInfo::IsCodeTarget(mode)) {
+    Address target = rinfo()->target_address();
+    Handle<Code> code(Code::GetCodeFromTargetAddress(target));
+
+    // Patch the code to invoke the builtin debug break function matching the
+    // calling convention used by the call site.
+    Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode));
+    rinfo()->set_target_address(dbgbrk_code->entry());
+
+    // For stubs that refer back to an inlined version clear the cached map for
+    // the inlined case to always go through the IC. As long as the break point
+    // is set the patching performed by the runtime system will take place in
+    // the code copy and will therefore have no effect on the running code
+    // keeping it from using the inlined code.
+    if (code->is_keyed_load_stub() && KeyedLoadIC::HasInlinedVersion(pc())) {
+      KeyedLoadIC::ClearInlinedVersion(pc());
+    }
+  }
+}
+
+
+void BreakLocationIterator::ClearDebugBreakAtIC() {
+  // Patch the code to the original invoke.
+  rinfo()->set_target_address(original_rinfo()->target_address());
+}
+
+
 Object* BreakLocationIterator::BreakPointObjects() {
   return debug_info_->GetBreakPointObjects(code_position());
 }
@@ -1055,48 +1085,42 @@
 
 
 // Find the builtin to use for invoking the debug break
-Handle<Code> Debug::FindDebugBreak(RelocInfo* rinfo) {
+Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
   // Find the builtin debug break function matching the calling convention
   // used by the call site.
-  RelocInfo::Mode mode = rinfo->rmode();
-
-  if (RelocInfo::IsCodeTarget(mode)) {
-    Address target = rinfo->target_address();
-    Code* code = Code::GetCodeFromTargetAddress(target);
-    if (code->is_inline_cache_stub()) {
-      if (code->is_call_stub()) {
-        return ComputeCallDebugBreak(code->arguments_count());
-      }
-      if (code->is_load_stub()) {
-        return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
-      }
-      if (code->is_store_stub()) {
-        return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
-      }
-      if (code->is_keyed_load_stub()) {
-        Handle<Code> result =
-            Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
-        return result;
-      }
-      if (code->is_keyed_store_stub()) {
-        Handle<Code> result =
-            Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
-        return result;
-      }
+  if (code->is_inline_cache_stub()) {
+    if (code->is_call_stub()) {
+      return ComputeCallDebugBreak(code->arguments_count());
     }
-    if (RelocInfo::IsConstructCall(mode)) {
+    if (code->is_load_stub()) {
+      return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
+    }
+    if (code->is_store_stub()) {
+      return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
+    }
+    if (code->is_keyed_load_stub()) {
       Handle<Code> result =
-          Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));
+          Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
       return result;
     }
-    if (code->kind() == Code::STUB) {
-      ASSERT(code->major_key() == CodeStub::CallFunction ||
-             code->major_key() == CodeStub::StackCheck);
+    if (code->is_keyed_store_stub()) {
       Handle<Code> result =
-          Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
+          Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
       return result;
     }
   }
+  if (RelocInfo::IsConstructCall(mode)) {
+    Handle<Code> result =
+        Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));
+    return result;
+  }
+  if (code->kind() == Code::STUB) {
+    ASSERT(code->major_key() == CodeStub::CallFunction ||
+           code->major_key() == CodeStub::StackCheck);
+    Handle<Code> result =
+        Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
+    return result;
+  }
 
   UNREACHABLE();
   return Handle<Code>::null();
@@ -1397,11 +1421,10 @@
 bool Debugger::is_loading_debugger_ = false;
 bool Debugger::never_unload_debugger_ = false;
 DebugMessageThread* Debugger::message_thread_ = NULL;
-v8::DebugMessageHandler Debugger::message_handler_ = NULL;
+v8::Debug::MessageHandler Debugger::message_handler_ = NULL;
 bool Debugger::message_handler_cleared_ = false;
-void* Debugger::message_handler_data_ = NULL;
-v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
-void* Debugger::host_dispatch_handler_data_ = NULL;
+v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
+int Debugger::host_dispatch_micros_ = 100 * 1000;
 DebuggerAgent* Debugger::agent_ = NULL;
 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize);
 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize);
@@ -1703,8 +1726,8 @@
     if (event_listener_->IsProxy()) {
       // C debug event listener.
       Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
-      v8::DebugEventCallback callback =
-            FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy());
+      v8::Debug::EventCallback callback =
+            FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy());
       callback(event,
                v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
                v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)),
@@ -1805,32 +1828,31 @@
   // Process requests from the debugger.
   while (true) {
     // Wait for new command in the queue.
-    command_received_->Wait();
+    if (Debugger::host_dispatch_handler_) {
+      // In case there is a host dispatch - do periodic dispatches.
+      if (!command_received_->Wait(host_dispatch_micros_)) {
+        // Timout expired, do the dispatch.
+        Debugger::host_dispatch_handler_();
+        continue;
+      }
+    } else {
+      // In case there is no host dispatch - just wait.
+      command_received_->Wait();
+    }
 
     // The debug command interrupt flag might have been set when the command was
     // added.
     StackGuard::Continue(DEBUGCOMMAND);
 
     // Get the command from the queue.
-    Vector<uint16_t> command = command_queue_.Get();
+    Message command = command_queue_.Get();
     Logger::DebugTag("Got request from command queue, in interactive loop.");
     if (!Debugger::IsDebuggerActive()) {
+      // Delete command text and user data.
+      command.Dispose();
       return;
     }
 
-    // Check if the command is a host dispatch.
-    if (command[0] == 0) {
-      if (Debugger::host_dispatch_handler_) {
-        int32_t dispatch = (command[1] << 16) | command[2];
-        Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch),
-                                         Debugger::host_dispatch_handler_data_);
-      }
-      if (auto_continue && !HasCommands()) {
-        return;
-      }
-      continue;
-    }
-
     // Invoke JavaScript to process the debug request.
     v8::Local<v8::String> fun_name;
     v8::Local<v8::Function> fun;
@@ -1838,8 +1860,10 @@
     v8::TryCatch try_catch;
     fun_name = v8::String::New("processDebugRequest");
     fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
-    request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),
-                              command.length());
+
+    request = v8::String::New(command.text().start(),
+                              command.text().length());
+    command.text().Dispose();
     static const int kArgc = 1;
     v8::Handle<Value> argv[kArgc] = { request };
     v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
@@ -1875,13 +1899,8 @@
       response = try_catch.Exception()->ToString();
     }
 
-    // Convert text result to C string.
-    v8::String::Value val(response);
-    Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
-                        response->Length());
-
     // Return the result.
-    SendMessage(str);
+    SendMessage(Message::NewOutput(response, command.client_data()));
 
     // Return from debug event processing if either the VM is put into the
     // runnning state (through a continue command) or auto continue is active
@@ -1927,12 +1946,11 @@
 }
 
 
-void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data,
+void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler,
                                  bool message_handler_thread) {
   ScopedLock with(debugger_access_);
 
   message_handler_ = handler;
-  message_handler_data_ = data;
   if (handler != NULL) {
     if (!message_thread_ && message_handler_thread) {
       message_thread_ = new DebugMessageThread();
@@ -1951,10 +1969,10 @@
 }
 
 
-void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
-                                      void* data) {
+void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
+                                      int period) {
   host_dispatch_handler_ = handler;
-  host_dispatch_handler_data_ = data;
+  host_dispatch_micros_ = period * 1000;
 }
 
 
@@ -1962,26 +1980,28 @@
 // public API. Messages are kept internally as Vector<uint16_t> strings, which
 // are allocated in various places and deallocated by the calling function
 // sometime after this call.
-void Debugger::InvokeMessageHandler(Vector<uint16_t> message) {
+void Debugger::InvokeMessageHandler(Message message) {
   ScopedLock with(debugger_access_);
 
   if (message_handler_ != NULL) {
-    message_handler_(message.start(), message.length(), message_handler_data_);
+    message_handler_(message.text().start(),
+                     message.text().length(),
+                     message.client_data());
   }
+  message.Dispose();
 }
 
 
-void Debugger::SendMessage(Vector<uint16_t> message) {
+void Debugger::SendMessage(Message message) {
   if (message_thread_ == NULL) {
     // If there is no message thread just invoke the message handler from the
     // V8 thread.
     InvokeMessageHandler(message);
   } else {
-    // Put a copy of the message coming from V8 on the queue. The new copy of
-    // the event string is destroyed by the message thread.
-    Vector<uint16_t> message_copy = message.Clone();
+    // Put the message coming from V8 on the queue. The text and user data will
+    // be destroyed by the message thread.
     Logger::DebugTag("Put message on event message_queue.");
-    message_queue_.Put(message_copy);
+    message_queue_.Put(message);
     message_received_->Signal();
   }
 }
@@ -2004,12 +2024,11 @@
       if (FLAG_trace_debug_json) {
         PrintLn(json_event_string);
       }
-      v8::String::Value val(json_event_string);
-      Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
-                           json_event_string->Length());
-      SendMessage(str);
+      SendMessage(Message::NewOutput(
+          json_event_string,
+          NULL /* no user data since there was no request */));
     } else {
-      SendMessage(Vector<uint16_t>::empty());
+      SendMessage(Message::NewEmptyMessage());
     }
   } else {
     PrintLn(try_catch.Exception());
@@ -2025,13 +2044,15 @@
 // by the API client thread.  This is where the API client hands off
 // processing of the command to the DebugMessageThread thread.
 // The new copy of the command is destroyed in HandleCommand().
-void Debugger::ProcessCommand(Vector<const uint16_t> command) {
-  // Make a copy of the command. Need to cast away const for Clone to work.
-  Vector<uint16_t> command_copy =
+void Debugger::ProcessCommand(Vector<const uint16_t> command,
+                              v8::Debug::ClientData* client_data) {
+  // Need to cast away const.
+  Message message = Message::NewCommand(
       Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
-                       command.length()).Clone();
+                       command.length()),
+      client_data);
   Logger::DebugTag("Put command on command_queue.");
-  command_queue_.Put(command_copy);
+  command_queue_.Put(message);
   command_received_->Signal();
 
   // Set the debug command break flag to have the command processed.
@@ -2046,23 +2067,6 @@
 }
 
 
-void Debugger::ProcessHostDispatch(void* dispatch) {
-  // Puts a host dispatch comming from the public API on the queue.
-  uint16_t hack[3];
-  hack[0] = 0;
-  hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16;
-  hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF;
-  Logger::DebugTag("Put dispatch on command_queue.");
-  command_queue_.Put(Vector<uint16_t>(hack, 3).Clone());
-  command_received_->Signal();
-
-  // Set the debug command break flag to have the host dispatch processed.
-  if (!Debug::InDebugger()) {
-    StackGuard::DebugCommand();
-  }
-}
-
-
 bool Debugger::IsDebuggerActive() {
   ScopedLock with(debugger_access_);
 
@@ -2133,9 +2137,11 @@
     // Wait and Get are paired so that semaphore count equals queue length.
     Debugger::message_received_->Wait();
     Logger::DebugTag("Get message from event message_queue.");
-    Vector<uint16_t> message = Debugger::message_queue_.Get();
-    if (message.length() > 0) {
+    Message message = Debugger::message_queue_.Get();
+    if (message.text().length() > 0) {
       Debugger::InvokeMessageHandler(message);
+    } else {
+      message.Dispose();
     }
   }
 }
@@ -2143,22 +2149,72 @@
 
 void DebugMessageThread::Stop() {
   keep_running_ = false;
-  Debugger::SendMessage(Vector<uint16_t>(NULL, 0));
+  Debugger::SendMessage(Message::NewEmptyMessage());
   Join();
 }
 
 
+Message::Message() : text_(Vector<uint16_t>::empty()),
+                     client_data_(NULL) {
+}
+
+
+Message::Message(const Vector<uint16_t>& text,
+                 v8::Debug::ClientData* data)
+    : text_(text),
+      client_data_(data) {
+}
+
+
+Message::~Message() {
+}
+
+
+void Message::Dispose() {
+  text_.Dispose();
+  delete client_data_;
+  client_data_ = NULL;
+}
+
+
+Message Message::NewCommand(const Vector<uint16_t>& command,
+                            v8::Debug::ClientData* data) {
+  return Message(command.Clone(), data);
+}
+
+
+Message Message::NewOutput(v8::Handle<v8::String> output,
+                           v8::Debug::ClientData* data) {
+  Vector<uint16_t> text;
+  if (!output.IsEmpty()) {
+    // Do not include trailing '\0'.
+    text = Vector<uint16_t>::New(output->Length());
+    output->Write(text.start(), 0, output->Length());
+  }
+  return Message(text, data);
+}
+
+
+Message Message::NewEmptyMessage() {
+  return Message();
+}
+
+
 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {
-  messages_ = NewArray<Vector<uint16_t> >(size);
+  messages_ = NewArray<Message>(size);
 }
 
 
 MessageQueue::~MessageQueue() {
+  while (!IsEmpty()) {
+    Message m = Get();
+    m.Dispose();
+  }
   DeleteArray(messages_);
 }
 
 
-Vector<uint16_t> MessageQueue::Get() {
+Message MessageQueue::Get() {
   ASSERT(!IsEmpty());
   int result = start_;
   start_ = (start_ + 1) % size_;
@@ -2166,7 +2222,7 @@
 }
 
 
-void MessageQueue::Put(const Vector<uint16_t>& message) {
+void MessageQueue::Put(const Message& message) {
   if ((end_ + 1) % size_ == start_) {
     Expand();
   }
@@ -2180,9 +2236,11 @@
   while (!IsEmpty()) {
     new_queue.Put(Get());
   }
-  Vector<uint16_t>* array_to_free = messages_;
+  Message* array_to_free = messages_;
   *this = new_queue;
   new_queue.messages_ = array_to_free;
+  // Make the new_queue empty so that it doesn't call Dispose on any messages.
+  new_queue.start_ = new_queue.end_;
   // Automatic destructor called on new_queue, freeing array_to_free.
 }
 
@@ -2203,18 +2261,18 @@
 }
 
 
-Vector<uint16_t> LockingMessageQueue::Get() {
+Message LockingMessageQueue::Get() {
   ScopedLock sl(lock_);
-  Vector<uint16_t> result = queue_.Get();
-  Logger::DebugEvent("Get", result);
+  Message result = queue_.Get();
+  Logger::DebugEvent("Get", result.text());
   return result;
 }
 
 
-void LockingMessageQueue::Put(const Vector<uint16_t>& message) {
+void LockingMessageQueue::Put(const Message& message) {
   ScopedLock sl(lock_);
   queue_.Put(message);
-  Logger::DebugEvent("Put", message);
+  Logger::DebugEvent("Put", message.text());
 }
 
 
@@ -2223,5 +2281,6 @@
   queue_.Clear();
 }
 
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 } }  // namespace v8::internal
diff --git a/src/debug.h b/src/debug.h
index 8822c50..ffd3da9 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -28,7 +28,6 @@
 #ifndef V8_V8_DEBUG_H_
 #define V8_V8_DEBUG_H_
 
-#include "../include/v8-debug.h"
 #include "assembler.h"
 #include "code-stubs.h"
 #include "debug-agent.h"
@@ -38,6 +37,8 @@
 #include "string-stream.h"
 #include "v8threads.h"
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+#include "../include/v8-debug.h"
 
 namespace v8 { namespace internal {
 
@@ -131,6 +132,10 @@
  private:
   void SetDebugBreak();
   void ClearDebugBreak();
+
+  void SetDebugBreakAtIC();
+  void ClearDebugBreakAtIC();
+
   bool IsDebugBreakAtReturn();
   void SetDebugBreakAtReturn();
   void ClearDebugBreakAtReturn();
@@ -204,7 +209,7 @@
   static bool IsBreakStub(Code* code);
 
   // Find the builtin to use for invoking the debug break
-  static Handle<Code> FindDebugBreak(RelocInfo* rinfo);
+  static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode);
 
   static Handle<Object> GetSourceBreakLocations(
       Handle<SharedFunctionInfo> shared);
@@ -396,6 +401,32 @@
 };
 
 
+// Message send by user to v8 debugger or debugger output message.
+// In addition to command text it may contain a pointer to some user data
+// which are expected to be passed along with the command reponse to message
+// handler.
+class Message {
+ public:
+  static Message NewCommand(const Vector<uint16_t>& command,
+                            v8::Debug::ClientData* data);
+  static Message NewOutput(v8::Handle<v8::String> output,
+                           v8::Debug::ClientData* data);
+  static Message NewEmptyMessage();
+  Message();
+  ~Message();
+
+  // Deletes user data and disposes of the text.
+  void Dispose();
+  Vector<uint16_t> text() const { return text_; }
+  v8::Debug::ClientData* client_data() const { return client_data_; }
+ private:
+  Message(const Vector<uint16_t>& text,
+          v8::Debug::ClientData* data);
+
+  Vector<uint16_t> text_;
+  v8::Debug::ClientData* client_data_;
+};
+
 // A Queue of Vector<uint16_t> objects.  A thread-safe version is
 // LockingMessageQueue, based on this class.
 class MessageQueue BASE_EMBEDDED {
@@ -403,14 +434,14 @@
   explicit MessageQueue(int size);
   ~MessageQueue();
   bool IsEmpty() const { return start_ == end_; }
-  Vector<uint16_t> Get();
-  void Put(const Vector<uint16_t>& message);
+  Message Get();
+  void Put(const Message& message);
   void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().
  private:
   // Doubles the size of the message queue, and copies the messages.
   void Expand();
 
-  Vector<uint16_t>* messages_;
+  Message* messages_;
   int start_;
   int end_;
   int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
@@ -426,8 +457,8 @@
   explicit LockingMessageQueue(int size);
   ~LockingMessageQueue();
   bool IsEmpty() const;
-  Vector<uint16_t> Get();
-  void Put(const Vector<uint16_t>& message);
+  Message Get();
+  void Put(const Message& message);
   void Clear();
  private:
   MessageQueue queue_;
@@ -472,29 +503,29 @@
                                    Handle<Object> event_data,
                                    bool auto_continue);
   static void SetEventListener(Handle<Object> callback, Handle<Object> data);
-  static void SetMessageHandler(v8::DebugMessageHandler handler, void* data,
+  static void SetMessageHandler(v8::Debug::MessageHandler handler,
                                 bool message_handler_thread);
   static void TearDown();
-  static void SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
-                                     void* data);
+  static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
+                                     int period);
 
   // Invoke the message handler function.
-  static void InvokeMessageHandler(Vector< uint16_t> message);
+  static void InvokeMessageHandler(Message message);
 
   // Send a message to the message handler eiher through the message thread or
   // directly.
-  static void SendMessage(Vector<uint16_t> message);
+  static void SendMessage(Message message);
 
   // Send the JSON message for a debug event.
   static bool SendEventMessage(Handle<Object> event_data);
 
   // Add a debugger command to the command queue.
-  static void ProcessCommand(Vector<const uint16_t> command);
+  static void ProcessCommand(Vector<const uint16_t> command,
+                             v8::Debug::ClientData* client_data = NULL);
 
   // Check whether there are commands in the command queue.
   static bool HasCommands();
 
-  static void ProcessHostDispatch(void* dispatch);
   static Handle<Object> Call(Handle<JSFunction> fun,
                              Handle<Object> data,
                              bool* pending_exception);
@@ -538,11 +569,10 @@
   static bool is_loading_debugger_;  // Are we loading the debugger?
   static bool never_unload_debugger_;  // Can we unload the debugger?
   static DebugMessageThread* message_thread_;
-  static v8::DebugMessageHandler message_handler_;
+  static v8::Debug::MessageHandler message_handler_;
   static bool message_handler_cleared_;  // Was message handler cleared?
-  static void* message_handler_data_;
-  static v8::DebugHostDispatchHandler host_dispatch_handler_;
-  static void* host_dispatch_handler_data_;
+  static v8::Debug::HostDispatchHandler host_dispatch_handler_;
+  static int host_dispatch_micros_;
 
   static DebuggerAgent* agent_;
 
@@ -719,4 +749,6 @@
 
 } }  // namespace v8::internal
 
+#endif  // ENABLE_DEBUGGER_SUPPORT
+
 #endif  // V8_V8_DEBUG_H_
diff --git a/src/disasm-arm.cc b/src/disasm-arm.cc
index d19e042..3b7474d 100644
--- a/src/disasm-arm.cc
+++ b/src/disasm-arm.cc
@@ -261,6 +261,15 @@
     case break_point:
       Print("break_point");
       return;
+    case simulator_fp_add:
+      Print("simulator_fp_add");
+      return;
+    case simulator_fp_mul:
+      Print("simulator_fp_mul");
+      return;
+    case simulator_fp_sub:
+      Print("simulator_fp_sub");
+      return;
     default:
       out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
                                            "%d",
diff --git a/src/execution.cc b/src/execution.cc
index 03017d0..1d4d9ef 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -305,6 +305,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 bool StackGuard::IsDebugBreak() {
   ExecutionAccess access;
   return thread_local_.interrupt_flags_ & DEBUGBREAK;
@@ -331,7 +332,7 @@
     set_limits(kInterruptLimit, access);
   }
 }
-
+#endif
 
 void StackGuard::Continue(InterruptFlag after_what) {
   ExecutionAccess access;
@@ -539,6 +540,7 @@
 
   ContextSwitcher::PreemptionReceived();
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   if (Debug::InDebugger()) {
     // If currently in the debugger don't do any actual preemption but record
     // that preemption occoured while in the debugger.
@@ -548,11 +550,17 @@
     v8::Unlocker unlocker;
     Thread::YieldCPU();
   }
+#else
+  // Perform preemption.
+  v8::Unlocker unlocker;
+  Thread::YieldCPU();
+#endif
 
   return Heap::undefined_value();
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Object* Execution::DebugBreakHelper() {
   // Just continue if breaks are disabled.
   if (Debug::disable_break()) {
@@ -598,12 +606,14 @@
   // Return to continue execution.
   return Heap::undefined_value();
 }
-
+#endif
 
 Object* Execution::HandleStackGuardInterrupt() {
+#ifdef ENABLE_DEBUGGER_SUPPORT
   if (StackGuard::IsDebugBreak() || StackGuard::IsDebugCommand()) {
     DebugBreakHelper();
   }
+#endif
   if (StackGuard::IsPreempted()) RuntimePreempt();
   if (StackGuard::IsInterrupted()) {
     // interrupt
@@ -626,7 +636,7 @@
 
 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
   // All allocation spaces other than NEW_SPACE have the same effect.
-  Heap::CollectGarbage(0, OLD_DATA_SPACE);
+  Heap::CollectAllGarbage();
   return v8::Undefined();
 }
 
diff --git a/src/execution.h b/src/execution.h
index 6531572..6f2f689 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -118,8 +118,9 @@
                                           Handle<JSFunction> fun,
                                           Handle<Object> pos,
                                           Handle<Object> is_global);
-
+#ifdef ENABLE_DEBUGGER_SUPPORT
   static Object* DebugBreakHelper();
+#endif
 
   // If the stack guard is triggered, but it is not an actual
   // stack overflow, then handle the interruption accordingly.
@@ -158,11 +159,13 @@
   static void Preempt();
   static bool IsInterrupted();
   static void Interrupt();
-  static bool IsDebugBreak();
-  static void DebugBreak();
-  static bool IsDebugCommand();
-  static void DebugCommand();
   static void Continue(InterruptFlag after_what);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  static void DebugBreak();
+  static void DebugCommand();
+  static bool IsDebugBreak();
+  static bool IsDebugCommand();
+#endif
 
  private:
   // You should hold the ExecutionAccess lock when calling this method.
diff --git a/src/factory.cc b/src/factory.cc
index e29c84d..c849ab7 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -173,6 +173,7 @@
   script->set_id(Heap::last_script_id());
   script->set_line_offset(Smi::FromInt(0));
   script->set_column_offset(Smi::FromInt(0));
+  script->set_data(Heap::undefined_value());
   script->set_type(Smi::FromInt(SCRIPT_TYPE_NORMAL));
   script->set_wrapper(*Factory::NewProxy(0, TENURED));
   script->set_line_ends(Heap::undefined_value());
@@ -671,6 +672,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
   // Get the original code of the function.
   Handle<Code> code(shared->code());
@@ -700,6 +702,7 @@
 
   return debug_info;
 }
+#endif
 
 
 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
diff --git a/src/factory.h b/src/factory.h
index 2564c3c..54f2089 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -310,8 +310,9 @@
                                                   uint32_t key,
                                                   Handle<Object> value);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   static Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
-
+#endif
 
   // Return a map using the map cache in the global context.
   // The key the an ordered set of property names.
diff --git a/src/frames.cc b/src/frames.cc
index 88c723d..1eedbf6 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -647,10 +647,10 @@
   handler->Iterate(v);
   // Make sure that there's the entry frame does not contain more than
   // one stack handler.
-  if (kDebug) {
-    it.Advance();
-    ASSERT(it.done());
-  }
+#ifdef DEBUG
+  it.Advance();
+  ASSERT(it.done());
+#endif
 }
 
 
diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc
index ef0c7db..75f7a99 100644
--- a/src/func-name-inferrer.cc
+++ b/src/func-name-inferrer.cc
@@ -63,11 +63,12 @@
 }
 
 
-void FuncNameInferrer::MaybeInferFunctionName() {
-  if (func_to_infer_ != NULL) {
-    func_to_infer_->set_inferred_name(MakeNameFromStack());
-    func_to_infer_ = NULL;
+void FuncNameInferrer::InferFunctionsNames() {
+  Handle<String> func_name = MakeNameFromStack();
+  for (int i = 0; i < funcs_to_infer_.length(); ++i) {
+    funcs_to_infer_[i]->set_inferred_name(func_name);
   }
+  funcs_to_infer_.Rewind(0);
 }
 
 
diff --git a/src/func-name-inferrer.h b/src/func-name-inferrer.h
index 9dcf7c5..d8270c3 100644
--- a/src/func-name-inferrer.h
+++ b/src/func-name-inferrer.h
@@ -45,7 +45,7 @@
   FuncNameInferrer() :
       entries_stack_(10),
       names_stack_(5),
-      func_to_infer_(NULL),
+      funcs_to_infer_(4),
       dot_(Factory::NewStringFromAscii(CStrVector("."))) {
   }
 
@@ -57,39 +57,34 @@
     entries_stack_.Add(names_stack_.length());
   }
 
-  void Leave() {
-    ASSERT(IsOpen());
-    names_stack_.Rewind(entries_stack_.RemoveLast());
-  }
-
   void PushName(Handle<String> name) {
     if (IsOpen()) {
       names_stack_.Add(name);
     }
   }
 
-  void SetFuncToInfer(FunctionLiteral* func_to_infer) {
+  void AddFunction(FunctionLiteral* func_to_infer) {
     if (IsOpen()) {
-      // If we encounter another function literal after already having
-      // encountered one, the second one replaces the first.
-      func_to_infer_ = func_to_infer;
+      funcs_to_infer_.Add(func_to_infer);
     }
   }
 
   void InferAndLeave() {
     ASSERT(IsOpen());
-    MaybeInferFunctionName();
-    Leave();
+    if (!funcs_to_infer_.is_empty()) {
+      InferFunctionsNames();
+    }
+    names_stack_.Rewind(entries_stack_.RemoveLast());
   }
 
  private:
   Handle<String> MakeNameFromStack();
   Handle<String> MakeNameFromStackHelper(int pos, Handle<String> prev);
-  void MaybeInferFunctionName();
+  void InferFunctionsNames();
 
   List<int> entries_stack_;
   List<Handle<String> > names_stack_;
-  FunctionLiteral* func_to_infer_;
+  List<FunctionLiteral*> funcs_to_infer_;
   Handle<String> dot_;
 
   DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
diff --git a/src/globals.h b/src/globals.h
index 1579c3d..fbbe7c9 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -80,12 +80,6 @@
 // -----------------------------------------------------------------------------
 // Constants
 
-#ifdef DEBUG
-const bool kDebug = true;
-#else
-const bool kDebug = false;
-#endif  // DEBUG
-
 const int KB = 1024;
 const int MB = KB * KB;
 const int GB = KB * KB * KB;
@@ -146,7 +140,6 @@
 class BreakableStatement;
 class Code;
 class CodeGenerator;
-class CodeRegion;
 class CodeStub;
 class Context;
 class Debug;
diff --git a/src/handles.cc b/src/handles.cc
index 60d8236..99161ce 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -212,10 +212,20 @@
 }
 
 
-Handle<Object> IgnoreAttributesAndSetLocalProperty(Handle<JSObject> object,
-                           Handle<String> key,
-                           Handle<Object> value,
-                           PropertyAttributes attributes) {
+Handle<Object> ForceSetProperty(Handle<JSObject> object,
+                                Handle<Object> key,
+                                Handle<Object> value,
+                                PropertyAttributes attributes) {
+  CALL_HEAP_FUNCTION(
+      Runtime::ForceSetObjectProperty(object, key, value, attributes), Object);
+}
+
+
+Handle<Object> IgnoreAttributesAndSetLocalProperty(
+    Handle<JSObject> object,
+    Handle<String> key,
+    Handle<Object> value,
+    PropertyAttributes attributes) {
   CALL_HEAP_FUNCTION(object->
       IgnoreAttributesAndSetLocalProperty(*key, *value, attributes), Object);
 }
@@ -491,17 +501,6 @@
         break;
       }
 
-      // Compute the property keys.
-      content = UnionOfKeys(content, GetEnumPropertyKeys(current));
-
-      // Add the property keys from the interceptor.
-      if (current->HasNamedInterceptor()) {
-        v8::Handle<v8::Array> result =
-            GetKeysForNamedInterceptor(object, current);
-        if (!result.IsEmpty())
-          content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
-      }
-
       // Compute the element keys.
       Handle<FixedArray> element_keys =
           Factory::NewFixedArray(current->NumberOfEnumElements());
@@ -515,6 +514,17 @@
         if (!result.IsEmpty())
           content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
       }
+
+      // Compute the property keys.
+      content = UnionOfKeys(content, GetEnumPropertyKeys(current));
+
+      // Add the property keys from the interceptor.
+      if (current->HasNamedInterceptor()) {
+        v8::Handle<v8::Array> result =
+            GetKeysForNamedInterceptor(object, current);
+        if (!result.IsEmpty())
+          content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
+      }
     }
   }
   return content;
@@ -549,7 +559,7 @@
         index++;
       }
     }
-    (*storage)->SortPairs(*sort_array);
+    (*storage)->SortPairs(*sort_array, sort_array->length());
     Handle<FixedArray> bridge_storage =
         Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength);
     DescriptorArray* desc = object->map()->instance_descriptors();
@@ -651,6 +661,7 @@
   // We shouldn't get here if compiling the script failed.
   ASSERT(!boilerplate.is_null());
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // When the debugger running in its own context touches lazy loaded
   // functions loading can be triggered. In that case ensure that the
   // execution of the boilerplate is in the correct context.
@@ -659,6 +670,7 @@
       Top::context() == *Debug::debug_context()) {
     Top::set_context(*compile_context);
   }
+#endif
 
   // Reset the lazy load data before running the script to make sure
   // not to get recursive lazy loading.
diff --git a/src/handles.h b/src/handles.h
index c8e534e..9cc1db4 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -196,6 +196,11 @@
                            Handle<Object> value,
                            PropertyAttributes attributes);
 
+Handle<Object> ForceSetProperty(Handle<JSObject> object,
+                                Handle<Object> key,
+                                Handle<Object> value,
+                                PropertyAttributes attributes);
+
 Handle<Object> IgnoreAttributesAndSetLocalProperty(Handle<JSObject> object,
                                                    Handle<String> key,
                                                    Handle<Object> value,
diff --git a/src/heap.cc b/src/heap.cc
index 7a8b728..a57884c 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2679,7 +2679,10 @@
   SYNCHRONIZE_TAG("bootstrapper");
   Top::Iterate(v);
   SYNCHRONIZE_TAG("top");
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Debug::Iterate(v);
+#endif
   SYNCHRONIZE_TAG("debug");
   CompilationCache::Iterate(v);
   SYNCHRONIZE_TAG("compilationcache");
diff --git a/src/ic-arm.cc b/src/ic-arm.cc
index 4db3980..ad6eb2c 100644
--- a/src/ic-arm.cc
+++ b/src/ic-arm.cc
@@ -39,7 +39,7 @@
 // Static IC stub generators.
 //
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 // Helper function used from LoadIC/CallIC GenerateNormal.
@@ -96,7 +96,9 @@
     // Compute the masked index: (hash + i + i * i) & mask.
     __ ldr(t1, FieldMemOperand(r2, String::kLengthOffset));
     __ mov(t1, Operand(t1, LSR, String::kHashShift));
-    if (i > 0) __ add(t1, t1, Operand(Dictionary::GetProbeOffset(i)));
+    if (i > 0) {
+      __ add(t1, t1, Operand(Dictionary::GetProbeOffset(i)));
+    }
     __ and_(t1, t1, Operand(r3));
 
     // Scale the index by multiplying by the element size.
@@ -505,6 +507,8 @@
 // TODO(181): Implement map patching once loop nesting is tracked on
 // the ARM platform so we can generate inlined fast-case code for
 // array indexing in loops.
+bool KeyedLoadIC::HasInlinedVersion(Address address) { return false; }
+void KeyedLoadIC::ClearInlinedVersion(Address address) { }
 void KeyedLoadIC::PatchInlinedMapCheck(Address address, Object* value) { }
 
 
diff --git a/src/ic-ia32.cc b/src/ic-ia32.cc
index 9060f2d..664303f 100644
--- a/src/ic-ia32.cc
+++ b/src/ic-ia32.cc
@@ -38,7 +38,7 @@
 // Static IC stub generators.
 //
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 // Helper function used to load a property from a dictionary backing storage.
@@ -91,7 +91,9 @@
     // Compute the masked index: (hash + i + i * i) & mask.
     __ mov(r1, FieldOperand(name, String::kLengthOffset));
     __ shr(r1, String::kHashShift);
-    if (i > 0) __ add(Operand(r1), Immediate(Dictionary::GetProbeOffset(i)));
+    if (i > 0) {
+      __ add(Operand(r1), Immediate(Dictionary::GetProbeOffset(i)));
+    }
     __ and_(r1, Operand(r2));
 
     // Scale the index by multiplying by the element size.
@@ -727,8 +729,24 @@
 }
 
 
+// One byte opcode for test eax,0xXXXXXXXX.
+static const byte kTestEaxByte = 0xA9;
+
+
+bool KeyedLoadIC::HasInlinedVersion(Address address) {
+  Address test_instruction_address = address + 4;  // 4 = stub address
+  return *test_instruction_address == kTestEaxByte;
+}
+
+
+void KeyedLoadIC::ClearInlinedVersion(Address address) {
+  // Insert null as the map to check for to make sure the map check fails
+  // sending control flow to the IC instead of the inlined version.
+  PatchInlinedMapCheck(address, Heap::null_value());
+}
+
+
 void KeyedLoadIC::PatchInlinedMapCheck(Address address, Object* value) {
-  static const byte kTestEaxByte = 0xA9;
   Address test_instruction_address = address + 4;  // 4 = stub address
   // The keyed load has a fast inlined case if the IC call instruction
   // is immediately followed by a test instruction.
@@ -742,7 +760,7 @@
     // bytes of the 7-byte operand-immediate compare instruction, so
     // we add 3 to the offset to get the map address.
     Address map_address = test_instruction_address + offset_value + 3;
-    // patch the map check.
+    // Patch the map check.
     (*(reinterpret_cast<Object**>(map_address))) = value;
   }
 }
diff --git a/src/ic-inl.h b/src/ic-inl.h
index f5ce0ad..bb56962 100644
--- a/src/ic-inl.h
+++ b/src/ic-inl.h
@@ -39,6 +39,7 @@
   // Get the address of the call.
   Address result = pc() - Assembler::kTargetAddrToReturnAddrDist;
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // First check if any break points are active if not just return the address
   // of the call.
   if (!Debug::has_break_points()) return result;
@@ -55,6 +56,9 @@
     // No break point here just return the address of the call.
     return result;
   }
+#else
+  return result;
+#endif
 }
 
 
diff --git a/src/ic.cc b/src/ic.cc
index d7bd764..51768d7 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -100,6 +100,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Address IC::OriginalCodeAddress() {
   HandleScope scope;
   // Compute the JavaScript frame for the frame pointer of this IC
@@ -126,7 +127,7 @@
   int delta = original_code->instruction_start() - code->instruction_start();
   return addr + delta;
 }
-
+#endif
 
 IC::State IC::StateFrom(Code* target, Object* receiver) {
   IC::State state = target->ic_state();
@@ -236,7 +237,7 @@
   // Make sure to also clear the map used in inline fast cases.  If we
   // do not clear these maps, cached code can keep objects alive
   // through the embedded maps.
-  PatchInlinedMapCheck(address, Heap::null_value());
+  ClearInlinedVersion(address);
   SetTargetAtAddress(address, initialize_stub());
 }
 
@@ -356,6 +357,7 @@
       if (opt->IsJSFunction()) return opt;
     }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
     // Handle stepping into a function if step into is active.
     if (Debug::StepInActive()) {
       // Protect the result in a handle as the debugger can allocate and might
@@ -365,6 +367,7 @@
       Debug::HandleStepIn(function, fp(), false);
       return *function;
     }
+#endif
 
     return result;
   }
diff --git a/src/ic.h b/src/ic.h
index bbe1f6d..11d47ae 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -107,9 +107,11 @@
   Address fp() const { return fp_; }
   Address pc() const { return *pc_address_; }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Computes the address in the original code when the code running is
   // containing break points (calls to DebugBreakXXX builtins).
   Address OriginalCodeAddress();
+#endif
 
   // Set the call-site target.
   void set_target(Code* code) { SetTargetAtAddress(address(), code); }
@@ -252,6 +254,12 @@
   static void GeneratePreMonomorphic(MacroAssembler* masm);
   static void GenerateGeneric(MacroAssembler* masm);
 
+  // Check if this IC corresponds to an inlined version.
+  static bool HasInlinedVersion(Address address);
+
+  // Clear the use of the inlined version.
+  static void ClearInlinedVersion(Address address);
+
  private:
   static void Generate(MacroAssembler* masm, const ExternalReference& f);
 
diff --git a/src/jump-target-arm.cc b/src/jump-target-arm.cc
index 3ce5f30..6d375e5 100644
--- a/src/jump-target-arm.cc
+++ b/src/jump-target-arm.cc
@@ -35,7 +35,7 @@
 // -------------------------------------------------------------------------
 // JumpTarget implementation.
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 void JumpTarget::DoJump() {
   ASSERT(cgen_ != NULL);
diff --git a/src/jump-target-ia32.cc b/src/jump-target-ia32.cc
index 8afb0a8..a1049b2 100644
--- a/src/jump-target-ia32.cc
+++ b/src/jump-target-ia32.cc
@@ -35,7 +35,7 @@
 // -------------------------------------------------------------------------
 // JumpTarget implementation.
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 void JumpTarget::DoJump() {
   ASSERT(cgen_ != NULL);
diff --git a/src/log.cc b/src/log.cc
index d9e304d..f23b73b 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -814,35 +814,6 @@
 }
 
 
-void Logger::BeginCodeRegionEvent(CodeRegion* region,
-                                  Assembler* masm,
-                                  const char* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (logfile_ == NULL || !FLAG_log_code) return;
-  LogMessageBuilder msg;
-  msg.Append("begin-code-region,0x%x,0x%x,0x%x,%s\n",
-             reinterpret_cast<unsigned int>(region),
-             reinterpret_cast<unsigned int>(masm),
-             masm->pc_offset(),
-             name);
-  msg.WriteToLogFile();
-#endif
-}
-
-
-void Logger::EndCodeRegionEvent(CodeRegion* region, Assembler* masm) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (logfile_ == NULL || !FLAG_log_code) return;
-  LogMessageBuilder msg;
-  msg.Append("end-code-region,0x%x,0x%x,0x%x\n",
-             reinterpret_cast<unsigned int>(region),
-             reinterpret_cast<unsigned int>(masm),
-             masm->pc_offset());
-  msg.WriteToLogFile();
-#endif
-}
-
-
 void Logger::ResourceEvent(const char* name, const char* tag) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (logfile_ == NULL || !FLAG_log) return;
diff --git a/src/log.h b/src/log.h
index bbcfa42..44c1957 100644
--- a/src/log.h
+++ b/src/log.h
@@ -174,11 +174,6 @@
   static void CodeMoveEvent(Address from, Address to);
   // Emits a code delete event.
   static void CodeDeleteEvent(Address from);
-  // Emits region delimiters
-  static void BeginCodeRegionEvent(CodeRegion* region,
-                                   Assembler* masm,
-                                   const char* name);
-  static void EndCodeRegionEvent(CodeRegion* region, Assembler* masm);
 
   // ==== Events logged by --log-gc. ====
   // Heap sampling events: start, end, and individual types.
diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc
index 88a300b..365c1ad 100644
--- a/src/macro-assembler-arm.cc
+++ b/src/macro-assembler-arm.cc
@@ -168,11 +168,11 @@
 }
 
 
-void MacroAssembler::Ret() {
+void MacroAssembler::Ret(Condition cond) {
 #if USE_BX
-  bx(lr);
+  bx(lr, cond);
 #else
-  mov(pc, Operand(lr));
+  mov(pc, Operand(lr), LeaveCC, cond);
 #endif
 }
 
@@ -320,16 +320,19 @@
   add(r6, fp, Operand(r4, LSL, kPointerSizeLog2));
   add(r6, r6, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize));
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Save the state of all registers to the stack from the memory
   // location. This is needed to allow nested break points.
   if (type == StackFrame::EXIT_DEBUG) {
     // Use sp as base to push.
     CopyRegistersFromMemoryToStack(sp, kJSCallerSaved);
   }
+#endif
 }
 
 
 void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Restore the memory copy of the registers by digging them out from
   // the stack. This is needed to allow nested break points.
   if (type == StackFrame::EXIT_DEBUG) {
@@ -339,6 +342,7 @@
     add(r3, fp, Operand(kOffset));
     CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved);
   }
+#endif
 
   // Clear top frame.
   mov(r3, Operand(0));
@@ -348,9 +352,9 @@
   // Restore current context from top and clear it in debug mode.
   mov(ip, Operand(ExternalReference(Top::k_context_address)));
   ldr(cp, MemOperand(ip));
-  if (kDebug) {
-    str(r3, MemOperand(ip));
-  }
+#ifdef DEBUG
+  str(r3, MemOperand(ip));
+#endif
 
   // Pop the arguments, restore registers, and return.
   mov(sp, Operand(fp));  // respect ABI stack constraint
@@ -491,6 +495,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::SaveRegistersToMemory(RegList regs) {
   ASSERT((regs & ~kJSCallerSaved) == 0);
   // Copy the content of registers to memory location.
@@ -548,7 +553,7 @@
     }
   }
 }
-
+#endif
 
 void MacroAssembler::PushTryHandler(CodeLocation try_location,
                                     HandlerType type) {
@@ -674,10 +679,10 @@
   // Load current lexical context from the stack frame.
   ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
   // In debug mode, make sure the lexical context is set.
-  if (kDebug) {
-    cmp(scratch, Operand(0));
-    Check(ne, "we should not have an empty lexical context");
-  }
+#ifdef DEBUG
+  cmp(scratch, Operand(0));
+  Check(ne, "we should not have an empty lexical context");
+#endif
 
   // Load the global context of the current context.
   int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
diff --git a/src/macro-assembler-arm.h b/src/macro-assembler-arm.h
index 4b999fd..d3835be 100644
--- a/src/macro-assembler-arm.h
+++ b/src/macro-assembler-arm.h
@@ -86,7 +86,7 @@
   void Call(Register target, Condition cond = al);
   void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al);
   void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
-  void Ret();
+  void Ret(Condition cond = al);
   // Jumps to the label at the index given by the Smi in "index".
   void SmiJumpTable(Register index, Vector<Label*> targets);
 
@@ -138,6 +138,7 @@
                       InvokeFlag flag);
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // ---------------------------------------------------------------------------
   // Debugger Support
 
@@ -147,7 +148,7 @@
   void CopyRegistersFromStackToMemory(Register base,
                                       Register scratch,
                                       RegList regs);
-
+#endif
 
   // ---------------------------------------------------------------------------
   // Exception handling
@@ -297,6 +298,15 @@
 }
 
 
+#ifdef GENERATED_CODE_COVERAGE
+#define CODE_COVERAGE_STRINGIFY(x) #x
+#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
+#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
+#define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
+#else
+#define ACCESS_MASM(masm) masm->
+#endif
+
 
 } }  // namespace v8::internal
 
diff --git a/src/macro-assembler-ia32.cc b/src/macro-assembler-ia32.cc
index 4fad3be..d6d5800 100644
--- a/src/macro-assembler-ia32.cc
+++ b/src/macro-assembler-ia32.cc
@@ -216,6 +216,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::SaveRegistersToMemory(RegList regs) {
   ASSERT((regs & ~kJSCallerSaved) == 0);
   // Copy the content of registers to memory location.
@@ -290,7 +291,7 @@
     }
   }
 }
-
+#endif
 
 void MacroAssembler::Set(Register dst, const Immediate& x) {
   if (x.is_zero()) {
@@ -378,6 +379,7 @@
   mov(edi, Operand(eax));
   lea(esi, Operand(ebp, eax, times_4, offset));
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Save the state of all registers to the stack from the memory
   // location. This is needed to allow nested break points.
   if (type == StackFrame::EXIT_DEBUG) {
@@ -389,6 +391,7 @@
     // associated with this issue).
     PushRegistersFromMemory(kJSCallerSaved);
   }
+#endif
 
   // Reserve space for two arguments: argc and argv.
   sub(Operand(esp), Immediate(2 * kPointerSize));
@@ -406,6 +409,7 @@
 
 
 void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Restore the memory copy of the registers by digging them out from
   // the stack. This is needed to allow nested break points.
   if (type == StackFrame::EXIT_DEBUG) {
@@ -416,6 +420,7 @@
     lea(ebx, Operand(ebp, kOffset));
     CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved);
   }
+#endif
 
   // Get the return address from the stack and restore the frame pointer.
   mov(ecx, Operand(ebp, 1 * kPointerSize));
@@ -427,9 +432,9 @@
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Top::k_context_address);
   mov(esi, Operand::StaticVariable(context_address));
-  if (kDebug) {
-    mov(Operand::StaticVariable(context_address), Immediate(0));
-  }
+#ifdef DEBUG
+  mov(Operand::StaticVariable(context_address), Immediate(0));
+#endif
 
   // Push the return address to get ready to return.
   push(ecx);
diff --git a/src/macro-assembler-ia32.h b/src/macro-assembler-ia32.h
index 40aa84a..ae3a853 100644
--- a/src/macro-assembler-ia32.h
+++ b/src/macro-assembler-ia32.h
@@ -73,7 +73,7 @@
                    Register value,
                    Register scratch);
 
-
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // ---------------------------------------------------------------------------
   // Debugger Support
 
@@ -84,7 +84,7 @@
   void CopyRegistersFromStackToMemory(Register base,
                                       Register scratch,
                                       RegList regs);
-
+#endif
 
   // ---------------------------------------------------------------------------
   // Activation frames
@@ -343,6 +343,29 @@
   return Operand(object, index, scale, offset - kHeapObjectTag);
 }
 
+
+#ifdef GENERATED_CODE_COVERAGE
+extern void LogGeneratedCodeCoverage(const char* file_line);
+#define CODE_COVERAGE_STRINGIFY(x) #x
+#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
+#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
+#define ACCESS_MASM(masm) {                                               \
+    byte* ia32_coverage_function =                                        \
+        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
+    masm->pushfd();                                                       \
+    masm->pushad();                                                       \
+    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
+    masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY);         \
+    masm->pop(eax);                                                       \
+    masm->popad();                                                        \
+    masm->popfd();                                                        \
+  }                                                                       \
+  masm->
+#else
+#define ACCESS_MASM(masm) masm->
+#endif
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_MACRO_ASSEMBLER_IA32_H_
diff --git a/src/messages.js b/src/messages.js
index cd9a1e8..fa6fb1f 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -98,6 +98,7 @@
   instanceof_function_expected: "Expecting a function in instanceof check, but got %0",
   instanceof_nonobject_proto:   "Function has non-object prototype '%0' in instanceof check",
   null_to_object:               "Cannot convert null to object",
+  reduce_no_initial:            "Reduce of empty array with no initial value",
   // RangeError
   invalid_array_length:         "Invalid array length",
   invalid_array_apply_length:   "Function.prototype.apply supports only up to 1024 arguments",
diff --git a/src/mirror-delay.js b/src/mirror-delay.js
index 9c9d713..dc4d7eb 100644
--- a/src/mirror-delay.js
+++ b/src/mirror-delay.js
@@ -1582,6 +1582,11 @@
 };
 
 
+ScriptMirror.prototype.data = function() {
+  return this.script_.data;
+};
+
+
 ScriptMirror.prototype.scriptType = function() {
   return this.script_.type;
 };
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index f40fd3e..635ef0f 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -924,7 +924,11 @@
   VerifyPointer(name());
   line_offset()->SmiVerify();
   column_offset()->SmiVerify();
+  VerifyPointer(data());
+  VerifyPointer(wrapper());
   type()->SmiVerify();
+  VerifyPointer(line_ends());
+  VerifyPointer(id());
 }
 
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index c2143ea..73b9c84 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2053,10 +2053,12 @@
 ACCESSORS(Script, id, Object, kIdOffset)
 ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
 ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
+ACCESSORS(Script, data, Object, kDataOffset)
 ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
 ACCESSORS(Script, type, Smi, kTypeOffset)
 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
 ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
@@ -2066,6 +2068,7 @@
 ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
 ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
+#endif
 
 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
diff --git a/src/objects.cc b/src/objects.cc
index 9c640f4..31c5bab 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -43,22 +43,6 @@
 
 namespace v8 { namespace internal {
 
-#define FIELD_ADDR(p, offset) \
-  (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
-
-
-#define WRITE_FIELD(p, offset, value) \
-  (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
-
-
-#define WRITE_INT_FIELD(p, offset, value) \
-  (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
-
-
-#define WRITE_BARRIER(object, offset) \
-  Heap::RecordWrite(object->address(), offset);
-
-
 // Getters and setters are stored in a fixed array property.  These are
 // constants for their indices.
 const int kGetterIndex = 0;
@@ -1800,6 +1784,17 @@
     && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
     return SetPropertyWithFailedAccessCheck(result, name, value);
   }
+
+  if (IsJSGlobalProxy()) {
+    Object* proto = GetPrototype();
+    if (proto->IsNull()) return value;
+    ASSERT(proto->IsJSGlobalObject());
+    return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty(
+        name,
+        value,
+        attributes);
+  }
+
   // Check for accessor in prototype chain removed here in clone.
   if (result->IsNotFound()) {
     return AddProperty(name, value, attributes);
@@ -1820,20 +1815,16 @@
         return AddFastPropertyUsingMap(result->GetTransitionMap(),
                                        name,
                                        value);
-      } else {
-        return ConvertDescriptorToField(name, value, attributes);
       }
+      return ConvertDescriptorToField(name, value, attributes);
     case CONSTANT_FUNCTION:
       if (value == result->GetConstantFunction()) return value;
       // Only replace the function if necessary.
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     case CALLBACKS:
-      return SetPropertyWithCallback(result->GetCallbackObject(),
-                                     name,
-                                     value,
-                                     result->holder());
     case INTERCEPTOR:
-      return SetPropertyWithInterceptor(name, value, attributes);
+      // Override callback in clone
+      return ConvertDescriptorToField(name, value, attributes);
     case CONSTANT_TRANSITION:
       // Replace with a MAP_TRANSITION to a new map with a FIELD, even
       // if the value is a function.
@@ -4678,6 +4669,7 @@
     it.rinfo()->set_target_object(code);
   }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   if (Debug::has_break_points()) {
     for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
          !it.done();
@@ -4691,6 +4683,7 @@
       }
     }
   }
+#endif
   set_ic_flag(IC_TARGET_IS_OBJECT);
 }
 
@@ -4712,10 +4705,12 @@
       v->VisitCodeTarget(it.rinfo());
     } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
       v->VisitExternalReference(it.rinfo()->target_reference_address());
+#ifdef ENABLE_DEBUGGER_SUPPORT
     } else if (Debug::has_break_points() &&
                RelocInfo::IsJSReturn(rmode) &&
                it.rinfo()->IsCallInstruction()) {
       v->VisitDebugTarget(it.rinfo());
+#endif
     } else if (rmode == RelocInfo::RUNTIME_ENTRY) {
       v->VisitRuntimeEntry(it.rinfo());
     }
@@ -4740,6 +4735,7 @@
     it.rinfo()->set_target_address(code->instruction_start());
   }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   if (Debug::has_break_points()) {
     for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
          !it.done();
@@ -4751,6 +4747,7 @@
       }
     }
   }
+#endif
   set_ic_flag(IC_TARGET_IS_ADDRESS);
 }
 
@@ -5138,7 +5135,7 @@
       VMState state(EXTERNAL);
       result = getter(index, info);
     }
-    if (!result.IsEmpty()) return !result->IsUndefined();
+    if (!result.IsEmpty()) return true;
   }
   return holder_handle->HasElementPostInterceptor(*receiver_handle, index);
 }
@@ -5861,43 +5858,46 @@
 }
 
 
-void FixedArray::Swap(int i, int j) {
+void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) {
   Object* temp = get(i);
   set(i, get(j));
   set(j, temp);
+  if (this != numbers) {
+    temp = numbers->get(i);
+    numbers->set(i, numbers->get(j));
+    numbers->set(j, temp);
+  }
 }
 
 
-static void InsertionSortPairs(FixedArray* content, FixedArray* smis) {
-  int len = smis->length();
+static void InsertionSortPairs(FixedArray* content,
+                               FixedArray* numbers,
+                               int len) {
   for (int i = 1; i < len; i++) {
     int j = i;
     while (j > 0 &&
-           Smi::cast(smis->get(j-1))->value() >
-               Smi::cast(smis->get(j))->value()) {
-      smis->Swap(j-1, j);
-      content->Swap(j-1, j);
+           (NumberToUint32(numbers->get(j - 1)) >
+            NumberToUint32(numbers->get(j)))) {
+      content->SwapPairs(numbers, j - 1, j);
       j--;
     }
   }
 }
 
 
-void HeapSortPairs(FixedArray* content, FixedArray* smis) {
+void HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) {
   // In-place heap sort.
-  ASSERT(content->length() == smis->length());
-  int len = smis->length();
+  ASSERT(content->length() == numbers->length());
 
   // Bottom-up max-heap construction.
   for (int i = 1; i < len; ++i) {
     int child_index = i;
     while (child_index > 0) {
       int parent_index = ((child_index + 1) >> 1) - 1;
-      int parent_value = Smi::cast(smis->get(parent_index))->value();
-      int child_value = Smi::cast(smis->get(child_index))->value();
+      uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
+      uint32_t child_value = NumberToUint32(numbers->get(child_index));
       if (parent_value < child_value) {
-        content->Swap(parent_index, child_index);
-        smis->Swap(parent_index, child_index);
+        content->SwapPairs(numbers, parent_index, child_index);
       } else {
         break;
       }
@@ -5908,25 +5908,22 @@
   // Extract elements and create sorted array.
   for (int i = len - 1; i > 0; --i) {
     // Put max element at the back of the array.
-    content->Swap(0, i);
-    smis->Swap(0, i);
+    content->SwapPairs(numbers, 0, i);
     // Sift down the new top element.
     int parent_index = 0;
     while (true) {
       int child_index = ((parent_index + 1) << 1) - 1;
       if (child_index >= i) break;
-      uint32_t child1_value = Smi::cast(smis->get(child_index))->value();
-      uint32_t child2_value = Smi::cast(smis->get(child_index + 1))->value();
-      uint32_t parent_value = Smi::cast(smis->get(parent_index))->value();
+      uint32_t child1_value = NumberToUint32(numbers->get(child_index));
+      uint32_t child2_value = NumberToUint32(numbers->get(child_index + 1));
+      uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
       if (child_index + 1 >= i || child1_value > child2_value) {
         if (parent_value > child1_value) break;
-        content->Swap(parent_index, child_index);
-        smis->Swap(parent_index, child_index);
+        content->SwapPairs(numbers, parent_index, child_index);
         parent_index = child_index;
       } else {
         if (parent_value > child2_value) break;
-        content->Swap(parent_index, child_index + 1);
-        smis->Swap(parent_index, child_index + 1);
+        content->SwapPairs(numbers, parent_index, child_index + 1);
         parent_index = child_index + 1;
       }
     }
@@ -5934,43 +5931,41 @@
 }
 
 
-// Sort this array and the smis as pairs wrt. the (distinct) smis.
-void FixedArray::SortPairs(FixedArray* smis) {
-  ASSERT(this->length() == smis->length());
-  int len = smis->length();
+// Sort this array and the numbers as pairs wrt. the (distinct) numbers.
+void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
+  ASSERT(this->length() == numbers->length());
   // For small arrays, simply use insertion sort.
   if (len <= 10) {
-    InsertionSortPairs(this, smis);
+    InsertionSortPairs(this, numbers, len);
     return;
   }
   // Check the range of indices.
-  int min_index = Smi::cast(smis->get(0))->value();
-  int max_index = min_index;
-  int i;
+  uint32_t min_index = NumberToUint32(numbers->get(0));
+  uint32_t max_index = min_index;
+  uint32_t i;
   for (i = 1; i < len; i++) {
-    if (Smi::cast(smis->get(i))->value() < min_index) {
-      min_index = Smi::cast(smis->get(i))->value();
-    } else if (Smi::cast(smis->get(i))->value() > max_index) {
-      max_index = Smi::cast(smis->get(i))->value();
+    if (NumberToUint32(numbers->get(i)) < min_index) {
+      min_index = NumberToUint32(numbers->get(i));
+    } else if (NumberToUint32(numbers->get(i)) > max_index) {
+      max_index = NumberToUint32(numbers->get(i));
     }
   }
   if (max_index - min_index + 1 == len) {
     // Indices form a contiguous range, unless there are duplicates.
-    // Do an in-place linear time sort assuming distinct smis, but
+    // Do an in-place linear time sort assuming distinct numbers, but
     // avoid hanging in case they are not.
     for (i = 0; i < len; i++) {
-      int p;
-      int j = 0;
+      uint32_t p;
+      uint32_t j = 0;
       // While the current element at i is not at its correct position p,
       // swap the elements at these two positions.
-      while ((p = Smi::cast(smis->get(i))->value() - min_index) != i &&
+      while ((p = NumberToUint32(numbers->get(i)) - min_index) != i &&
              j++ < len) {
-        this->Swap(i, p);
-        smis->Swap(i, p);
+        SwapPairs(numbers, i, p);
       }
     }
   } else {
-    HeapSortPairs(this, smis);
+    HeapSortPairs(this, numbers, len);
     return;
   }
 }
@@ -6758,7 +6753,7 @@
   }
 
   // Sort the arrays wrt. enumeration order.
-  iteration_order->SortPairs(enumeration_order);
+  iteration_order->SortPairs(enumeration_order, enumeration_order->length());
 
   // Overwrite the enumeration_order with the enumeration indices.
   for (int i = 0; i < length; i++) {
@@ -7010,6 +7005,7 @@
        if ((attr & filter) == 0) storage->set(index++, k);
      }
   }
+  storage->SortPairs(storage, index);
   ASSERT(storage->length() >= index);
 }
 
@@ -7031,7 +7027,7 @@
        }
      }
   }
-  storage->SortPairs(sort_array);
+  storage->SortPairs(sort_array, sort_array->length());
   ASSERT(storage->length() >= index);
 }
 
@@ -7176,6 +7172,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 // Check if there is a break point at this code position.
 bool DebugInfo::HasBreakPoint(int code_position) {
   // Get the break point info object for this code position.
@@ -7419,6 +7416,6 @@
   // Multiple break points.
   return FixedArray::cast(break_point_objects())->length();
 }
-
+#endif
 
 } }  // namespace v8::internal
diff --git a/src/objects.h b/src/objects.h
index ade282b..db3c449 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -389,7 +389,7 @@
 // Note that for subtle reasons related to the ordering or numerical values of
 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
 // manually.
-#define STRUCT_LIST(V)                                                    \
+#define STRUCT_LIST_ALL(V)                                                \
   V(ACCESSOR_INFO, AccessorInfo, accessor_info)                           \
   V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                \
   V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                  \
@@ -398,10 +398,19 @@
   V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)       \
   V(SIGNATURE_INFO, SignatureInfo, signature_info)                        \
   V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                   \
-  V(DEBUG_INFO, DebugInfo, debug_info)                                    \
-  V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)                   \
   V(SCRIPT, Script, script)
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+#define STRUCT_LIST_DEBUGGER(V)                                           \
+  V(DEBUG_INFO, DebugInfo, debug_info)                                    \
+  V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
+#else
+#define STRUCT_LIST_DEBUGGER(V)
+#endif
+
+#define STRUCT_LIST(V)                                                    \
+  STRUCT_LIST_ALL(V)                                                      \
+  STRUCT_LIST_DEBUGGER(V)
 
 // We use the full 8 bits of the instance_type field to encode heap object
 // instance types.  The high-order bit (bit 7) is set if the object is not a
@@ -1585,11 +1594,15 @@
   bool IsEqualTo(FixedArray* other);
 #endif
 
-  // Swap two elements.
-  void Swap(int i, int j);
+  // Swap two elements in a pair of arrays.  If this array and the
+  // numbers array are the same object, the elements are only swapped
+  // once.
+  void SwapPairs(FixedArray* numbers, int i, int j);
 
-  // Sort this array and the smis as pairs wrt. the smis.
-  void SortPairs(FixedArray* smis);
+  // Sort prefix of this array and the numbers array as pairs wrt. the
+  // numbers.  If the numbers array and the this array are the same
+  // object, the prefix of this array is sorted.
+  void SortPairs(FixedArray* numbers, uint32_t len);
 
  protected:
   // Set operation on FixedArray without using write barriers.
@@ -2590,6 +2603,9 @@
   // extracted.
   DECL_ACCESSORS(column_offset, Smi)
 
+  // [data]: additional data associated with this script.
+  DECL_ACCESSORS(data, Object)
+
   // [wrapper]: the wrapper cache.
   DECL_ACCESSORS(wrapper, Proxy)
 
@@ -2610,7 +2626,8 @@
   static const int kNameOffset = kSourceOffset + kPointerSize;
   static const int kLineOffsetOffset = kNameOffset + kPointerSize;
   static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
-  static const int kWrapperOffset = kColumnOffsetOffset + kPointerSize;
+  static const int kDataOffset = kColumnOffsetOffset + kPointerSize;
+  static const int kWrapperOffset = kDataOffset + kPointerSize;
   static const int kTypeOffset = kWrapperOffset + kPointerSize;
   static const int kLineEndsOffset = kTypeOffset + kPointerSize;
   static const int kIdOffset = kLineEndsOffset + kPointerSize;
@@ -4147,6 +4164,7 @@
 };
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 // The DebugInfo class holds additional information for a function being
 // debugged.
 class DebugInfo: public Struct {
@@ -4252,6 +4270,7 @@
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
 };
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 
 #undef DECL_BOOLEAN_ACCESSORS
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 9209990..1e71704 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -262,7 +262,8 @@
 }
 
 
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  int frames_size = frames.length();
   void** addresses = NewArray<void*>(frames_size);
 
   int frames_count = backtrace(addresses, frames_size);
@@ -502,27 +503,24 @@
 
 bool FreeBSDSemaphore::Wait(int timeout) {
   const long kOneSecondMicros = 1000000;  // NOLINT
-  const long kOneSecondNanos = 1000000000;  // NOLINT
 
   // Split timeout into second and nanosecond parts.
-  long nanos = (timeout % kOneSecondMicros) * 1000;  // NOLINT
-  time_t secs = timeout / kOneSecondMicros;
+  struct timeval delta;
+  delta.tv_usec = timeout % kOneSecondMicros;
+  delta.tv_sec = timeout / kOneSecondMicros;
 
-  // Get the current real time clock.
-  struct timespec ts;
-  if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
+  struct timeval current_time;
+  // Get the current time.
+  if (gettimeofday(&current_time, NULL) == -1) {
     return false;
   }
 
-  // Calculate realtime for end of timeout.
-  ts.tv_nsec += nanos;
-  if (ts.tv_nsec >= kOneSecondNanos) {
-    ts.tv_nsec -= kOneSecondNanos;
-    ts.tv_nsec++;
-  }
-  ts.tv_sec += secs;
+  // Calculate time for end of timeout.
+  struct timeval end_time;
+  timeradd(&current_time, &delta, &end_time);
 
-  // Wait for semaphore signalled or timeout.
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC(&end_time, &ts);
   while (true) {
     int result = sem_timedwait(&sem_, &ts);
     if (result == 0) return true;  // Successfully got semaphore.
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index f9a5dea..9f5b9ac 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -262,9 +262,10 @@
 }
 
 
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
   // backtrace is a glibc extension.
 #ifdef __GLIBC__
+  int frames_size = frames.length();
   void** addresses = NewArray<void*>(frames_size);
 
   int frames_count = backtrace(addresses, frames_size);
@@ -506,28 +507,34 @@
 }
 
 
+#ifndef TIMEVAL_TO_TIMESPEC
+#define TIMEVAL_TO_TIMESPEC(tv, ts) do {                            \
+    (ts)->tv_sec = (tv)->tv_sec;                                    \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000;                           \
+} while (false)
+#endif
+
+
 bool LinuxSemaphore::Wait(int timeout) {
   const long kOneSecondMicros = 1000000;  // NOLINT
-  const long kOneSecondNanos = 1000000000;  // NOLINT
 
   // Split timeout into second and nanosecond parts.
-  long nanos = (timeout % kOneSecondMicros) * 1000;  // NOLINT
-  time_t secs = timeout / kOneSecondMicros;
+  struct timeval delta;
+  delta.tv_usec = timeout % kOneSecondMicros;
+  delta.tv_sec = timeout / kOneSecondMicros;
 
-  // Get the current realtime clock.
-  struct timespec ts;
-  if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
+  struct timeval current_time;
+  // Get the current time.
+  if (gettimeofday(&current_time, NULL) == -1) {
     return false;
   }
 
-  // Calculate real time for end of timeout.
-  ts.tv_nsec += nanos;
-  if (ts.tv_nsec >= kOneSecondNanos) {
-    ts.tv_nsec -= kOneSecondNanos;
-    ts.tv_nsec++;
-  }
-  ts.tv_sec += secs;
+  // Calculate time for end of timeout.
+  struct timeval end_time;
+  timeradd(&current_time, &delta, &end_time);
 
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC(&end_time, &ts);
   // Wait for semaphore signalled or timeout.
   while (true) {
     int result = sem_timedwait(&sem_, &ts);
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index b13122f..7951543 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -212,10 +212,11 @@
 }
 
 
-int OS::StackWalk(StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<StackFrame> frames) {
 #ifndef MAC_OS_X_VERSION_10_5
   return 0;
 #else
+  int frames_size = frames.length();
   void** addresses = NewArray<void*>(frames_size);
   int frames_count = backtrace(addresses, frames_size);
 
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 3a50b9d..42583f1 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -215,7 +215,7 @@
 }
 
 
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
   UNIMPLEMENTED();
   return 0;
 }
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 7177870..597a217 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1161,7 +1161,7 @@
 // it is triggered by the use of inline assembler.
 #pragma warning(push)
 #pragma warning(disable : 4748)
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
   BOOL ok;
 
   // Load the required functions from DLL's.
@@ -1201,6 +1201,7 @@
   int frames_count = 0;
 
   // Collect stack frames.
+  int frames_size = frames.length();
   while (frames_count < frames_size) {
     ok = _StackWalk64(
         IMAGE_FILE_MACHINE_I386,    // MachineType
@@ -1284,7 +1285,7 @@
 
 #else  // __MINGW32__
 void OS::LogSharedLibraryAddresses() { }
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) { return 0; }
+int OS::StackWalk(Vector<OS::StackFrame> frames) { return 0; }
 #endif  // __MINGW32__
 
 
diff --git a/src/platform.h b/src/platform.h
index db4f2fd..b70095b 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -207,7 +207,7 @@
     char text[kStackWalkMaxTextLen];
   };
 
-  static int StackWalk(StackFrame* frames, int frames_size);
+  static int StackWalk(Vector<StackFrame> frames);
 
   // Factory method for creating platform dependent Mutex.
   // Please use delete to reclaim the storage for the returned Mutex.
diff --git a/src/regexp-macro-assembler-ia32.cc b/src/regexp-macro-assembler-ia32.cc
index c2f76b4..8c92091 100644
--- a/src/regexp-macro-assembler-ia32.cc
+++ b/src/regexp-macro-assembler-ia32.cc
@@ -86,7 +86,7 @@
  *              byte* stack_area_top)
  */
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
     Mode mode,
diff --git a/src/rewriter.cc b/src/rewriter.cc
index 6641f26..4e3676b 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -194,7 +194,7 @@
 
   if (node->name()->length() == 0) {
     // Anonymous function.
-    func_name_inferrer_.SetFuncToInfer(node);
+    func_name_inferrer_.AddFunction(node);
   }
 }
 
@@ -282,10 +282,7 @@
     case Token::ASSIGN:
       // No type can be infered from the general assignment.
 
-      if (node->value()->AsFunctionLiteral() != NULL ||
-          node->value()->AsObjectLiteral() != NULL) {
-        scoped_fni.Enter();
-      }
+      scoped_fni.Enter();
       break;
     case Token::ASSIGN_BIT_OR:
     case Token::ASSIGN_BIT_XOR:
diff --git a/src/runtime.cc b/src/runtime.cc
index ab25c9e..2b350a5 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2688,6 +2688,59 @@
 }
 
 
+Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
+                                        Handle<Object> key,
+                                        Handle<Object> value,
+                                        PropertyAttributes attr) {
+  HandleScope scope;
+
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (Array::IndexFromObject(*key, &index)) {
+    ASSERT(attr == NONE);
+
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
+    // of a string using [] notation.  We need to support this too in
+    // JavaScript.
+    // In the case of a String object we just need to redirect the assignment to
+    // the underlying string if the index is in range.  Since the underlying
+    // string does nothing with the assignment then we can ignore such
+    // assignments.
+    if (js_object->IsStringObjectWithCharacterAt(index)) {
+      return *value;
+    }
+
+    return js_object->SetElement(index, *value);
+  }
+
+  if (key->IsString()) {
+    if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
+      ASSERT(attr == NONE);
+      return js_object->SetElement(index, *value);
+    } else {
+      Handle<String> key_string = Handle<String>::cast(key);
+      key_string->TryFlattenIfNotFlat();
+      return js_object->IgnoreAttributesAndSetLocalProperty(*key_string,
+                                                            *value,
+                                                            attr);
+    }
+  }
+
+  // Call-back into JavaScript to convert the key to a string.
+  bool has_pending_exception = false;
+  Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+  if (has_pending_exception) return Failure::Exception();
+  Handle<String> name = Handle<String>::cast(converted);
+
+  if (name->AsArrayIndex(&index)) {
+    ASSERT(attr == NONE);
+    return js_object->SetElement(index, *value);
+  } else {
+    return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr);
+  }
+}
+
+
 static Object* Runtime_SetProperty(Arguments args) {
   NoHandleAllocation ha;
   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
@@ -3482,6 +3535,7 @@
   return Heap::nan_value();
 }
 
+
 static Object* Runtime_NumberAdd(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
@@ -4158,10 +4212,12 @@
     JSFunction* function = JSFunction::cast(constructor);
 
     // Handle stepping into constructors if step into is active.
+#ifdef ENABLE_DEBUGGER_SUPPORT
     if (Debug::StepInActive()) {
       HandleScope scope;
       Debug::HandleStepIn(Handle<JSFunction>(function), 0, true);
     }
+#endif
 
     if (function->has_initial_map() &&
         function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
@@ -4525,12 +4581,6 @@
 }
 
 
-static Object* Runtime_DebugBreak(Arguments args) {
-  ASSERT(args.length() == 0);
-  return Execution::DebugBreakHelper();
-}
-
-
 static Object* Runtime_StackGuard(Arguments args) {
   ASSERT(args.length() == 1);
 
@@ -4892,26 +4942,6 @@
 }
 
 
-static Object* Runtime_CompileScript(Arguments args) {
-  HandleScope scope;
-  ASSERT(args.length() == 4);
-
-  CONVERT_ARG_CHECKED(String, source, 0);
-  CONVERT_ARG_CHECKED(String, script, 1);
-  CONVERT_CHECKED(Smi, line_attrs, args[2]);
-  int line = line_attrs->value();
-  CONVERT_CHECKED(Smi, col_attrs, args[3]);
-  int col = col_attrs->value();
-  Handle<JSFunction> boilerplate =
-      Compiler::Compile(source, script, line, col, NULL, NULL);
-  if (boilerplate.is_null()) return Failure::Exception();
-  Handle<JSFunction> fun =
-      Factory::NewFunctionFromBoilerplate(boilerplate,
-                                          Handle<Context>(Top::context()));
-  return *fun;
-}
-
-
 static Object* Runtime_SetNewFunctionAttributes(Arguments args) {
   // This utility adjusts the property attributes for newly created Function
   // object ("new Function(...)") by changing the map.
@@ -5316,6 +5346,13 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+static Object* Runtime_DebugBreak(Arguments args) {
+  ASSERT(args.length() == 0);
+  return Execution::DebugBreakHelper();
+}
+
+
 // Helper functions for wrapping and unwrapping stack frame ids.
 static Smi* WrapFrameId(StackFrame::Id id) {
   ASSERT(IsAligned(OffsetFrom(id), 4));
@@ -5928,8 +5965,8 @@
   if (result->IsFailure()) return result;
 
   static const int kMaxCFramesSize = 200;
-  OS::StackFrame frames[kMaxCFramesSize];
-  int frames_count = OS::StackWalk(frames, kMaxCFramesSize);
+  ScopedVector<OS::StackFrame> frames(kMaxCFramesSize);
+  int frames_count = OS::StackWalk(frames);
   if (frames_count == OS::kStackWalkError) {
     return Heap::undefined_value();
   }
@@ -6796,6 +6833,22 @@
 }
 
 
+static Object* Runtime_FunctionGetAssemblerCode(Arguments args) {
+#ifdef DEBUG
+  HandleScope scope;
+  ASSERT(args.length() == 1);
+  // Get the function and make sure it is compiled.
+  CONVERT_ARG_CHECKED(JSFunction, func, 0);
+  if (!func->is_compiled() && !CompileLazy(func, KEEP_EXCEPTION)) {
+    return Failure::Exception();
+  }
+  func->code()->PrintLn();
+#endif  // DEBUG
+  return Heap::undefined_value();
+}
+#endif  // ENABLE_DEBUGGER_SUPPORT
+
+
 // Finds the script object from the script data. NOTE: This operation uses
 // heap traversal to find the function generated for the source position
 // for the requested break point. For lazily compiled functions several heap
@@ -6845,21 +6898,6 @@
 }
 
 
-static Object* Runtime_FunctionGetAssemblerCode(Arguments args) {
-#ifdef DEBUG
-  HandleScope scope;
-  ASSERT(args.length() == 1);
-  // Get the function and make sure it is compiled.
-  CONVERT_ARG_CHECKED(JSFunction, func, 0);
-  if (!func->is_compiled() && !CompileLazy(func, KEEP_EXCEPTION)) {
-    return Failure::Exception();
-  }
-  func->code()->PrintLn();
-#endif  // DEBUG
-  return Heap::undefined_value();
-}
-
-
 static Object* Runtime_Abort(Arguments args) {
   ASSERT(args.length() == 2);
   OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) +
diff --git a/src/runtime.h b/src/runtime.h
index 657e5c5..6bd19f6 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -195,7 +195,6 @@
   \
   /* Globals */ \
   F(CompileString, 2) \
-  F(CompileScript, 4) \
   F(GlobalPrint, 1) \
   \
   /* Eval */ \
@@ -215,42 +214,6 @@
   F(DefineAccessor, -1 /* 4 or 5 */) \
   F(LookupAccessor, 3) \
   \
-  /* Debugging */ \
-  F(SetDebugEventListener, 2) \
-  F(Break, 0) \
-  F(DebugGetPropertyDetails, 2) \
-  F(DebugGetProperty, 2) \
-  F(DebugLocalPropertyNames, 1) \
-  F(DebugLocalElementNames, 1) \
-  F(DebugPropertyTypeFromDetails, 1) \
-  F(DebugPropertyAttributesFromDetails, 1) \
-  F(DebugPropertyIndexFromDetails, 1) \
-  F(DebugInterceptorInfo, 1) \
-  F(DebugNamedInterceptorPropertyNames, 1) \
-  F(DebugIndexedInterceptorElementNames, 1) \
-  F(DebugNamedInterceptorPropertyValue, 2) \
-  F(DebugIndexedInterceptorElementValue, 2) \
-  F(CheckExecutionState, 1) \
-  F(GetFrameCount, 1) \
-  F(GetFrameDetails, 2) \
-  F(GetCFrames, 1) \
-  F(GetThreadCount, 1) \
-  F(GetThreadDetails, 2) \
-  F(GetBreakLocations, 1) \
-  F(SetFunctionBreakPoint, 3) \
-  F(SetScriptBreakPoint, 3) \
-  F(ClearBreakPoint, 1) \
-  F(ChangeBreakOnException, 2) \
-  F(PrepareStep, 3) \
-  F(ClearStepping, 0) \
-  F(DebugEvaluate, 4) \
-  F(DebugEvaluateGlobal, 3) \
-  F(DebugGetLoadedScripts, 0) \
-  F(DebugReferencedBy, 3) \
-  F(DebugConstructedBy, 2) \
-  F(DebugGetPrototype, 1) \
-  F(SystemBreak, 0) \
-  \
   /* Literals */ \
   F(MaterializeRegExpLiteral, 4)\
   F(CreateArrayLiteralBoilerplate, 3) \
@@ -290,8 +253,6 @@
   F(DebugTrace, 0) \
   F(TraceEnter, 0) \
   F(TraceExit, 1) \
-  F(DebugBreak, 0) \
-  F(FunctionGetAssemblerCode, 1) \
   F(Abort, 2) \
   /* Logging */ \
   F(Log, 2) \
@@ -299,6 +260,48 @@
   /* Pseudo functions - handled as macros by parser */ \
   F(IS_VAR, 1)
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
+  /* Debugger support*/ \
+  F(DebugBreak, 0) \
+  F(SetDebugEventListener, 2) \
+  F(Break, 0) \
+  F(DebugGetPropertyDetails, 2) \
+  F(DebugGetProperty, 2) \
+  F(DebugLocalPropertyNames, 1) \
+  F(DebugLocalElementNames, 1) \
+  F(DebugPropertyTypeFromDetails, 1) \
+  F(DebugPropertyAttributesFromDetails, 1) \
+  F(DebugPropertyIndexFromDetails, 1) \
+  F(DebugInterceptorInfo, 1) \
+  F(DebugNamedInterceptorPropertyNames, 1) \
+  F(DebugIndexedInterceptorElementNames, 1) \
+  F(DebugNamedInterceptorPropertyValue, 2) \
+  F(DebugIndexedInterceptorElementValue, 2) \
+  F(CheckExecutionState, 1) \
+  F(GetFrameCount, 1) \
+  F(GetFrameDetails, 2) \
+  F(GetCFrames, 1) \
+  F(GetThreadCount, 1) \
+  F(GetThreadDetails, 2) \
+  F(GetBreakLocations, 1) \
+  F(SetFunctionBreakPoint, 3) \
+  F(SetScriptBreakPoint, 3) \
+  F(ClearBreakPoint, 1) \
+  F(ChangeBreakOnException, 2) \
+  F(PrepareStep, 3) \
+  F(ClearStepping, 0) \
+  F(DebugEvaluate, 4) \
+  F(DebugEvaluateGlobal, 3) \
+  F(DebugGetLoadedScripts, 0) \
+  F(DebugReferencedBy, 3) \
+  F(DebugConstructedBy, 2) \
+  F(DebugGetPrototype, 1) \
+  F(SystemBreak, 0) \
+  F(FunctionGetAssemblerCode, 1)
+#else
+#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
+#endif
 
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
@@ -316,7 +319,8 @@
 
 #define RUNTIME_FUNCTION_LIST(F) \
   RUNTIME_FUNCTION_LIST_ALWAYS(F) \
-  RUNTIME_FUNCTION_LIST_DEBUG(F)
+  RUNTIME_FUNCTION_LIST_DEBUG(F) \
+  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 
 // ----------------------------------------------------------------------------
 // Runtime provides access to all C++ runtime functions.
@@ -369,6 +373,11 @@
                                    Handle<Object> value,
                                    PropertyAttributes attr);
 
+  static Object* ForceSetObjectProperty(Handle<JSObject> object,
+                                        Handle<Object> key,
+                                        Handle<Object> value,
+                                        PropertyAttributes attr);
+
   static Object* GetObjectProperty(Handle<Object> object, Handle<Object> key);
 
   // This function is used in FunctionNameUsing* tests.
diff --git a/src/serialize.cc b/src/serialize.cc
index 9a2be23..e15c003 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -548,6 +548,7 @@
     AddFromId(ref_table[i].type, ref_table[i].id, ref_table[i].name);
   }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Debug addresses
   Add(Debug_Address(Debug::k_after_break_target_address).address(),
       DEBUG_ADDRESS,
@@ -567,6 +568,7 @@
         Debug::k_register_address << kDebugIdShift | i,
         name.start());
   }
+#endif
 
   // Stat counters
   struct StatsRefTableEntry {
@@ -659,10 +661,6 @@
       UNCLASSIFIED,
       4,
       "RegExpStack::limit_address()");
-  Add(ExternalReference::debug_break().address(),
-      UNCLASSIFIED,
-      5,
-      "Debug::Break()");
   Add(ExternalReference::new_space_start().address(),
       UNCLASSIFIED,
       6,
@@ -679,10 +677,28 @@
       UNCLASSIFIED,
       9,
       "Heap::NewSpaceAllocationTopAddress()");
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  Add(ExternalReference::debug_break().address(),
+      UNCLASSIFIED,
+      5,
+      "Debug::Break()");
   Add(ExternalReference::debug_step_in_fp_address().address(),
       UNCLASSIFIED,
       10,
       "Debug::step_in_fp_addr()");
+  Add(ExternalReference::double_fp_operation(Token::ADD).address(),
+      UNCLASSIFIED,
+      11,
+      "add_two_doubles");
+  Add(ExternalReference::double_fp_operation(Token::SUB).address(),
+      UNCLASSIFIED,
+      12,
+      "sub_two_doubles");
+  Add(ExternalReference::double_fp_operation(Token::MUL).address(),
+      UNCLASSIFIED,
+      13,
+      "mul_two_doubles");
+#endif
 }
 
 
diff --git a/src/simulator-arm.cc b/src/simulator-arm.cc
index 5a61107..7d96b3a 100644
--- a/src/simulator-arm.cc
+++ b/src/simulator-arm.cc
@@ -90,12 +90,44 @@
 }
 
 
+
+#ifdef GENERATED_CODE_COVERAGE
+static FILE* coverage_log = NULL;
+
+
+static void InitializeCoverage() {
+  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
+  if (file_name != NULL) {
+    coverage_log = fopen(file_name, "aw+");
+  }
+}
+
+
+void Debugger::Stop(Instr* instr) {
+  char* str = reinterpret_cast<char*>(instr->InstructionBits() & 0x0fffffff);
+  if (strlen(str) > 0) {
+    if (coverage_log != NULL) {
+      fprintf(coverage_log, "%s\n", str);
+      fflush(coverage_log);
+    }
+    instr->SetInstructionBits(0xe1a00000);  // Overwrite with nop.
+  }
+  sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
+}
+
+#else  // ndef GENERATED_CODE_COVERAGE
+
+static void InitializeCoverage() {
+}
+
+
 void Debugger::Stop(Instr* instr) {
   const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
   PrintF("Simulator hit %s\n", str);
   sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
   Debug();
 }
+#endif
 
 
 static const char* reg_names[] = {  "r0",  "r1",  "r2",  "r3",
@@ -375,6 +407,7 @@
   // access violation if the simulator ever tries to execute it.
   registers_[pc] = bad_lr;
   registers_[lr] = bad_lr;
+  InitializeCoverage();
 }
 
 
@@ -427,6 +460,37 @@
 }
 
 
+// For use in calls that take two double values, constructed from r0, r1, r2
+// and r3.
+void Simulator::GetFpArgs(double* x, double* y) {
+  // We use a char buffer to get around the strict-aliasing rules which
+  // otherwise allow the compiler to optimize away the copy.
+  char buffer[2 * sizeof(registers_[0])];
+  // Registers 0 and 1 -> x.
+  memcpy(buffer, registers_, sizeof(buffer));
+  memcpy(x, buffer, sizeof(buffer));
+  // Registers 2 and 3 -> y.
+  memcpy(buffer, registers_ + 2, sizeof(buffer));
+  memcpy(y, buffer, sizeof(buffer));
+}
+
+
+void Simulator::SetFpResult(const double& result) {
+  char buffer[2 * sizeof(registers_[0])];
+  memcpy(buffer, &result, sizeof(buffer));
+  // result -> registers 0 and 1.
+  memcpy(registers_, buffer, sizeof(buffer));
+}
+
+
+void Simulator::TrashCallerSaveRegisters() {
+  // We don't trash the registers with the return value.
+  registers_[2] = 0x50Bad4U;
+  registers_[3] = 0x50Bad4U;
+  registers_[12] = 0x50Bad4U;
+}
+
+
 // The ARM cannot do unaligned reads and writes.  On some ARM platforms an
 // interrupt is caused.  On others it does a funky rotation thing.  For now we
 // simply disallow unaligned reads, but at some point we may want to move to
@@ -862,7 +926,8 @@
 // Software interrupt instructions are used by the simulator to call into the
 // C-based V8 runtime.
 void Simulator::SoftwareInterrupt(Instr* instr) {
-  switch (instr->SwiField()) {
+  int swi = instr->SwiField();
+  switch (swi) {
     case call_rt_r5: {
       SimulatorRuntimeCall target =
           reinterpret_cast<SimulatorRuntimeCall>(get_register(r5));
@@ -894,6 +959,30 @@
       dbg.Debug();
       break;
     }
+    {
+      double x, y, z;
+    case simulator_fp_add:
+      GetFpArgs(&x, &y);
+      z = x + y;
+      SetFpResult(z);
+      TrashCallerSaveRegisters();
+      set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
+      break;
+    case simulator_fp_sub:
+      GetFpArgs(&x, &y);
+      z = x - y;
+      SetFpResult(z);
+      TrashCallerSaveRegisters();
+      set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
+      break;
+    case simulator_fp_mul:
+      GetFpArgs(&x, &y);
+      z = x * y;
+      SetFpResult(z);
+      TrashCallerSaveRegisters();
+      set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
+      break;
+    }
     default: {
       UNREACHABLE();
       break;
diff --git a/src/simulator-arm.h b/src/simulator-arm.h
index 4f3c53d..5553ab2 100644
--- a/src/simulator-arm.h
+++ b/src/simulator-arm.h
@@ -174,6 +174,12 @@
   // Executes one instruction.
   void InstructionDecode(Instr* instr);
 
+  // For use in calls that take two double values, constructed from r0, r1, r2
+  // and r3.
+  void GetFpArgs(double* x, double* y);
+  void SetFpResult(const double& result);
+  void TrashCallerSaveRegisters();
+
   // architecture state
   int32_t registers_[16];
   bool n_flag_;
diff --git a/src/string-stream.cc b/src/string-stream.cc
index f311e20..2e0912f 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -57,19 +57,26 @@
 
 
 bool StringStream::Put(char c) {
-  if (space() == 0) return false;
-  if (length_ >= capacity_ - 1) {
+  if (full()) return false;
+  ASSERT(length_ < capacity_);
+  // Since the trailing '\0' is not accounted for in length_ fullness is
+  // indicated by a difference of 1 between length_ and capacity_. Thus when
+  // reaching a difference of 2 we need to grow the buffer.
+  if (length_ == capacity_ - 2) {
     unsigned new_capacity = capacity_;
     char* new_buffer = allocator_->grow(&new_capacity);
     if (new_capacity > capacity_) {
       capacity_ = new_capacity;
       buffer_ = new_buffer;
     } else {
-      // Indicate truncation with dots.
-      memset(cursor(), '.', space());
-      length_ = capacity_;
-      buffer_[length_ - 2] = '\n';
-      buffer_[length_ - 1] = '\0';
+      // Reached the end of the available buffer.
+      ASSERT(capacity_ >= 5);
+      length_ = capacity_ - 1;  // Indicate fullness of the stream.
+      buffer_[length_ - 4] = '.';
+      buffer_[length_ - 3] = '.';
+      buffer_[length_ - 2] = '.';
+      buffer_[length_ - 1] = '\n';
+      buffer_[length_] = '\0';
       return false;
     }
   }
@@ -95,8 +102,7 @@
 
 void StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) {
   // If we already ran out of space then return immediately.
-  if (space() == 0)
-    return;
+  if (full()) return;
   int offset = 0;
   int elm = 0;
   while (offset < format.length()) {
@@ -564,12 +570,10 @@
 }
 
 
+// Only grow once to the maximum allowable size.
 char* NoAllocationStringAllocator::grow(unsigned* bytes) {
-  unsigned new_bytes = *bytes * 2;
-  if (new_bytes > size_) {
-    new_bytes = size_;
-  }
-  *bytes = new_bytes;
+  ASSERT(size_ >= *bytes);
+  *bytes = size_;
   return space_;
 }
 
diff --git a/src/string-stream.h b/src/string-stream.h
index 37ae93e..901f376 100644
--- a/src/string-stream.h
+++ b/src/string-stream.h
@@ -162,8 +162,8 @@
   unsigned length_;  // does not include terminating 0-character
   char* buffer_;
 
+  bool full() const { return (capacity_ - length_) == 1; }
   int space() const { return capacity_ - length_; }
-  char* cursor() const { return buffer_ + length_; }
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
 };
diff --git a/src/stub-cache-arm.cc b/src/stub-cache-arm.cc
index 211b643..56afa02 100644
--- a/src/stub-cache-arm.cc
+++ b/src/stub-cache-arm.cc
@@ -33,7 +33,7 @@
 
 namespace v8 { namespace internal {
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 static void ProbeTable(MacroAssembler* masm,
@@ -183,7 +183,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
   GenerateFastPropertyLoad(masm, r0, reg, holder, index);
   __ Ret();
 }
@@ -203,7 +203,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Return the constant value.
   __ mov(r0, Operand(Handle<Object>(value)));
@@ -226,7 +226,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Push the arguments on the JS stack of the caller.
   __ push(receiver);  // receiver
@@ -256,7 +256,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Push the arguments on the JS stack of the caller.
   __ push(receiver);  // receiver
@@ -456,8 +456,7 @@
 
 
 #undef __
-
-#define __ masm()->
+#define __ ACCESS_MASM(masm())
 
 
 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) {
@@ -511,7 +510,7 @@
 
   // Do the right check and compute the holder register.
   Register reg =
-      __ CheckMaps(JSObject::cast(object), r0, holder, r3, r2, &miss);
+      masm()->CheckMaps(JSObject::cast(object), r0, holder, r3, r2, &miss);
   GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
 
   // Check that the function really is a function.
diff --git a/src/stub-cache-ia32.cc b/src/stub-cache-ia32.cc
index 19777e6..bdfc3d6 100644
--- a/src/stub-cache-ia32.cc
+++ b/src/stub-cache-ia32.cc
@@ -33,7 +33,7 @@
 
 namespace v8 { namespace internal {
 
-#define __ masm->
+#define __ ACCESS_MASM(masm)
 
 
 static void ProbeTable(MacroAssembler* masm,
@@ -256,7 +256,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Get the value from the properties.
   GenerateFastPropertyLoad(masm, eax, reg, holder, index);
@@ -279,7 +279,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Push the arguments on the JS stack of the caller.
   __ pop(scratch2);  // remove return address
@@ -310,7 +310,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Return the constant value.
   __ mov(eax, Handle<Object>(value));
@@ -332,7 +332,7 @@
 
   // Check that the maps haven't changed.
   Register reg =
-      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
+      masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);
 
   // Push the arguments on the JS stack of the caller.
   __ pop(scratch2);  // remove return address
@@ -440,7 +440,7 @@
 
 #undef __
 
-#define __ masm()->
+#define __ ACCESS_MASM(masm())
 
 
 // TODO(1241006): Avoid having lazy compile stubs specialized by the
@@ -485,7 +485,7 @@
 
   // Do the right check and compute the holder register.
   Register reg =
-      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);
+      masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);
 
   GenerateFastPropertyLoad(masm(), edi, reg, holder, index);
 
@@ -656,7 +656,7 @@
 
   // Check that maps have not changed and compute the holder register.
   Register reg =
-      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);
+      masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);
 
   // Enter an internal frame.
   __ EnterInternalFrame();
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 35e3d42..6811fd2 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -594,6 +594,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Object* StubCache::ComputeCallDebugBreak(int argc) {
   Code::Flags flags =
       Code::ComputeFlags(Code::CALL_IC, DEBUG_BREAK, NORMAL, argc);
@@ -612,6 +613,7 @@
   StubCompiler compiler;
   return FillCache(compiler.CompileCallDebugPrepareStepIn(flags));
 }
+#endif
 
 
 Object* StubCache::ComputeLazyCompile(int argc) {
@@ -836,6 +838,7 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
   HandleScope scope;
   Debug::GenerateCallICDebugBreak(masm());
@@ -864,6 +867,7 @@
   }
   return result;
 }
+#endif
 
 
 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, const char* name) {
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 05845e5..824f4ff 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -157,8 +157,10 @@
   // Finds the Code object stored in the Heap::non_monomorphic_cache().
   static Code* FindCallInitialize(int argc);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   static Object* ComputeCallDebugBreak(int argc);
   static Object* ComputeCallDebugPrepareStepIn(int argc);
+#endif
 
   static Object* ComputeLazyCompile(int argc);
 
@@ -288,8 +290,10 @@
   Object* CompileCallNormal(Code::Flags flags);
   Object* CompileCallMegamorphic(Code::Flags flags);
   Object* CompileCallMiss(Code::Flags flags);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Object* CompileCallDebugBreak(Code::Flags flags);
   Object* CompileCallDebugPrepareStepIn(Code::Flags flags);
+#endif
   Object* CompileLazyCompile(Code::Flags flags);
 
   // Static functions for generating parts of stubs.
diff --git a/src/top.cc b/src/top.cc
index a99e9ff..96f98a5 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -116,15 +116,15 @@
   // When the thread starts running it will allocate a fixed number of bytes
   // on the stack and publish the location of this memory for others to use.
   void Run() {
-    EmbeddedVector<char, 32 * 1024> local_buffer;
+    EmbeddedVector<char, 15 * 1024> local_buffer;
 
     // Initialize the buffer with a known good value.
     OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
                 local_buffer.length());
 
     // Publish the local buffer and signal its availability.
-    data_ = &local_buffer[0];
-    length_ = sizeof(local_buffer);
+    data_ = local_buffer.start();
+    length_ = local_buffer.length();
     data_ready_semaphore_->Signal();
 
     while (keep_running_) {
@@ -728,8 +728,10 @@
   bool should_return_exception = ShouldReportException(&is_caught_externally);
   bool report_exception = !is_out_of_memory && should_return_exception;
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger of exception.
   Debugger::OnException(exception_handle, report_exception);
+#endif
 
   // Generate the message.
   Handle<Object> message_obj;
diff --git a/src/utils.h b/src/utils.h
index f62b47a..e008c85 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -406,6 +406,16 @@
 };
 
 
+template <typename T>
+class ScopedVector : public Vector<T> {
+ public:
+  explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
+  ~ScopedVector() {
+    DeleteArray(this->start());
+  }
+};
+
+
 inline Vector<const char> CStrVector(const char* data) {
   return Vector<const char>(data, strlen(data));
 }
diff --git a/src/v8.cc b/src/v8.cc
index 9158b52..fbe3d5d 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -72,7 +72,9 @@
     v8::Locker::StartPreemption(100);
   }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Debug::Setup(create_heap_objects);
+#endif
   StubCache::Initialize(create_heap_objects);
 
   // If we are deserializing, read the state into the now-empty heap.
@@ -111,7 +113,9 @@
   Heap::TearDown();
   Logger::TearDown();
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
   Debugger::TearDown();
+#endif
 
   has_been_setup_ = false;
   has_been_disposed_ = true;
diff --git a/src/v8.h b/src/v8.h
index 4cf0b70..4ced0d2 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -51,6 +51,11 @@
 #error both DEBUG and NDEBUG are set
 #endif
 
+// Enable debugger support by default, unless it is in ANDROID
+#if !defined(ENABLE_DEBUGGER_SUPPORT) && !defined(ANDROID)
+#define ENABLE_DEBUGGER_SUPPORT
+#endif
+
 // Basic includes
 #include "../include/v8.h"
 #include "globals.h"
diff --git a/src/v8threads.cc b/src/v8threads.cc
index e8f6f9b..2439476 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -144,7 +144,9 @@
   char* from = state->data();
   from = HandleScopeImplementer::RestoreThread(from);
   from = Top::RestoreThread(from);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   from = Debug::RestoreDebug(from);
+#endif
   from = StackGuard::RestoreStackGuard(from);
   from = RegExpStack::RestoreStack(from);
   from = Bootstrapper::RestoreState(from);
@@ -172,7 +174,9 @@
 static int ArchiveSpacePerThread() {
   return HandleScopeImplementer::ArchiveSpacePerThread() +
                             Top::ArchiveSpacePerThread() +
+#ifdef ENABLE_DEBUGGER_SUPPORT
                           Debug::ArchiveSpacePerThread() +
+#endif
                      StackGuard::ArchiveSpacePerThread() +
                     RegExpStack::ArchiveSpacePerThread() +
                    Bootstrapper::ArchiveSpacePerThread();
@@ -259,7 +263,9 @@
   char* to = state->data();
   to = HandleScopeImplementer::ArchiveThread(to);
   to = Top::ArchiveThread(to);
+#ifdef ENABLE_DEBUGGER_SUPPORT
   to = Debug::ArchiveDebug(to);
+#endif
   to = StackGuard::ArchiveStackGuard(to);
   to = RegExpStack::ArchiveStack(to);
   to = Bootstrapper::ArchiveState(to);
diff --git a/src/virtual-frame-arm.cc b/src/virtual-frame-arm.cc
index baf0814..b794d8b 100644
--- a/src/virtual-frame-arm.cc
+++ b/src/virtual-frame-arm.cc
@@ -36,7 +36,8 @@
 // -------------------------------------------------------------------------
 // VirtualFrame implementation.
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
+
 
 // On entry to a function, the virtual frame already contains the
 // receiver and the parameters.  All initial frame elements are in
diff --git a/src/virtual-frame-ia32.cc b/src/virtual-frame-ia32.cc
index eb3befc..3647ca5 100644
--- a/src/virtual-frame-ia32.cc
+++ b/src/virtual-frame-ia32.cc
@@ -33,7 +33,7 @@
 
 namespace v8 { namespace internal {
 
-#define __ masm_->
+#define __ ACCESS_MASM(masm_)
 
 // -------------------------------------------------------------------------
 // VirtualFrame implementation.