Merge "make sure the snapshot is built with the right flags depending on arch"
diff --git a/AUTHORS b/AUTHORS
index 9128ba3..8b0db5c 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -23,3 +23,4 @@
 Ryan Dahl <coldredlemur@gmail.com>
 Patrick Gansterer <paroga@paroga.com>
 Subrato K De <subratokde@codeaurora.org>
+Dineel D Sule <dsule@codeaurora.org>
diff --git a/Android.v8common.mk b/Android.v8common.mk
index 6d8034b..ded5f61 100644
--- a/Android.v8common.mk
+++ b/Android.v8common.mk
@@ -38,6 +38,7 @@
 	src/interpreter-irregexp.cc \
 	src/jsregexp.cc \
 	src/jump-target.cc \
+	src/liveedit.cc \
 	src/log.cc \
 	src/log-utils.cc \
 	src/mark-compact.cc \
diff --git a/ChangeLog b/ChangeLog
index 29ecccd..339fd18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2010-02-23: Version 2.1.2
+
+        Fix a crash bug caused by wrong assert.
+
+        Fix a bug with register names on 64-bit V8 (issue 615).
+
+        Performance improvements on all platforms.
+
+2010-02-19: Version 2.1.1
+
+        [ES5] Implemented Object.defineProperty.
+
+        Improved profiler support.
+
+        Added SetPrototype method in the public V8 API.
+
+        Added GetScriptOrigin and GetScriptLineNumber methods to Function
+        objects in the API.
+
+        Performance improvements on all platforms.
+
+
 2010-02-03: Version 2.1.0
 
         Values are now always wrapped in objects when used as a receiver.
diff --git a/include/v8.h b/include/v8.h
index 19a41f4..c911cc7 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -534,51 +534,76 @@
 class V8EXPORT Script {
  public:
 
-   /**
-    * Compiles the specified script. The ScriptOrigin* and ScriptData*
-    * parameters are owned by the caller of Script::Compile. No
-    * references to these objects are kept after compilation finishes.
-    *
-    * The script object returned is context independent; when run it
-    * will use the currently entered context.
-    */
-   static Local<Script> New(Handle<String> source,
-                            ScriptOrigin* origin = NULL,
-                            ScriptData* pre_data = NULL);
-
-   /**
-    * Compiles the specified script using the specified file name
-    * object (typically a string) as the script's origin.
-    *
-    * The script object returned is context independent; when run it
-    * will use the currently entered context.
-    */
-   static Local<Script> New(Handle<String> source,
-                            Handle<Value> file_name);
-
   /**
-   * Compiles the specified script. The ScriptOrigin* and ScriptData*
-   * parameters are owned by the caller of Script::Compile. No
-   * references to these objects are kept after compilation finishes.
+   * Compiles the specified script (context-independent).
    *
-   * The script object returned is bound to the context that was active
-   * when this function was called.  When run it will always use this
-   * context.
+   * \param source Script source code.
+   * \param origin Script origin, owned by caller, no references are kept 
+   *   when New() returns
+   * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
+   *   using pre_data speeds compilation if it's done multiple times.
+   *   Owned by caller, no references are kept when New() returns.
+   * \param script_data Arbitrary data associated with script. Using
+   *   this has same effect as calling SetData(), but allows data to be 
+   *   available to compile event handlers.
+   * \return Compiled script object (context independent; when run it
+   *   will use the currently entered context).
    */
-  static Local<Script> Compile(Handle<String> source,
-                               ScriptOrigin* origin = NULL,
-                               ScriptData* pre_data = NULL);
+  static Local<Script> New(Handle<String> source,
+                           ScriptOrigin* origin = NULL,
+                           ScriptData* pre_data = NULL,
+                           Handle<String> script_data = Handle<String>());
 
   /**
    * Compiles the specified script using the specified file name
    * object (typically a string) as the script's origin.
    *
-   * The script object returned is bound to the context that was active
-   * when this function was called.  When run it will always use this
-   * context.
+   * \param source Script source code.
+   * \patam file_name file name object (typically a string) to be used 
+   *   as the script's origin.
+   * \return Compiled script object (context independent; when run it
+   *   will use the currently entered context).
+   */
+  static Local<Script> New(Handle<String> source,
+                           Handle<Value> file_name);
+
+  /**
+   * Compiles the specified script (bound to current context).
+   *
+   * \param source Script source code.
+   * \param origin Script origin, owned by caller, no references are kept 
+   *   when Compile() returns
+   * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
+   *   using pre_data speeds compilation if it's done multiple times.
+   *   Owned by caller, no references are kept when Compile() returns.
+   * \param script_data Arbitrary data associated with script. Using
+   *   this has same effect as calling SetData(), but makes data available
+   *   earlier (i.e. to compile event handlers).
+   * \return Compiled script object, bound to the context that was active
+   *   when this function was called.  When run it will always use this
+   *   context.
    */
   static Local<Script> Compile(Handle<String> source,
-                               Handle<Value> file_name);
+                               ScriptOrigin* origin = NULL,
+                               ScriptData* pre_data = NULL,
+                               Handle<String> script_data = Handle<String>());
+
+  /**
+   * Compiles the specified script using the specified file name
+   * object (typically a string) as the script's origin.
+   *
+   * \param source Script source code.
+   * \param file_name File name to use as script's origin
+   * \param script_data Arbitrary data associated with script. Using
+   *   this has same effect as calling SetData(), but makes data available
+   *   earlier (i.e. to compile event handlers).
+   * \return Compiled script object, bound to the context that was active
+   *   when this function was called.  When run it will always use this
+   *   context.
+   */
+  static Local<Script> Compile(Handle<String> source,
+                               Handle<Value> file_name,
+                               Handle<String> script_data = Handle<String>());
 
   /**
    * Runs the script returning the resulting value.  If the script is
@@ -1197,6 +1222,13 @@
   Local<Value> GetPrototype();
 
   /**
+   * Set the prototype object.  This does not skip objects marked to
+   * be skipped by __proto__ and it does not consult the security
+   * handler.
+   */
+  bool SetPrototype(Handle<Value> prototype);
+
+  /**
    * Finds an instance of the given function template in the prototype
    * chain.
    */
@@ -1354,7 +1386,15 @@
   Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]);
   void SetName(Handle<String> name);
   Handle<Value> GetName() const;
+
+  /**
+   * Returns zero based line number of function body and
+   * kLineOffsetNotFound if no information available.
+   */
+  int GetScriptLineNumber() const;
+  ScriptOrigin GetScriptOrigin() const;
   static inline Function* Cast(Value* obj);
+  static const int kLineOffsetNotFound;
  private:
   Function();
   static void CheckCast(Value* obj);
@@ -2309,22 +2349,30 @@
   static bool IsProfilerPaused();
 
   /**
-   * Resumes specified profiler modules.
+   * Resumes specified profiler modules. Can be called several times to
+   * mark the opening of a profiler events block with the given tag.
+   *
    * "ResumeProfiler" is equivalent to "ResumeProfilerEx(PROFILER_MODULE_CPU)".
    * See ProfilerModules enum.
    *
    * \param flags Flags specifying profiler modules.
+   * \param tag Profile tag.
    */
-  static void ResumeProfilerEx(int flags);
+  static void ResumeProfilerEx(int flags, int tag = 0);
 
   /**
-   * Pauses specified profiler modules.
+   * Pauses specified profiler modules. Each call to "PauseProfilerEx" closes
+   * a block of profiler events opened by a call to "ResumeProfilerEx" with the
+   * same tag value. There is no need for blocks to be properly nested.
+   * The profiler is paused when the last opened block is closed.
+   *
    * "PauseProfiler" is equivalent to "PauseProfilerEx(PROFILER_MODULE_CPU)".
    * See ProfilerModules enum.
    *
    * \param flags Flags specifying profiler modules.
+   * \param tag Profile tag.
    */
-  static void PauseProfilerEx(int flags);
+  static void PauseProfilerEx(int flags, int tag = 0);
 
   /**
    * Returns active (resumed) profiler modules.
diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc
index 505dabf..61517d3 100644
--- a/samples/lineprocessor.cc
+++ b/samples/lineprocessor.cc
@@ -152,7 +152,7 @@
     } else if (strcmp(str, "--main-cycle-in-js") == 0) {
       cycle_type = CycleInJs;
     } else if (strcmp(str, "-p") == 0 && i + 1 < argc) {
-      port_number = atoi(argv[i + 1]);
+      port_number = atoi(argv[i + 1]);  // NOLINT
       i++;
     } else if (strncmp(str, "--", 2) == 0) {
       printf("Warning: unknown flag %s.\nTry --help for options\n", str);
diff --git a/src/SConscript b/src/SConscript
index 864b4e7..3b227c8 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -57,7 +57,6 @@
     disassembler.cc
     execution.cc
     factory.cc
-    fast-codegen.cc
     flags.cc
     frame-element.cc
     frames.cc
@@ -72,6 +71,7 @@
     interpreter-irregexp.cc
     jsregexp.cc
     jump-target.cc
+    liveedit.cc
     log-utils.cc
     log.cc
     mark-compact.cc
@@ -108,6 +108,7 @@
     zone.cc
     """),
   'arch:arm': Split("""
+    fast-codegen.cc
     arm/builtins-arm.cc
     arm/codegen-arm.cc
     arm/constants-arm.cc
@@ -132,6 +133,7 @@
     arm/assembler-thumb2.cc
     """),
   'arch:mips': Split("""
+    fast-codegen.cc
     mips/assembler-mips.cc
     mips/builtins-mips.cc
     mips/codegen-mips.cc
@@ -168,6 +170,7 @@
     ia32/virtual-frame-ia32.cc
     """),
   'arch:x64': Split("""
+    fast-codegen.cc
     x64/assembler-x64.cc
     x64/builtins-x64.cc
     x64/codegen-x64.cc
diff --git a/src/accessors.cc b/src/accessors.cc
index 5a02928..b05719e 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -647,42 +647,9 @@
 Object* Accessors::ObjectSetPrototype(JSObject* receiver,
                                       Object* value,
                                       void*) {
-  // Before we can set the prototype we need to be sure
-  // prototype cycles are prevented.
-  // It is sufficient to validate that the receiver is not in the new prototype
-  // chain.
-
-  // Silently ignore the change if value is not a JSObject or null.
-  // SpiderMonkey behaves this way.
-  if (!value->IsJSObject() && !value->IsNull()) return value;
-
-  for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) {
-    if (JSObject::cast(pt) == receiver) {
-      // Cycle detected.
-      HandleScope scope;
-      return Top::Throw(*Factory::NewError("cyclic_proto",
-                                           HandleVector<Object>(NULL, 0)));
-    }
-  }
-
-  // Find the first object in the chain whose prototype object is not
-  // hidden and set the new prototype on that object.
-  JSObject* current = receiver;
-  Object* current_proto = receiver->GetPrototype();
-  while (current_proto->IsJSObject() &&
-         JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
-    current = JSObject::cast(current_proto);
-    current_proto = current_proto->GetPrototype();
-  }
-
-  // Set the new prototype of the object.
-  Object* new_map = current->map()->CopyDropTransitions();
-  if (new_map->IsFailure()) return new_map;
-  Map::cast(new_map)->set_prototype(value);
-  current->set_map(Map::cast(new_map));
-
+  const bool skip_hidden_prototypes = true;
   // To be consistent with other Set functions, return the value.
-  return value;
+  return receiver->SetPrototype(value, skip_hidden_prototypes);
 }
 
 
diff --git a/src/api.cc b/src/api.cc
index a949e6f..262bf52 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1107,7 +1107,8 @@
 
 Local<Script> Script::New(v8::Handle<String> source,
                           v8::ScriptOrigin* origin,
-                          v8::ScriptData* script_data) {
+                          v8::ScriptData* pre_data,
+                          v8::Handle<String> script_data) {
   ON_BAILOUT("v8::Script::New()", return Local<Script>());
   LOG_API("Script::New");
   ENTER_V8;
@@ -1127,13 +1128,13 @@
     }
   }
   EXCEPTION_PREAMBLE();
-  i::ScriptDataImpl* pre_data = static_cast<i::ScriptDataImpl*>(script_data);
+  i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
   // We assert that the pre-data is sane, even though we can actually
   // handle it if it turns out not to be in release mode.
-  ASSERT(pre_data == NULL || pre_data->SanityCheck());
+  ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
   // If the pre-data isn't sane we simply ignore it
-  if (pre_data != NULL && !pre_data->SanityCheck()) {
-    pre_data = NULL;
+  if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
+    pre_data_impl = NULL;
   }
   i::Handle<i::JSFunction> boilerplate =
       i::Compiler::Compile(str,
@@ -1141,7 +1142,8 @@
                            line_offset,
                            column_offset,
                            NULL,
-                           pre_data,
+                           pre_data_impl,
+                           Utils::OpenHandle(*script_data),
                            i::NOT_NATIVES_CODE);
   has_pending_exception = boilerplate.is_null();
   EXCEPTION_BAILOUT_CHECK(Local<Script>());
@@ -1158,11 +1160,12 @@
 
 Local<Script> Script::Compile(v8::Handle<String> source,
                               v8::ScriptOrigin* origin,
-                              v8::ScriptData* script_data) {
+                              v8::ScriptData* pre_data,
+                              v8::Handle<String> script_data) {
   ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
   LOG_API("Script::Compile");
   ENTER_V8;
-  Local<Script> generic = New(source, origin, script_data);
+  Local<Script> generic = New(source, origin, pre_data, script_data);
   if (generic.IsEmpty())
     return generic;
   i::Handle<i::JSFunction> boilerplate = Utils::OpenHandle(*generic);
@@ -1174,9 +1177,10 @@
 
 
 Local<Script> Script::Compile(v8::Handle<String> source,
-                              v8::Handle<Value> file_name) {
+                              v8::Handle<Value> file_name,
+                              v8::Handle<String> script_data) {
   ScriptOrigin origin(file_name);
-  return Compile(source, &origin);
+  return Compile(source, &origin, 0, script_data);
 }
 
 
@@ -2035,6 +2039,19 @@
 }
 
 
+bool v8::Object::SetPrototype(Handle<Value> value) {
+  ON_BAILOUT("v8::Object::SetPrototype()", return false);
+  ENTER_V8;
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
+  has_pending_exception = result.is_null();
+  EXCEPTION_BAILOUT_CHECK(false);
+  return true;
+}
+
+
 Local<Object> v8::Object::FindInstanceInPrototypeChain(
     v8::Handle<FunctionTemplate> tmpl) {
   ON_BAILOUT("v8::Object::FindInstanceInPrototypeChain()",
@@ -2197,7 +2214,7 @@
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
   self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
-  if (lookup.IsValid()) {
+  if (lookup.IsProperty()) {
     PropertyAttributes attributes;
     i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
                                                       &lookup,
@@ -2216,7 +2233,7 @@
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
   self_obj->LookupRealNamedProperty(*key_obj, &lookup);
-  if (lookup.IsValid()) {
+  if (lookup.IsProperty()) {
     PropertyAttributes attributes;
     i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
                                                       &lookup,
@@ -2448,6 +2465,99 @@
 }
 
 
+ScriptOrigin Function::GetScriptOrigin() const {
+  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+  if (func->shared()->script()->IsScript()) {
+    i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
+    v8::ScriptOrigin origin(
+      Utils::ToLocal(i::Handle<i::Object>(script->name())),
+      v8::Integer::New(script->line_offset()->value()),
+      v8::Integer::New(script->column_offset()->value()));
+    return origin;
+  }
+  return v8::ScriptOrigin(Handle<Value>());
+}
+
+
+const int Function::kLineOffsetNotFound = -1;
+
+
+int Function::GetScriptLineNumber() const {
+  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+  if (func->shared()->script()->IsScript()) {
+    i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
+    return i::GetScriptLineNumber(script, func->shared()->start_position());
+  }
+  return kLineOffsetNotFound;
+}
+
+
+namespace {
+
+// Tracks string usage to help make better decisions when
+// externalizing strings.
+//
+// Implementation note: internally this class only tracks fresh
+// strings and keeps a single use counter for them.
+class StringTracker {
+ public:
+  // Records that the given string's characters were copied to some
+  // external buffer. If this happens often we should honor
+  // externalization requests for the string.
+  static void RecordWrite(i::Handle<i::String> string) {
+    i::Address address = reinterpret_cast<i::Address>(*string);
+    i::Address top = i::Heap::NewSpaceTop();
+    if (IsFreshString(address, top)) {
+      IncrementUseCount(top);
+    }
+  }
+
+  // Estimates freshness and use frequency of the given string based
+  // on how close it is to the new space top and the recorded usage
+  // history.
+  static inline bool IsFreshUnusedString(i::Handle<i::String> string) {
+    i::Address address = reinterpret_cast<i::Address>(*string);
+    i::Address top = i::Heap::NewSpaceTop();
+    return IsFreshString(address, top) && IsUseCountLow(top);
+  }
+
+ private:
+  static inline bool IsFreshString(i::Address string, i::Address top) {
+    return top - kFreshnessLimit <= string && string <= top;
+  }
+
+  static inline bool IsUseCountLow(i::Address top) {
+    if (last_top_ != top) return true;
+    return use_count_ < kUseLimit;
+  }
+
+  static inline void IncrementUseCount(i::Address top) {
+    if (last_top_ != top) {
+      use_count_ = 0;
+      last_top_ = top;
+    }
+    ++use_count_;
+  }
+
+  // How close to the new space top a fresh string has to be.
+  static const int kFreshnessLimit = 1024;
+
+  // The number of uses required to consider a string useful.
+  static const int kUseLimit = 32;
+
+  // Single use counter shared by all fresh strings.
+  static int use_count_;
+
+  // Last new space top when the use count above was valid.
+  static i::Address last_top_;
+};
+
+int StringTracker::use_count_ = 0;
+i::Address StringTracker::last_top_ = NULL;
+
+}  // namespace
+
+
 int String::Length() const {
   if (IsDeadCheck("v8::String::Length()")) return 0;
   return Utils::OpenHandle(this)->length();
@@ -2465,6 +2575,7 @@
   LOG_API("String::WriteUtf8");
   ENTER_V8;
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  StringTracker::RecordWrite(str);
   write_input_buffer.Reset(0, *str);
   int len = str->length();
   // Encode the first K - 3 bytes directly into the buffer since we
@@ -2508,6 +2619,7 @@
   ENTER_V8;
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  StringTracker::RecordWrite(str);
   // Flatten the string for efficiency.  This applies whether we are
   // using StringInputBuffer or Get(i) to access the characters.
   str->TryFlattenIfNotFlat();
@@ -2534,6 +2646,7 @@
   ENTER_V8;
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  StringTracker::RecordWrite(str);
   int end = length;
   if ( (length == -1) || (length > str->length() - start) )
     end = str->length() - start;
@@ -3102,6 +3215,7 @@
   if (this->IsExternal()) return false;  // Already an external string.
   ENTER_V8;
   i::Handle<i::String> obj = Utils::OpenHandle(this);
+  if (StringTracker::IsFreshUnusedString(obj)) return false;
   bool result = obj->MakeExternal(resource);
   if (result && !obj->IsSymbol()) {
     i::ExternalStringTable::AddString(*obj);
@@ -3127,6 +3241,7 @@
   if (this->IsExternal()) return false;  // Already an external string.
   ENTER_V8;
   i::Handle<i::String> obj = Utils::OpenHandle(this);
+  if (StringTracker::IsFreshUnusedString(obj)) return false;
   bool result = obj->MakeExternal(resource);
   if (result && !obj->IsSymbol()) {
     i::ExternalStringTable::AddString(*obj);
@@ -3138,6 +3253,7 @@
 bool v8::String::CanMakeExternal() {
   if (IsDeadCheck("v8::String::CanMakeExternal()")) return false;
   i::Handle<i::String> obj = Utils::OpenHandle(this);
+  if (StringTracker::IsFreshUnusedString(obj)) return false;
   int size = obj->Size();  // Byte size of the original string.
   if (size < i::ExternalString::kSize)
     return false;
@@ -3361,14 +3477,14 @@
 
 void V8::PauseProfiler() {
 #ifdef ENABLE_LOGGING_AND_PROFILING
-  i::Logger::PauseProfiler(PROFILER_MODULE_CPU);
+  PauseProfilerEx(PROFILER_MODULE_CPU);
 #endif
 }
 
 
 void V8::ResumeProfiler() {
 #ifdef ENABLE_LOGGING_AND_PROFILING
-  i::Logger::ResumeProfiler(PROFILER_MODULE_CPU);
+  ResumeProfilerEx(PROFILER_MODULE_CPU);
 #endif
 }
 
@@ -3382,7 +3498,7 @@
 }
 
 
-void V8::ResumeProfilerEx(int flags) {
+void V8::ResumeProfilerEx(int flags, int tag) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
     // Snapshot mode: resume modules, perform GC, then pause only
@@ -3392,19 +3508,19 @@
     // Reset snapshot flag and CPU module flags.
     flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
     const int current_flags = i::Logger::GetActiveProfilerModules();
-    i::Logger::ResumeProfiler(flags);
+    i::Logger::ResumeProfiler(flags, tag);
     i::Heap::CollectAllGarbage(false);
-    i::Logger::PauseProfiler(~current_flags & flags);
+    i::Logger::PauseProfiler(~current_flags & flags, tag);
   } else {
-    i::Logger::ResumeProfiler(flags);
+    i::Logger::ResumeProfiler(flags, tag);
   }
 #endif
 }
 
 
-void V8::PauseProfilerEx(int flags) {
+void V8::PauseProfilerEx(int flags, int tag) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
-  i::Logger::PauseProfiler(flags);
+  i::Logger::PauseProfiler(flags, tag);
 #endif
 }
 
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index cf167f0..1b3bcb0 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -47,10 +47,29 @@
 unsigned CpuFeatures::enabled_ = 0;
 unsigned CpuFeatures::found_by_runtime_probing_ = 0;
 
+
+#ifdef __arm__
+static uint64_t CpuFeaturesImpliedByCompiler() {
+  uint64_t answer = 0;
+#ifdef CAN_USE_ARMV7_INSTRUCTIONS
+  answer |= 1u << ARMv7;
+#endif  // def CAN_USE_ARMV7_INSTRUCTIONS
+  // If the compiler is allowed to use VFP then we can use VFP too in our code
+  // generation even when generating snapshots.  This won't work for cross
+  // compilation.
+#if defined(__VFP_FP__) && !defined(__SOFTFP__)
+  answer |= 1u << VFP3;
+#endif  // defined(__VFP_FP__) && !defined(__SOFTFP__)
+#ifdef CAN_USE_VFP_INSTRUCTIONS
+  answer |= 1u << VFP3;
+#endif  // def CAN_USE_VFP_INSTRUCTIONS
+  return answer;
+}
+#endif  // def __arm__
+
+
 void CpuFeatures::Probe() {
-  // If the compiler is allowed to use vfp then we can use vfp too in our
-  // code generation.
-#if !defined(__arm__)
+#ifndef __arm__
   // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled.
   if (FLAG_enable_vfp3) {
       supported_ |= 1u << VFP3;
@@ -59,10 +78,10 @@
   if (FLAG_enable_armv7) {
       supported_ |= 1u << ARMv7;
   }
-#else
+#else  // def __arm__
   if (Serializer::enabled()) {
-      supported_ |= 1u << VFP3;
-    //supported_ |= OS::CpuFeaturesImpliedByPlatform();
+    supported_ |= OS::CpuFeaturesImpliedByPlatform();
+    supported_ |= CpuFeaturesImpliedByCompiler();
     return;  // No features if we might serialize.
   }
 
@@ -77,7 +96,7 @@
     supported_ |= 1u << ARMv7;
     found_by_runtime_probing_ |= 1u << ARMv7;
   }
-#endif
+#endif  // def __arm__
 }
 
 
@@ -621,7 +640,7 @@
     if (!Serializer::enabled()) {
       Serializer::TooLateToEnableNow();
     }
-#endif
+#endif  // def DEBUG
     return Serializer::enabled();
   } else if (rmode == RelocInfo::NONE) {
     return false;
@@ -1226,14 +1245,16 @@
 
 // Exception-generating instructions and debugging support.
 void Assembler::stop(const char* msg) {
-#if !defined(__arm__)
+#ifndef __arm__
   // The simulator handles these special instructions and stops execution.
   emit(15 << 28 | ((intptr_t) msg));
-#else
-  // Just issue a simple break instruction for now. Alternatively we could use
-  // the swi(0x9f0001) instruction on Linux.
+#else  // def __arm__
+#ifdef CAN_USE_ARMV5_INSTRUCTIONS
   bkpt(0);
-#endif
+#else  // ndef CAN_USE_ARMV5_INSTRUCTIONS
+  swi(0x9f0001);
+#endif  // ndef CAN_USE_ARMV5_INSTRUCTIONS
+#endif  // def __arm__
 }
 
 
diff --git a/src/arm/assembler-thumb2-inl.h b/src/arm/assembler-thumb2-inl.h
index 3808ef0..9e0fc2f 100644
--- a/src/arm/assembler-thumb2-inl.h
+++ b/src/arm/assembler-thumb2-inl.h
@@ -174,20 +174,6 @@
 }
 
 
-Operand::Operand(Object** opp) {
-  rm_ = no_reg;
-  imm32_ = reinterpret_cast<int32_t>(opp);
-  rmode_ = RelocInfo::NONE;
-}
-
-
-Operand::Operand(Context** cpp) {
-  rm_ = no_reg;
-  imm32_ = reinterpret_cast<int32_t>(cpp);
-  rmode_ = RelocInfo::NONE;
-}
-
-
 Operand::Operand(Smi* value) {
   rm_ = no_reg;
   imm32_ =  reinterpret_cast<intptr_t>(value);
@@ -229,14 +215,24 @@
 
 
 Address Assembler::target_address_address_at(Address pc) {
-  Instr instr = Memory::int32_at(pc);
-  // Verify that the instruction at pc is a ldr<cond> <Rd>, [pc +/- offset_12].
+  Address target_pc = pc;
+  Instr instr = Memory::int32_at(target_pc);
+  // If we have a bx instruction, the instruction before the bx is
+  // what we need to patch.
+  static const int32_t kBxInstMask = 0x0ffffff0;
+  static const int32_t kBxInstPattern = 0x012fff10;
+  if ((instr & kBxInstMask) == kBxInstPattern) {
+    target_pc -= kInstrSize;
+    instr = Memory::int32_at(target_pc);
+  }
+  // Verify that the instruction to patch is a
+  // ldr<cond> <Rd>, [pc +/- offset_12].
   ASSERT((instr & 0x0f7f0000) == 0x051f0000);
   int offset = instr & 0xfff;  // offset_12 is unsigned
   if ((instr & (1 << 23)) == 0) offset = -offset;  // U bit defines offset sign
   // Verify that the constant pool comes after the instruction referencing it.
   ASSERT(offset >= -4);
-  return pc + offset + 8;
+  return target_pc + offset + 8;
 }
 
 
diff --git a/src/arm/assembler-thumb2.cc b/src/arm/assembler-thumb2.cc
index 6c2b903..e31c429 100644
--- a/src/arm/assembler-thumb2.cc
+++ b/src/arm/assembler-thumb2.cc
@@ -30,9 +30,9 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// The original source code covered by the above license above has been modified
-// significantly by Google Inc.
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2010 the V8 project authors. All rights reserved.
 
 #include "v8.h"
 
@@ -51,9 +51,14 @@
   // If the compiler is allowed to use vfp then we can use vfp too in our
   // code generation.
 #if !defined(__arm__)
-  // For the simulator=arm build, always use VFP since the arm simulator has
-  // VFP support.
-  supported_ |= 1u << VFP3;
+  // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled.
+  if (FLAG_enable_vfp3) {
+      supported_ |= 1u << VFP3;
+  }
+  // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
+  if (FLAG_enable_armv7) {
+      supported_ |= 1u << ARMv7;
+  }
 #else
   if (Serializer::enabled()) {
     supported_ |= OS::CpuFeaturesImpliedByPlatform();
@@ -66,6 +71,11 @@
     supported_ |= 1u << VFP3;
     found_by_runtime_probing_ |= 1u << VFP3;
   }
+
+  if (OS::ArmCpuHasFeature(ARMv7)) {
+    supported_ |= 1u << ARMv7;
+    found_by_runtime_probing_ |= 1u << ARMv7;
+  }
 #endif
 }
 
@@ -83,9 +93,9 @@
 Register r5  = {  5 };
 Register r6  = {  6 };
 Register r7  = {  7 };
-Register r8  = {  8 };
+Register r8  = {  8 };  // Used as context register.
 Register r9  = {  9 };
-Register r10 = { 10 };
+Register r10 = { 10 };  // Used as roots register.
 Register fp  = { 11 };
 Register ip  = { 12 };
 Register sp  = { 13 };
@@ -264,9 +274,9 @@
 
 
 // -----------------------------------------------------------------------------
-// Implementation of Assembler
+// Implementation of Assembler.
 
-// Instruction encoding bits
+// Instruction encoding bits.
 enum {
   H   = 1 << 5,   // halfword (or byte)
   S6  = 1 << 6,   // signed (or unsigned)
@@ -299,14 +309,14 @@
   B26 = 1 << 26,
   B27 = 1 << 27,
 
-  // Instruction bit masks
+  // Instruction bit masks.
   RdMask     = 15 << 12,  // in str instruction
   CondMask   = 15 << 28,
   CoprocessorMask = 15 << 8,
   OpCodeMask = 15 << 21,  // in data-processing instructions
   Imm24Mask  = (1 << 24) - 1,
   Off12Mask  = (1 << 12) - 1,
-  // Reserved condition
+  // Reserved condition.
   nv = 15 << 28
 };
 
@@ -327,13 +337,13 @@
 // ldr pc, [pc, #XXX]
 const Instr kLdrPCPattern = al | B26 | L | pc.code() * B16;
 
-// spare_buffer_
+// Spare buffer.
 static const int kMinimalBufferSize = 4*KB;
 static byte* spare_buffer_ = NULL;
 
 Assembler::Assembler(void* buffer, int buffer_size) {
   if (buffer == NULL) {
-    // do our own buffer management
+    // Do our own buffer management.
     if (buffer_size <= kMinimalBufferSize) {
       buffer_size = kMinimalBufferSize;
 
@@ -351,14 +361,14 @@
     own_buffer_ = true;
 
   } else {
-    // use externally provided buffer instead
+    // Use externally provided buffer instead.
     ASSERT(buffer_size > 0);
     buffer_ = static_cast<byte*>(buffer);
     buffer_size_ = buffer_size;
     own_buffer_ = false;
   }
 
-  // setup buffer pointers
+  // Setup buffer pointers.
   ASSERT(buffer_ != NULL);
   pc_ = buffer_;
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
@@ -386,11 +396,11 @@
 
 
 void Assembler::GetCode(CodeDesc* desc) {
-  // emit constant pool if necessary
+  // Emit constant pool if necessary.
   CheckConstPool(true, false);
   ASSERT(num_prinfo_ == 0);
 
-  // setup desc
+  // Setup code descriptor.
   desc->buffer = buffer_;
   desc->buffer_size = buffer_size_;
   desc->instr_size = pc_offset();
@@ -539,7 +549,7 @@
 void Assembler::link_to(Label* L, Label* appendix) {
   if (appendix->is_linked()) {
     if (L->is_linked()) {
-      // append appendix to L's list
+      // Append appendix to L's list.
       int fixup_pos;
       int link = L->pos();
       do {
@@ -549,7 +559,7 @@
       ASSERT(link == kEndOfChain);
       target_at_put(fixup_pos, appendix->pos());
     } else {
-      // L is empty, simply use appendix
+      // L is empty, simply use appendix.
       *L = *appendix;
     }
   }
@@ -575,12 +585,12 @@
 }
 
 
-// Low-level code emission routines depending on the addressing mode
+// Low-level code emission routines depending on the addressing mode.
 static bool fits_shifter(uint32_t imm32,
                          uint32_t* rotate_imm,
                          uint32_t* immed_8,
                          Instr* instr) {
-  // imm32 must be unsigned
+  // imm32 must be unsigned.
   for (int rot = 0; rot < 16; rot++) {
     uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));
     if ((imm8 <= 0xff)) {
@@ -589,7 +599,7 @@
       return true;
     }
   }
-  // if the opcode is mov or mvn and if ~imm32 fits, change the opcode
+  // If the opcode is mov or mvn and if ~imm32 fits, change the opcode.
   if (instr != NULL && (*instr & 0xd*B21) == 0xd*B21) {
     if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
       *instr ^= 0x2*B21;
@@ -626,7 +636,7 @@
   CheckBuffer();
   ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0);
   if (!x.rm_.is_valid()) {
-    // immediate
+    // Immediate.
     uint32_t rotate_imm;
     uint32_t immed_8;
     if (MustUseIp(x.rmode_) ||
@@ -634,7 +644,7 @@
       // The immediate operand cannot be encoded as a shifter operand, so load
       // it first to register ip and change the original instruction to use ip.
       // However, if the original instruction is a 'mov rd, x' (not setting the
-      // condition code), then replace it with a 'ldr rd, [pc]'
+      // condition code), then replace it with a 'ldr rd, [pc]'.
       RecordRelocInfo(x.rmode_, x.imm32_);
       CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
       Condition cond = static_cast<Condition>(instr & CondMask);
@@ -648,16 +658,16 @@
     }
     instr |= I | rotate_imm*B8 | immed_8;
   } else if (!x.rs_.is_valid()) {
-    // immediate shift
+    // Immediate shift.
     instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   } else {
-    // register shift
+    // Register shift.
     ASSERT(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
     instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
   }
   emit(instr | rn.code()*B16 | rd.code()*B12);
   if (rn.is(pc) || x.rm_.is(pc))
-    // block constant pool emission for one instruction after reading pc
+    // Block constant pool emission for one instruction after reading pc.
     BlockConstPoolBefore(pc_offset() + kInstrSize);
 }
 
@@ -666,15 +676,15 @@
   ASSERT((instr & ~(CondMask | B | L)) == B26);
   int am = x.am_;
   if (!x.rm_.is_valid()) {
-    // immediate offset
+    // Immediate offset.
     int offset_12 = x.offset_;
     if (offset_12 < 0) {
       offset_12 = -offset_12;
       am ^= U;
     }
     if (!is_uint12(offset_12)) {
-      // immediate offset cannot be encoded, load it first to register ip
-      // rn (and rd in a load) should never be ip, or will be trashed
+      // Immediate offset cannot be encoded, load it first to register ip
+      // rn (and rd in a load) should never be ip, or will be trashed.
       ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC,
           static_cast<Condition>(instr & CondMask));
@@ -684,9 +694,9 @@
     ASSERT(offset_12 >= 0);  // no masking needed
     instr |= offset_12;
   } else {
-    // register offset (shift_imm_ and shift_op_ are 0) or scaled
+    // Register offset (shift_imm_ and shift_op_ are 0) or scaled
     // register offset the constructors make sure than both shift_imm_
-    // and shift_op_ are initialized
+    // and shift_op_ are initialized.
     ASSERT(!x.rm_.is(pc));
     instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   }
@@ -700,15 +710,15 @@
   ASSERT(x.rn_.is_valid());
   int am = x.am_;
   if (!x.rm_.is_valid()) {
-    // immediate offset
+    // Immediate offset.
     int offset_8 = x.offset_;
     if (offset_8 < 0) {
       offset_8 = -offset_8;
       am ^= U;
     }
     if (!is_uint8(offset_8)) {
-      // immediate offset cannot be encoded, load it first to register ip
-      // rn (and rd in a load) should never be ip, or will be trashed
+      // Immediate offset cannot be encoded, load it first to register ip
+      // rn (and rd in a load) should never be ip, or will be trashed.
       ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC,
           static_cast<Condition>(instr & CondMask));
@@ -718,15 +728,15 @@
     ASSERT(offset_8 >= 0);  // no masking needed
     instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
   } else if (x.shift_imm_ != 0) {
-    // scaled register offset not supported, load index first
-    // rn (and rd in a load) should never be ip, or will be trashed
+    // Scaled register offset not supported, load index first
+    // rn (and rd in a load) should never be ip, or will be trashed.
     ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
     mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
         static_cast<Condition>(instr & CondMask));
     addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
     return;
   } else {
-    // register offset
+    // Register offset.
     ASSERT((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
     instr |= x.rm_.code();
   }
@@ -744,7 +754,7 @@
 
 
 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
-  // unindexed addressing is not encoded by this function
+  // Unindexed addressing is not encoded by this function.
   ASSERT_EQ((B27 | B26),
             (instr & ~(CondMask | CoprocessorMask | P | U | N | W | L)));
   ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
@@ -759,7 +769,7 @@
   ASSERT(is_uint8(offset_8));  // unsigned word offset must fit in a byte
   ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
 
-  // post-indexed addressing requires W == 1; different than in addrmod2/3
+  // Post-indexed addressing requires W == 1; different than in addrmod2/3.
   if ((am & P) == 0)
     am |= W;
 
@@ -782,7 +792,7 @@
   }
 
   // Block the emission of the constant pool, since the branch instruction must
-  // be emitted at the pc offset recorded by the label
+  // be emitted at the pc offset recorded by the label.
   BlockConstPoolBefore(pc_offset() + kInstrSize);
   return target_pos - (pc_offset() + kPcLoadDelta);
 }
@@ -804,7 +814,7 @@
 }
 
 
-// Branch instructions
+// Branch instructions.
 void Assembler::b(int branch_offset, Condition cond) {
   ASSERT((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
@@ -812,7 +822,7 @@
   emit(cond | B27 | B25 | (imm24 & Imm24Mask));
 
   if (cond == al)
-    // dead code is a good location to emit the constant pool
+    // Dead code is a good location to emit the constant pool.
     CheckConstPool(false, false);
 }
 
@@ -849,7 +859,22 @@
 }
 
 
-// Data-processing instructions
+// Data-processing instructions.
+
+// UBFX <Rd>,<Rn>,#<lsb>,#<width - 1>
+// Instruction details available in ARM DDI 0406A, A8-464.
+// cond(31-28) | 01111(27-23)| 1(22) | 1(21) | widthm1(20-16) |
+//  Rd(15-12) | lsb(11-7) | 101(6-4) | Rn(3-0)
+void Assembler::ubfx(Register dst, Register src1, const Operand& src2,
+                     const Operand& src3, Condition cond) {
+  ASSERT(!src2.rm_.is_valid() && !src3.rm_.is_valid());
+  ASSERT(static_cast<uint32_t>(src2.imm32_) <= 0x1f);
+  ASSERT(static_cast<uint32_t>(src3.imm32_) <= 0x1f);
+  emit(cond | 0x3F*B21 | src3.imm32_*B16 |
+       dst.code()*B12 | src2.imm32_*B7 | 0x5*B4 | src1.code());
+}
+
+
 void Assembler::and_(Register dst, Register src1, const Operand& src2,
                      SBit s, Condition cond) {
   addrmod1(cond | 0*B21 | s, src1, dst, src2);
@@ -886,7 +911,7 @@
   if (FLAG_push_pop_elimination &&
       last_bound_pos_ <= (pc_offset() - pattern_size) &&
       reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
-      // pattern
+      // Pattern.
       instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
       (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) {
     pc_ -= 2 * kInstrSize;
@@ -960,7 +985,7 @@
 }
 
 
-// Multiply instructions
+// Multiply instructions.
 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
                     SBit s, Condition cond) {
   ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
@@ -1029,7 +1054,7 @@
 }
 
 
-// Miscellaneous arithmetic instructions
+// Miscellaneous arithmetic instructions.
 void Assembler::clz(Register dst, Register src, Condition cond) {
   // v5 and above.
   ASSERT(!dst.is(pc) && !src.is(pc));
@@ -1038,7 +1063,7 @@
 }
 
 
-// Status register access instructions
+// Status register access instructions.
 void Assembler::mrs(Register dst, SRegister s, Condition cond) {
   ASSERT(!dst.is(pc));
   emit(cond | B24 | s | 15*B16 | dst.code()*B12);
@@ -1050,12 +1075,12 @@
   ASSERT(fields >= B16 && fields < B20);  // at least one field set
   Instr instr;
   if (!src.rm_.is_valid()) {
-    // immediate
+    // Immediate.
     uint32_t rotate_imm;
     uint32_t immed_8;
     if (MustUseIp(src.rmode_) ||
         !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
-      // immediate operand cannot be encoded, load it first to register ip
+      // Immediate operand cannot be encoded, load it first to register ip.
       RecordRelocInfo(src.rmode_, src.imm32_);
       ldr(ip, MemOperand(pc, 0), cond);
       msr(fields, Operand(ip), cond);
@@ -1070,7 +1095,7 @@
 }
 
 
-// Load/Store instructions
+// Load/Store instructions.
 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
   if (dst.is(pc)) {
     WriteRecordedPositions();
@@ -1085,7 +1110,7 @@
   if (FLAG_push_pop_elimination &&
       last_bound_pos_ <= (pc_offset() - pattern_size) &&
       reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
-      // pattern
+      // Pattern.
       instr_at(pc_ - 1 * kInstrSize) == (kPopRegPattern | dst.code() * B12) &&
       instr_at(pc_ - 2 * kInstrSize) == (kPushRegPattern | dst.code() * B12)) {
     pc_ -= 2 * kInstrSize;
@@ -1106,6 +1131,7 @@
   if (FLAG_push_pop_elimination &&
      last_bound_pos_ <= (pc_offset() - pattern_size) &&
      reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
+     // Pattern.
      instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) &&
      instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) {
     pc_ -= 2 * kInstrSize;
@@ -1147,17 +1173,17 @@
 }
 
 
-// Load/Store multiple instructions
+// Load/Store multiple instructions.
 void Assembler::ldm(BlockAddrMode am,
                     Register base,
                     RegList dst,
                     Condition cond) {
-  // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable
+  // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
   ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
 
   addrmod4(cond | B27 | am | L, base, dst);
 
-  // emit the constant pool after a function return implemented by ldm ..{..pc}
+  // Emit the constant pool after a function return implemented by ldm ..{..pc}.
   if (cond == al && (dst & pc.bit()) != 0) {
     // There is a slight chance that the ldm instruction was actually a call,
     // in which case it would be wrong to return into the constant pool; we
@@ -1177,7 +1203,7 @@
 }
 
 
-// Semaphore instructions
+// Semaphore instructions.
 void Assembler::swp(Register dst, Register src, Register base, Condition cond) {
   ASSERT(!dst.is(pc) && !src.is(pc) && !base.is(pc));
   ASSERT(!dst.is(base) && !src.is(base));
@@ -1197,7 +1223,7 @@
 }
 
 
-// Exception-generating instructions and debugging support
+// Exception-generating instructions and debugging support.
 void Assembler::stop(const char* msg) {
 #if !defined(__arm__)
   // The simulator handles these special instructions and stops execution.
@@ -1222,7 +1248,7 @@
 }
 
 
-// Coprocessor instructions
+// Coprocessor instructions.
 void Assembler::cdp(Coprocessor coproc,
                     int opcode_1,
                     CRegister crd,
@@ -1307,7 +1333,7 @@
                     int option,
                     LFlag l,
                     Condition cond) {
-  // unindexed addressing
+  // Unindexed addressing.
   ASSERT(is_uint8(option));
   emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
        coproc*B8 | (option & 255));
@@ -1346,7 +1372,7 @@
                     int option,
                     LFlag l,
                     Condition cond) {
-  // unindexed addressing
+  // Unindexed addressing.
   ASSERT(is_uint8(option));
   emit(cond | B27 | B26 | U | l | rn.code()*B16 | crd.code()*B12 |
        coproc*B8 | (option & 255));
@@ -1371,6 +1397,36 @@
 
 
 // Support for VFP.
+void Assembler::vldr(const DwVfpRegister dst,
+                     const Register base,
+                     int offset,
+                     const Condition cond) {
+  // Ddst = MEM(Rbase + offset).
+  // Instruction details available in ARM DDI 0406A, A8-628.
+  // cond(31-28) | 1101(27-24)| 1001(23-20) | Rbase(19-16) |
+  // Vdst(15-12) | 1011(11-8) | offset
+  ASSERT(CpuFeatures::IsEnabled(VFP3));
+  ASSERT(offset % 4 == 0);
+  emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 |
+       0xB*B8 | ((offset / 4) & 255));
+}
+
+
+void Assembler::vstr(const DwVfpRegister src,
+                     const Register base,
+                     int offset,
+                     const Condition cond) {
+  // MEM(Rbase + offset) = Dsrc.
+  // Instruction details available in ARM DDI 0406A, A8-786.
+  // cond(31-28) | 1101(27-24)| 1000(23-20) | | Rbase(19-16) |
+  // Vsrc(15-12) | 1011(11-8) | (offset/4)
+  ASSERT(CpuFeatures::IsEnabled(VFP3));
+  ASSERT(offset % 4 == 0);
+  emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 |
+       0xB*B8 | ((offset / 4) & 255));
+}
+
+
 void Assembler::vmov(const DwVfpRegister dst,
                      const Register src1,
                      const Register src2,
@@ -1434,7 +1490,7 @@
                      const Condition cond) {
   // Dd = Sm (integer in Sm converted to IEEE 64-bit doubles in Dd).
   // Instruction details available in ARM DDI 0406A, A8-576.
-  // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) |opc2=000(18-16) |
+  // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) | opc2=000(18-16) |
   // Vd(15-12) | 101(11-9) | sz(8)=1 | op(7)=1 | 1(6) | M=?(5) | 0(4) | Vm(3-0)
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   emit(cond | 0xE*B24 | B23 | 0x3*B20 | B19 |
@@ -1541,14 +1597,14 @@
 }
 
 
-// Pseudo instructions
+// Pseudo instructions.
 void Assembler::lea(Register dst,
                     const MemOperand& x,
                     SBit s,
                     Condition cond) {
   int am = x.am_;
   if (!x.rm_.is_valid()) {
-    // immediate offset
+    // Immediate offset.
     if ((am & P) == 0)  // post indexing
       mov(dst, Operand(x.rn_), s, cond);
     else if ((am & U) == 0)  // negative indexing
@@ -1582,7 +1638,7 @@
 }
 
 
-// Debugging
+// Debugging.
 void Assembler::RecordJSReturn() {
   WriteRecordedPositions();
   CheckBuffer();
@@ -1635,7 +1691,7 @@
 void Assembler::GrowBuffer() {
   if (!own_buffer_) FATAL("external code buffer is too small");
 
-  // compute new buffer size
+  // Compute new buffer size.
   CodeDesc desc;  // the new buffer
   if (buffer_size_ < 4*KB) {
     desc.buffer_size = 4*KB;
@@ -1646,20 +1702,20 @@
   }
   CHECK_GT(desc.buffer_size, 0);  // no overflow
 
-  // setup new buffer
+  // Setup new buffer.
   desc.buffer = NewArray<byte>(desc.buffer_size);
 
   desc.instr_size = pc_offset();
   desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
 
-  // copy the data
+  // Copy the data.
   int pc_delta = desc.buffer - buffer_;
   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
   memmove(desc.buffer, buffer_, desc.instr_size);
   memmove(reloc_info_writer.pos() + rc_delta,
           reloc_info_writer.pos(), desc.reloc_size);
 
-  // switch buffers
+  // Switch buffers.
   DeleteArray(buffer_);
   buffer_ = desc.buffer;
   buffer_size_ = desc.buffer_size;
@@ -1667,11 +1723,11 @@
   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
                                reloc_info_writer.last_pc() + pc_delta);
 
-  // none of our relocation types are pc relative pointing outside the code
+  // None of our relocation types are pc relative pointing outside the code
   // buffer nor pc absolute pointing inside the code buffer, so there is no need
-  // to relocate any emitted relocation entries
+  // to relocate any emitted relocation entries.
 
-  // relocate pending relocation entries
+  // Relocate pending relocation entries.
   for (int i = 0; i < num_prinfo_; i++) {
     RelocInfo& rinfo = prinfo_[i];
     ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
@@ -1686,16 +1742,16 @@
 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
   RelocInfo rinfo(pc_, rmode, data);  // we do not try to reuse pool constants
   if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::STATEMENT_POSITION) {
-    // Adjust code for new modes
+    // Adjust code for new modes.
     ASSERT(RelocInfo::IsJSReturn(rmode)
            || RelocInfo::IsComment(rmode)
            || RelocInfo::IsPosition(rmode));
-    // these modes do not need an entry in the constant pool
+    // These modes do not need an entry in the constant pool.
   } else {
     ASSERT(num_prinfo_ < kMaxNumPRInfo);
     prinfo_[num_prinfo_++] = rinfo;
     // Make sure the constant pool is not emitted in place of the next
-    // instruction for which we just recorded relocation info
+    // instruction for which we just recorded relocation info.
     BlockConstPoolBefore(pc_offset() + kInstrSize);
   }
   if (rinfo.rmode() != RelocInfo::NONE) {
@@ -1722,7 +1778,7 @@
   // blocked for a specific range.
   next_buffer_check_ = pc_offset() + kCheckConstInterval;
 
-  // There is nothing to do if there are no pending relocation info entries
+  // There is nothing to do if there are no pending relocation info entries.
   if (num_prinfo_ == 0) return;
 
   // We emit a constant pool at regular intervals of about kDistBetweenPools
@@ -1748,10 +1804,11 @@
   // no_const_pool_before_, which is checked here. Also, recursive calls to
   // CheckConstPool are blocked by no_const_pool_before_.
   if (pc_offset() < no_const_pool_before_) {
-    // Emission is currently blocked; make sure we try again as soon as possible
+    // Emission is currently blocked; make sure we try again as soon as
+    // possible.
     next_buffer_check_ = no_const_pool_before_;
 
-    // Something is wrong if emission is forced and blocked at the same time
+    // Something is wrong if emission is forced and blocked at the same time.
     ASSERT(!force_emit);
     return;
   }
@@ -1765,23 +1822,23 @@
       jump_instr + kInstrSize + num_prinfo_*(kInstrSize + kMaxRelocSize);
   while (buffer_space() <= (max_needed_space + kGap)) GrowBuffer();
 
-  // Block recursive calls to CheckConstPool
+  // Block recursive calls to CheckConstPool.
   BlockConstPoolBefore(pc_offset() + jump_instr + kInstrSize +
                        num_prinfo_*kInstrSize);
   // Don't bother to check for the emit calls below.
   next_buffer_check_ = no_const_pool_before_;
 
-  // Emit jump over constant pool if necessary
+  // Emit jump over constant pool if necessary.
   Label after_pool;
   if (require_jump) b(&after_pool);
 
   RecordComment("[ Constant Pool");
 
-  // Put down constant pool marker
-  // "Undefined instruction" as specified by A3.1 Instruction set encoding
+  // Put down constant pool marker "Undefined instruction" as specified by
+  // A3.1 Instruction set encoding.
   emit(0x03000000 | num_prinfo_);
 
-  // Emit constant pool entries
+  // Emit constant pool entries.
   for (int i = 0; i < num_prinfo_; i++) {
     RelocInfo& rinfo = prinfo_[i];
     ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
@@ -1789,8 +1846,8 @@
            rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
     Instr instr = instr_at(rinfo.pc());
 
-    // Instruction to patch must be a ldr/str [pc, #offset]
-    // P and U set, B and W clear, Rn == pc, offset12 still 0
+    // Instruction to patch must be a ldr/str [pc, #offset].
+    // P and U set, B and W clear, Rn == pc, offset12 still 0.
     ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) ==
            (2*B25 | P | U | pc.code()*B16));
     int delta = pc_ - rinfo.pc() - 8;
diff --git a/src/arm/assembler-thumb2.h b/src/arm/assembler-thumb2.h
index 9998e63..869ac46 100644
--- a/src/arm/assembler-thumb2.h
+++ b/src/arm/assembler-thumb2.h
@@ -30,9 +30,9 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// The original source code covered by the above license above has been modified
-// significantly by Google Inc.
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2010 the V8 project authors. All rights reserved.
 
 // A light-weight ARM Assembler
 // Generates user mode instructions for the ARM architecture up to version 5
@@ -250,7 +250,7 @@
 };
 
 
-// Condition field in instructions
+// Condition field in instructions.
 enum Condition {
   eq =  0 << 28,  // Z set            equal.
   ne =  1 << 28,  // Z clear          not equal.
@@ -398,8 +398,6 @@
          RelocInfo::Mode rmode = RelocInfo::NONE));
   INLINE(explicit Operand(const ExternalReference& f));
   INLINE(explicit Operand(const char* s));
-  INLINE(explicit Operand(Object** opp));
-  INLINE(explicit Operand(Context** cpp));
   explicit Operand(Handle<Object> handle);
   INLINE(explicit Operand(Smi* value));
 
@@ -630,6 +628,9 @@
   void blx(Label* L)  { blx(branch_offset(L, false)); }  // v5 and above
 
   // Data-processing instructions
+  void ubfx(Register dst, Register src1, const Operand& src2,
+            const Operand& src3, Condition cond = al);
+
   void and_(Register dst, Register src1, const Operand& src2,
             SBit s = LeaveCC, Condition cond = al);
 
@@ -796,6 +797,14 @@
   // However, some simple modifications can allow
   // these APIs to support D16 to D31.
 
+  void vldr(const DwVfpRegister dst,
+            const Register base,
+            int offset,  // Offset must be a multiple of 4.
+            const Condition cond = al);
+  void vstr(const DwVfpRegister src,
+            const Register base,
+            int offset,  // Offset must be a multiple of 4.
+            const Condition cond = al);
   void vmov(const DwVfpRegister dst,
             const Register src1,
             const Register src2,
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index ae7dae3..edb1b0a 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -499,7 +499,10 @@
   // r0: number of arguments
   // r1: called object
   __ bind(&non_function_call);
-
+  // CALL_NON_FUNCTION expects the non-function constructor as receiver
+  // (instead of the original receiver from the call site).  The receiver is
+  // stack element argc.
+  __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
   // Set expected number of arguments to zero (not changing r0).
   __ mov(r2, Operand(0));
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
@@ -904,7 +907,7 @@
 
 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
   // 1. Make sure we have at least one argument.
-  // r0: actual number of argument
+  // r0: actual number of arguments
   { Label done;
     __ tst(r0, Operand(r0));
     __ b(ne, &done);
@@ -914,40 +917,31 @@
     __ bind(&done);
   }
 
-  // 2. Get the function to call from the stack.
-  // r0: actual number of argument
-  { Label done, non_function, function;
-    __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, &non_function);
-    __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
-    __ b(eq, &function);
+  // 2. Get the function to call (passed as receiver) from the stack, check
+  //    if it is a function.
+  // r0: actual number of arguments
+  Label non_function;
+  __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
+  __ tst(r1, Operand(kSmiTagMask));
+  __ b(eq, &non_function);
+  __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
+  __ b(ne, &non_function);
 
-    // Non-function called: Clear the function to force exception.
-    __ bind(&non_function);
-    __ mov(r1, Operand(0));
-    __ b(&done);
-
-    // Change the context eagerly because it will be used below to get the
-    // right global object.
-    __ bind(&function);
-    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-
-    __ bind(&done);
-  }
-
-  // 3. Make sure first argument is an object; convert if necessary.
+  // 3a. Patch the first argument if necessary when calling a function.
   // r0: actual number of arguments
   // r1: function
-  { Label call_to_object, use_global_receiver, patch_receiver, done;
+  Label shift_arguments;
+  { Label convert_to_object, use_global_receiver, patch_receiver;
+    // Change context eagerly in case we need the global receiver.
+    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
+
     __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
     __ ldr(r2, MemOperand(r2, -kPointerSize));
-
     // r0: actual number of arguments
     // r1: function
     // r2: first argument
     __ tst(r2, Operand(kSmiTagMask));
-    __ b(eq, &call_to_object);
+    __ b(eq, &convert_to_object);
 
     __ LoadRoot(r3, Heap::kNullValueRootIndex);
     __ cmp(r2, r3);
@@ -957,31 +951,28 @@
     __ b(eq, &use_global_receiver);
 
     __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE);
-    __ b(lt, &call_to_object);
+    __ b(lt, &convert_to_object);
     __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE));
-    __ b(le, &done);
+    __ b(le, &shift_arguments);
 
-    __ bind(&call_to_object);
-    __ EnterInternalFrame();
-
-    // Store number of arguments and function across the call into the runtime.
-    __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+    __ bind(&convert_to_object);
+    __ EnterInternalFrame();  // In order to preserve argument count.
+    __ mov(r0, Operand(r0, LSL, kSmiTagSize));  // Smi-tagged.
     __ push(r0);
-    __ push(r1);
 
     __ push(r2);
     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
     __ mov(r2, r0);
 
-    // Restore number of arguments and function.
-    __ pop(r1);
     __ pop(r0);
     __ mov(r0, Operand(r0, ASR, kSmiTagSize));
-
     __ LeaveInternalFrame();
-    __ b(&patch_receiver);
+    // Restore the function to r1.
+    __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
+    __ jmp(&patch_receiver);
 
-    // Use the global receiver object from the called function as the receiver.
+    // Use the global receiver object from the called function as the
+    // receiver.
     __ bind(&use_global_receiver);
     const int kGlobalIndex =
         Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
@@ -994,16 +985,30 @@
     __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2));
     __ str(r2, MemOperand(r3, -kPointerSize));
 
-    __ bind(&done);
+    __ jmp(&shift_arguments);
   }
 
-  // 4. Shift stuff one slot down the stack
-  // r0: actual number of arguments (including call() receiver)
+  // 3b. Patch the first argument when calling a non-function.  The
+  //     CALL_NON_FUNCTION builtin expects the non-function callee as
+  //     receiver, so overwrite the first argument which will ultimately
+  //     become the receiver.
+  // r0: actual number of arguments
   // r1: function
+  __ bind(&non_function);
+  __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
+  __ str(r1, MemOperand(r2, -kPointerSize));
+  // Clear r1 to indicate a non-function being called.
+  __ mov(r1, Operand(0));
+
+  // 4. Shift arguments and return address one slot down on the stack
+  //    (overwriting the original receiver).  Adjust argument count to make
+  //    the original first argument the new receiver.
+  // r0: actual number of arguments
+  // r1: function
+  __ bind(&shift_arguments);
   { Label loop;
     // Calculate the copy start address (destination). Copy end address is sp.
     __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
-    __ add(r2, r2, Operand(kPointerSize));  // copy receiver too
 
     __ bind(&loop);
     __ ldr(ip, MemOperand(r2, -kPointerSize));
@@ -1011,43 +1016,41 @@
     __ sub(r2, r2, Operand(kPointerSize));
     __ cmp(r2, sp);
     __ b(ne, &loop);
+    // Adjust the actual number of arguments and remove the top element
+    // (which is a copy of the last argument).
+    __ sub(r0, r0, Operand(1));
+    __ pop();
   }
 
-  // 5. Adjust the actual number of arguments and remove the top element.
-  // r0: actual number of arguments (including call() receiver)
-  // r1: function
-  __ sub(r0, r0, Operand(1));
-  __ add(sp, sp, Operand(kPointerSize));
-
-  // 6. Get the code for the function or the non-function builtin.
-  //    If number of expected arguments matches, then call. Otherwise restart
-  //    the arguments adaptor stub.
+  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
   // r0: actual number of arguments
   // r1: function
-  { Label invoke;
+  { Label function;
     __ tst(r1, r1);
-    __ b(ne, &invoke);
+    __ b(ne, &function);
     __ mov(r2, Operand(0));  // expected arguments is 0 for CALL_NON_FUNCTION
     __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
     __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
                          RelocInfo::CODE_TARGET);
-
-    __ bind(&invoke);
-    __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-    __ ldr(r2,
-           FieldMemOperand(r3,
-                           SharedFunctionInfo::kFormalParameterCountOffset));
-    __ ldr(r3,
-           MemOperand(r3, SharedFunctionInfo::kCodeOffset - kHeapObjectTag));
-    __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
-    __ cmp(r2, r0);  // Check formal and actual parameter counts.
-    __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
-                         RelocInfo::CODE_TARGET, ne);
-
-    // 7. Jump to the code in r3 without checking arguments.
-    ParameterCount expected(0);
-    __ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
+    __ bind(&function);
   }
+
+  // 5b. Get the code to call from the function and check that the number of
+  //     expected arguments matches what we're providing.  If so, jump
+  //     (tail-call) to the code in register edx without checking arguments.
+  // r0: actual number of arguments
+  // r1: function
+  __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+  __ ldr(r2,
+         FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
+  __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
+  __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ cmp(r2, r0);  // Check formal and actual parameter counts.
+  __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
+          RelocInfo::CODE_TARGET, ne);
+
+  ParameterCount expected(0);
+  __ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
 }
 
 
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 9afefac..e47d392 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -142,7 +142,7 @@
 // r1: called JS function
 // cp: callee's context
 
-void CodeGenerator::Generate(CompilationInfo* info, Mode mode) {
+void CodeGenerator::Generate(CompilationInfo* info) {
   // Record the position for debugging purposes.
   CodeForFunctionPosition(info->function());
 
@@ -174,7 +174,7 @@
     }
 #endif
 
-    if (mode == PRIMARY) {
+    if (info->mode() == CompilationInfo::PRIMARY) {
       frame_->Enter();
       // tos: code slot
 
@@ -277,6 +277,12 @@
       frame_->Adjust(4);
       allocator_->Unuse(r1);
       allocator_->Unuse(lr);
+
+      // Bind all the bailout labels to the beginning of the function.
+      List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
+      for (int i = 0; i < bailouts->length(); i++) {
+        __ bind(bailouts->at(i)->label());
+      }
     }
 
     // Initialize the function return target after the locals are set
@@ -2293,8 +2299,7 @@
   Comment cmnt(masm_, "[ DebuggerStatament");
   CodeForStatementPosition(node);
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  DebuggerStatementStub ces;
-  frame_->CallStub(&ces, 0);
+  frame_->DebugBreak();
 #endif
   // Ignore the return value.
   ASSERT(frame_->height() == original_height);
@@ -2719,9 +2724,9 @@
     frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
   }
   frame_->EmitPush(r0);  // save the result
-  // r0: created object literal
-
   for (int i = 0; i < node->properties()->length(); i++) {
+    // At the start of each iteration, the top of stack contains
+    // the newly created object literal.
     ObjectLiteral::Property* property = node->properties()->at(i);
     Literal* key = property->key();
     Expression* value = property->value();
@@ -2731,34 +2736,43 @@
       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
         if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
         // else fall through
-      case ObjectLiteral::Property::COMPUTED:  // fall through
+      case ObjectLiteral::Property::COMPUTED:
+        if (key->handle()->IsSymbol()) {
+          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+          LoadAndSpill(value);
+          frame_->EmitPop(r0);
+          __ mov(r2, Operand(key->handle()));
+          __ ldr(r1, frame_->Top());  // Load the receiver.
+          frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
+          break;
+        }
+        // else fall through
       case ObjectLiteral::Property::PROTOTYPE: {
+        __ ldr(r0, frame_->Top());
         frame_->EmitPush(r0);  // dup the result
         LoadAndSpill(key);
         LoadAndSpill(value);
         frame_->CallRuntime(Runtime::kSetProperty, 3);
-        // restore r0
-        __ ldr(r0, frame_->Top());
         break;
       }
       case ObjectLiteral::Property::SETTER: {
+        __ ldr(r0, frame_->Top());
         frame_->EmitPush(r0);
         LoadAndSpill(key);
         __ mov(r0, Operand(Smi::FromInt(1)));
         frame_->EmitPush(r0);
         LoadAndSpill(value);
         frame_->CallRuntime(Runtime::kDefineAccessor, 4);
-        __ ldr(r0, frame_->Top());
         break;
       }
       case ObjectLiteral::Property::GETTER: {
+        __ ldr(r0, frame_->Top());
         frame_->EmitPush(r0);
         LoadAndSpill(key);
         __ mov(r0, Operand(Smi::FromInt(0)));
         frame_->EmitPush(r0);
         LoadAndSpill(value);
         frame_->CallRuntime(Runtime::kDefineAccessor, 4);
-        __ ldr(r0, frame_->Top());
         break;
       }
     }
@@ -2776,17 +2790,19 @@
 
   // Load the function of this activation.
   __ ldr(r2, frame_->Function());
-  // Literals array.
+  // Load the literals array of the function.
   __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
-  // Literal index.
   __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
-  // Constant elements.
   __ mov(r0, Operand(node->constant_elements()));
   frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
+  int length = node->values()->length();
   if (node->depth() > 1) {
     frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
-  } else {
+  } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
     frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
+  } else {
+    FastCloneShallowArrayStub stub(length);
+    frame_->CallStub(&stub, 3);
   }
   frame_->EmitPush(r0);  // save the result
   // r0: created object literal
@@ -3013,11 +3029,6 @@
     // ----------------------------------
     // JavaScript example: 'foo(1, 2, 3)'  // foo is global
     // ----------------------------------
-
-    // Push the name of the function and the receiver onto the stack.
-    __ mov(r0, Operand(var->name()));
-    frame_->EmitPush(r0);
-
     // Pass the global object as the receiver and let the IC stub
     // patch the stack to use the global proxy as 'this' in the
     // invoked function.
@@ -3029,15 +3040,14 @@
       LoadAndSpill(args->at(i));
     }
 
-    // Setup the receiver register and call the IC initialization code.
+    // Setup the name register and call the IC initialization code.
+    __ mov(r2, Operand(var->name()));
     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
     Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
     CodeForSourcePosition(node->position());
     frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
                            arg_count + 1);
     __ ldr(cp, frame_->Context());
-    // Remove the function from the stack.
-    frame_->Drop();
     frame_->EmitPush(r0);
 
   } else if (var != NULL && var->slot() != NULL &&
@@ -3070,28 +3080,21 @@
       // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
       // ------------------------------------------------------------------
 
-      // Push the name of the function and the receiver onto the stack.
-      __ mov(r0, Operand(literal->handle()));
-      frame_->EmitPush(r0);
-      LoadAndSpill(property->obj());
-
+      LoadAndSpill(property->obj());  // Receiver.
       // Load the arguments.
       int arg_count = args->length();
       for (int i = 0; i < arg_count; i++) {
         LoadAndSpill(args->at(i));
       }
 
-      // Set the receiver register and call the IC initialization code.
+      // Set the name register and call the IC initialization code.
+      __ mov(r2, Operand(literal->handle()));
       InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
       Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
       CodeForSourcePosition(node->position());
       frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
       __ ldr(cp, frame_->Context());
-
-      // Remove the function from the stack.
-      frame_->Drop();
-
-      frame_->EmitPush(r0);  // push after get rid of function from the stack
+      frame_->EmitPush(r0);
 
     } else {
       // -------------------------------------------
@@ -3423,6 +3426,25 @@
 }
 
 
+void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
+  VirtualFrame::SpilledScope spilled_scope;
+  ASSERT(args->length() == 1);
+  LoadAndSpill(args->at(0));
+  JumpTarget answer;
+  // We need the CC bits to come out as not_equal in the case where the
+  // object is a smi.  This can't be done with the usual test opcode so
+  // we use XOR to get the right CC bits.
+  frame_->EmitPop(r0);
+  __ and_(r1, r0, Operand(kSmiTagMask));
+  __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
+  answer.Branch(ne);
+  // It is a heap object - get the map. Check if the object is a regexp.
+  __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
+  answer.Bind();
+  cc_reg_ = eq;
+}
+
+
 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
   // This generates a fast version of:
   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
@@ -3595,6 +3617,35 @@
 }
 
 
+void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+
+  frame_->CallRuntime(Runtime::kNumberToString, 1);
+  frame_->EmitPush(r0);
+}
+
+
+void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+  frame_->CallRuntime(Runtime::kMath_sin, 1);
+  frame_->EmitPush(r0);
+}
+
+
+void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+  frame_->CallRuntime(Runtime::kMath_cos, 1);
+  frame_->EmitPush(r0);
+}
+
+
 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
   VirtualFrame::SpilledScope spilled_scope;
   ASSERT(args->length() == 2);
@@ -3626,8 +3677,6 @@
 
   if (function == NULL) {
     // Prepare stack for calling JS runtime function.
-    __ mov(r0, Operand(node->name()));
-    frame_->EmitPush(r0);
     // Push the builtins object found in the current global object.
     __ ldr(r1, GlobalObject());
     __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
@@ -3642,11 +3691,11 @@
 
   if (function == NULL) {
     // Call the JS runtime function.
+    __ mov(r2, Operand(node->name()));
     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
     Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
     frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
     __ ldr(cp, frame_->Context());
-    frame_->Drop();
     frame_->EmitPush(r0);
   } else {
     // Call the C runtime function.
@@ -4389,11 +4438,11 @@
       Handle<String> name(GetName());
 
       frame->EmitPop(r0);
-      // Setup the name register.
+      frame->EmitPop(r1);
       __ mov(r2, Operand(name));
       frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
       frame->EmitPush(r0);
-      cgen_->UnloadReference(this);
+      set_unloaded();
       break;
     }
 
@@ -4405,7 +4454,6 @@
 
       // Call IC code.
       Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
-      // TODO(1222589): Make the IC grab the values from the stack.
       frame->EmitPop(r0);  // value
       frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
       frame->EmitPush(r0);
@@ -4480,7 +4528,7 @@
                         TAG_OBJECT);
 
   // Load the function from the stack.
-  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
+  __ ldr(r3, MemOperand(sp, 0));
 
   // Setup the object header.
   __ LoadRoot(r2, Heap::kContextMapRootIndex);
@@ -4516,6 +4564,69 @@
 }
 
 
+void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
+  // Stack layout on entry:
+  //
+  // [sp]: constant elements.
+  // [sp + kPointerSize]: literal index.
+  // [sp + (2 * kPointerSize)]: literals array.
+
+  // All sizes here are multiples of kPointerSize.
+  int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
+  int size = JSArray::kSize + elements_size;
+
+  // Load boilerplate object into r3 and check if we need to create a
+  // boilerplate.
+  Label slow_case;
+  __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
+  __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
+  __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ ldr(r3, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r3, ip);
+  __ b(eq, &slow_case);
+
+  // Allocate both the JS array and the elements array in one big
+  // allocation. This avoids multiple limit checks.
+  __ AllocateInNewSpace(size / kPointerSize,
+                        r0,
+                        r1,
+                        r2,
+                        &slow_case,
+                        TAG_OBJECT);
+
+  // Copy the JS array part.
+  for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
+    if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
+      __ ldr(r1, FieldMemOperand(r3, i));
+      __ str(r1, FieldMemOperand(r0, i));
+    }
+  }
+
+  if (length_ > 0) {
+    // Get hold of the elements array of the boilerplate and setup the
+    // elements pointer in the resulting object.
+    __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
+    __ add(r2, r0, Operand(JSArray::kSize));
+    __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset));
+
+    // Copy the elements array.
+    for (int i = 0; i < elements_size; i += kPointerSize) {
+      __ ldr(r1, FieldMemOperand(r3, i));
+      __ str(r1, FieldMemOperand(r2, i));
+    }
+  }
+
+  // Return and remove the on-stack parameters.
+  __ add(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
+  __ bind(&slow_case);
+  ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
+  __ TailCallRuntime(runtime, 3, 1);
+}
+
+
 // Count leading zeros in a 32 bit word.  On ARM5 and later it uses the clz
 // instruction.  On pre-ARM5 hardware this routine gives the wrong answer for 0
 // (31 instead of 32).
@@ -6584,7 +6695,7 @@
   __ b(gt, &slow);
 
   // Get the prototype of the function (r4 is result, r2 is scratch).
-  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
+  __ ldr(r1, MemOperand(sp, 0));
   __ TryGetFunctionPrototype(r1, r4, r2, &slow);
 
   // Check that the function prototype is a JS object.
@@ -6699,20 +6810,102 @@
 
 
 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+  // sp[0] : number of parameters
+  // sp[4] : receiver displacement
+  // sp[8] : function
+
   // Check if the calling frame is an arguments adaptor frame.
-  Label runtime;
+  Label adaptor_frame, try_allocate, runtime;
   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
   __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
-  __ b(ne, &runtime);
+  __ b(eq, &adaptor_frame);
+
+  // Get the length from the frame.
+  __ ldr(r1, MemOperand(sp, 0));
+  __ b(&try_allocate);
 
   // Patch the arguments.length and the parameters pointer.
-  __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
-  __ str(r0, MemOperand(sp, 0 * kPointerSize));
-  __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+  __ bind(&adaptor_frame);
+  __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ str(r1, MemOperand(sp, 0));
+  __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
   __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
   __ str(r3, MemOperand(sp, 1 * kPointerSize));
 
+  // Try the new space allocation. Start out with computing the size
+  // of the arguments object and the elements array (in words, not
+  // bytes because AllocateInNewSpace expects words).
+  Label add_arguments_object;
+  __ bind(&try_allocate);
+  __ cmp(r1, Operand(0));
+  __ b(eq, &add_arguments_object);
+  __ mov(r1, Operand(r1, LSR, kSmiTagSize));
+  __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
+  __ bind(&add_arguments_object);
+  __ add(r1, r1, Operand(Heap::kArgumentsObjectSize / kPointerSize));
+
+  // Do the allocation of both objects in one go.
+  __ AllocateInNewSpace(r1, r0, r2, r3, &runtime, TAG_OBJECT);
+
+  // Get the arguments boilerplate from the current (global) context.
+  int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+  __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
+  __ ldr(r4, MemOperand(r4, offset));
+
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ ldr(r3, FieldMemOperand(r4, i));
+    __ str(r3, FieldMemOperand(r0, i));
+  }
+
+  // Setup the callee in-object property.
+  ASSERT(Heap::arguments_callee_index == 0);
+  __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
+  __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize));
+
+  // Get the length (smi tagged) and set that as an in-object property too.
+  ASSERT(Heap::arguments_length_index == 1);
+  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
+  __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize));
+
+  // If there are no actual arguments, we're done.
+  Label done;
+  __ cmp(r1, Operand(0));
+  __ b(eq, &done);
+
+  // Get the parameters pointer from the stack and untag the length.
+  __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
+  __ mov(r1, Operand(r1, LSR, kSmiTagSize));
+
+  // Setup the elements pointer in the allocated arguments object and
+  // initialize the header in the elements fixed array.
+  __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
+  __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
+  __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
+  __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
+  __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
+
+  // Copy the fixed array slots.
+  Label loop;
+  // Setup r4 to point to the first array slot.
+  __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ bind(&loop);
+  // Pre-decrement r2 with kPointerSize on each iteration.
+  // Pre-decrement in order to skip receiver.
+  __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
+  // Post-increment r4 with kPointerSize on each iteration.
+  __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
+  __ sub(r1, r1, Operand(1));
+  __ cmp(r1, Operand(0));
+  __ b(ne, &loop);
+
+  // Return and remove the on-stack parameters.
+  __ bind(&done);
+  __ add(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
   __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
@@ -6766,6 +6959,9 @@
 
   // Slow-case: Non-function called.
   __ bind(&slow);
+  // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+  // of the original receiver from the call site).
+  __ str(r1, MemOperand(sp, argc_ * kPointerSize));
   __ mov(r0, Operand(argc_));  // Setup the number of arguments.
   __ mov(r2, Operand(0));
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 2578a39..22dd854 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -150,15 +150,6 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Compilation mode.  Either the compiler is used as the primary
-  // compiler and needs to setup everything or the compiler is used as
-  // the secondary compiler for split compilation and has to handle
-  // bailouts.
-  enum Mode {
-    PRIMARY,
-    SECONDARY
-  };
-
   // Takes a function literal, generates code for it. This function should only
   // be called by compiler.cc.
   static Handle<Code> MakeCode(CompilationInfo* info);
@@ -244,7 +235,7 @@
   inline void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
 
   // Main code generation function
-  void Generate(CompilationInfo* info, Mode mode);
+  void Generate(CompilationInfo* info);
 
   // The following are used by class Reference.
   void LoadReference(Reference* ref);
@@ -359,6 +350,7 @@
   void GenerateIsSmi(ZoneList<Expression*>* args);
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
+  void GenerateIsRegExp(ZoneList<Expression*>* args);
   void GenerateIsObject(ZoneList<Expression*>* args);
   void GenerateIsFunction(ZoneList<Expression*>* args);
   void GenerateIsUndetectableObject(ZoneList<Expression*>* args);
@@ -398,6 +390,13 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
+  // Fast support for number to string.
+  void GenerateNumberToString(ZoneList<Expression*>* args);
+
+  // Fast call to sine function.
+  void GenerateMathSin(ZoneList<Expression*>* args);
+  void GenerateMathCos(ZoneList<Expression*>* args);
+
   // Simple condition analysis.
   enum ConditionAnalysis {
     ALWAYS_TRUE,
diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc
index 4e39cda..55f31d4 100644
--- a/src/arm/cpu-arm.cc
+++ b/src/arm/cpu-arm.cc
@@ -122,7 +122,7 @@
 
 
 void CPU::DebugBreak() {
-#if !defined (__arm__)
+#if !defined (__arm__) || !defined(CAN_USE_ARMV5_INSTRUCTIONS)
   UNIMPLEMENTED();  // when building ARM emulator target
 #else
   asm volatile("bkpt 0");
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
index 6eb5239..e6b61b4 100644
--- a/src/arm/debug-arm.cc
+++ b/src/arm/debug-arm.cc
@@ -128,7 +128,7 @@
   //  -- lr    : return address
   //  -- [sp]  : receiver
   // -----------------------------------
-  // Registers r0 and r2 contain objects that needs to be pushed on the
+  // Registers r0 and r2 contain objects that need to be pushed on the
   // expression stack of the fake JS frame.
   Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit());
 }
@@ -137,14 +137,14 @@
 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
   // Calling convention for IC store (from ic-arm.cc).
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
+  //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
-  // Registers r0 and r2 contain objects that needs to be pushed on the
+  // Registers r0, r1, and r2 contain objects that need to be pushed on the
   // expression stack of the fake JS frame.
-  Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit());
+  Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit());
 }
 
 
diff --git a/src/arm/fast-codegen-arm.cc b/src/arm/fast-codegen-arm.cc
index 80da533..aa7128f 100644
--- a/src/arm/fast-codegen-arm.cc
+++ b/src/arm/fast-codegen-arm.cc
@@ -35,51 +35,36 @@
 
 #define __ ACCESS_MASM(masm())
 
-void FastCodeGenerator::EmitLoadReceiver(Register reg) {
+Register FastCodeGenerator::accumulator0() { return r0; }
+Register FastCodeGenerator::accumulator1() { return r1; }
+Register FastCodeGenerator::scratch0() { return r3; }
+Register FastCodeGenerator::scratch1() { return r4; }
+Register FastCodeGenerator::receiver_reg() { return r2; }
+Register FastCodeGenerator::context_reg() { return cp; }
+
+
+void FastCodeGenerator::EmitLoadReceiver() {
   // Offset 2 is due to return address and saved frame pointer.
   int index = 2 + scope()->num_parameters();
-  __ ldr(reg, MemOperand(sp, index * kPointerSize));
-}
-
-
-void FastCodeGenerator::EmitReceiverMapCheck() {
-  Comment cmnt(masm(), ";; MapCheck(this)");
-  if (FLAG_print_ir) {
-    PrintF("MapCheck(this)\n");
-  }
-
-  ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
-  Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
-  Handle<Map> map(object->map());
-
-  EmitLoadReceiver(r1);
-  __ CheckMap(r1, r3, map, bailout(), false);
-}
-
-
-void FastCodeGenerator::EmitGlobalMapCheck() {
-  Comment cmnt(masm(), ";; GlobalMapCheck");
-  if (FLAG_print_ir) {
-    PrintF(";; GlobalMapCheck()");
-  }
-
-  ASSERT(info()->has_global_object());
-  Handle<Map> map(info()->global_object()->map());
-
-  __ ldr(r3, CodeGenerator::GlobalObject());
-  __ CheckMap(r3, r3, map, bailout(), true);
+  __ ldr(receiver_reg(), MemOperand(sp, index * kPointerSize));
 }
 
 
 void FastCodeGenerator::EmitGlobalVariableLoad(Handle<Object> cell) {
+  ASSERT(!destination().is(no_reg));
   ASSERT(cell->IsJSGlobalPropertyCell());
-  __ mov(r0, Operand(cell));
-  __ ldr(r0, FieldMemOperand(r0, JSGlobalPropertyCell::kValueOffset));
+
+  __ mov(destination(), Operand(cell));
+  __ ldr(destination(),
+         FieldMemOperand(destination(), JSGlobalPropertyCell::kValueOffset));
   if (FLAG_debug_code) {
     __ mov(ip, Operand(Factory::the_hole_value()));
-    __ cmp(r0, ip);
+    __ cmp(destination(), ip);
     __ Check(ne, "DontDelete cells can't contain the hole");
   }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
 }
 
 
@@ -93,18 +78,101 @@
   int index = lookup.GetFieldIndex() - map->inobject_properties();
   int offset = index * kPointerSize;
 
+  // We will emit the write barrier unless the stored value is statically
+  // known to be a smi.
+  bool needs_write_barrier = !is_smi(accumulator0());
+
   // Negative offsets are inobject properties.
   if (offset < 0) {
     offset += map->instance_size();
-    __ mov(r2, r1);  // Copy receiver for write barrier.
+    __ str(accumulator0(), FieldMemOperand(receiver_reg(), offset));
+    if (needs_write_barrier) {
+      // Preserve receiver from write barrier.
+      __ mov(scratch0(), receiver_reg());
+    }
   } else {
     offset += FixedArray::kHeaderSize;
-    __ ldr(r2, FieldMemOperand(r1, JSObject::kPropertiesOffset));
+    __ ldr(scratch0(),
+           FieldMemOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ str(accumulator0(), FieldMemOperand(scratch0(), offset));
   }
-  // Perform the store.
-  __ str(r0, FieldMemOperand(r2, offset));
-  __ mov(r3, Operand(offset));
-  __ RecordWrite(r2, r3, ip);
+
+  if (needs_write_barrier) {
+    __ mov(scratch1(), Operand(offset));
+    __ RecordWrite(scratch0(), scratch1(), ip);
+  }
+
+  if (destination().is(accumulator1())) {
+    __ mov(accumulator1(), accumulator0());
+    if (is_smi(accumulator0())) {
+      set_as_smi(accumulator1());
+    } else {
+      clear_as_smi(accumulator1());
+    }
+  }
+}
+
+
+void FastCodeGenerator::EmitThisPropertyLoad(Handle<String> name) {
+  ASSERT(!destination().is(no_reg));
+  LookupResult lookup;
+  info()->receiver()->Lookup(*name, &lookup);
+
+  ASSERT(lookup.holder() == *info()->receiver());
+  ASSERT(lookup.type() == FIELD);
+  Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map());
+  int index = lookup.GetFieldIndex() - map->inobject_properties();
+  int offset = index * kPointerSize;
+
+  // Perform the load.  Negative offsets are inobject properties.
+  if (offset < 0) {
+    offset += map->instance_size();
+    __ ldr(destination(), FieldMemOperand(receiver_reg(), offset));
+  } else {
+    offset += FixedArray::kHeaderSize;
+    __ ldr(scratch0(),
+           FieldMemOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ ldr(destination(), FieldMemOperand(scratch0(), offset));
+  }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
+}
+
+
+void FastCodeGenerator::EmitBitOr() {
+  if (is_smi(accumulator0()) && is_smi(accumulator1())) {
+    // If both operands are known to be a smi then there is no need to check
+    // the operands or result.  There is no need to perform the operation in
+    // an effect context.
+    if (!destination().is(no_reg)) {
+      __ orr(destination(), accumulator1(), Operand(accumulator0()));
+    }
+  } else {
+    // Left is in accumulator1, right in accumulator0.
+    if (destination().is(accumulator0())) {
+      __ mov(scratch0(), accumulator0());
+      __ orr(destination(), accumulator1(), Operand(accumulator1()));
+      Label* bailout =
+          info()->AddBailout(accumulator1(), scratch0());  // Left, right.
+      __ BranchOnNotSmi(destination(), bailout);
+    } else if (destination().is(accumulator1())) {
+      __ mov(scratch0(), accumulator1());
+      __ orr(destination(), accumulator1(), Operand(accumulator0()));
+      Label* bailout = info()->AddBailout(scratch0(), accumulator0());
+      __ BranchOnNotSmi(destination(), bailout);
+    } else {
+      ASSERT(destination().is(no_reg));
+      __ orr(scratch0(), accumulator1(), Operand(accumulator0()));
+      Label* bailout = info()->AddBailout(accumulator1(), accumulator0());
+      __ BranchOnNotSmi(scratch0(), bailout);
+    }
+  }
+
+  // If we didn't bailout, the result (in fact, both inputs too) is known to
+  // be a smi.
+  set_as_smi(accumulator0());
+  set_as_smi(accumulator1());
 }
 
 
@@ -119,26 +187,45 @@
   // Note that we keep a live register reference to cp (context) at
   // this point.
 
-  // Receiver (this) is allocated to r1 if there are this properties.
-  if (info()->has_this_properties()) EmitReceiverMapCheck();
+  Label* bailout_to_beginning = info()->AddBailout();
+  // Receiver (this) is allocated to a fixed register.
+  if (info()->has_this_properties()) {
+    Comment cmnt(masm(), ";; MapCheck(this)");
+    if (FLAG_print_ir) {
+      PrintF("MapCheck(this)\n");
+    }
+    ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
+    Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
+    Handle<Map> map(object->map());
+    EmitLoadReceiver();
+    __ CheckMap(receiver_reg(), scratch0(), map, bailout_to_beginning, false);
+  }
 
-  // If there is a global variable access check if the global object
-  // is the same as at lazy-compilation time.
-  if (info()->has_globals()) EmitGlobalMapCheck();
+  // If there is a global variable access check if the global object is the
+  // same as at lazy-compilation time.
+  if (info()->has_globals()) {
+    Comment cmnt(masm(), ";; MapCheck(GLOBAL)");
+    if (FLAG_print_ir) {
+      PrintF("MapCheck(GLOBAL)\n");
+    }
+    ASSERT(info()->has_global_object());
+    Handle<Map> map(info()->global_object()->map());
+    __ ldr(scratch0(), CodeGenerator::GlobalObject());
+    __ CheckMap(scratch0(), scratch1(), map, bailout_to_beginning, true);
+  }
 
   VisitStatements(function()->body());
 
   Comment return_cmnt(masm(), ";; Return(<undefined>)");
+  if (FLAG_print_ir) {
+    PrintF("Return(<undefined>)\n");
+  }
   __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
-
-  Comment epilogue_cmnt(masm(), ";; Epilogue");
   __ mov(sp, fp);
   __ ldm(ia_w, sp, fp.bit() | lr.bit());
   int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
   __ add(sp, sp, Operand(sp_delta));
   __ Jump(lr);
-
-  __ bind(&bailout_);
 }
 
 
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 7e048ff..4896373 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -816,9 +816,9 @@
         if (key->handle()->IsSymbol()) {
           VisitForValue(value, kAccumulator);
           __ mov(r2, Operand(key->handle()));
+          __ ldr(r1, MemOperand(sp));
           Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
           __ Call(ic, RelocInfo::CODE_TARGET);
-          // StoreIC leaves the receiver on the stack.
           break;
         }
         // Fall through.
@@ -907,6 +907,92 @@
 }
 
 
+void FullCodeGenerator::VisitAssignment(Assignment* expr) {
+  Comment cmnt(masm_, "[ Assignment");
+  ASSERT(expr->op() != Token::INIT_CONST);
+  // Left-hand side can only be a property, a global or a (parameter or local)
+  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
+  LhsKind assign_type = VARIABLE;
+  Property* prop = expr->target()->AsProperty();
+  if (prop != NULL) {
+    assign_type =
+        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
+  }
+
+  // Evaluate LHS expression.
+  switch (assign_type) {
+    case VARIABLE:
+      // Nothing to do here.
+      break;
+    case NAMED_PROPERTY:
+      if (expr->is_compound()) {
+        // We need the receiver both on the stack and in the accumulator.
+        VisitForValue(prop->obj(), kAccumulator);
+        __ push(result_register());
+      } else {
+        VisitForValue(prop->obj(), kStack);
+      }
+      break;
+    case KEYED_PROPERTY:
+      VisitForValue(prop->obj(), kStack);
+      VisitForValue(prop->key(), kStack);
+      break;
+  }
+
+  // If we have a compound assignment: Get value of LHS expression and
+  // store in on top of the stack.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kStack;
+    switch (assign_type) {
+      case VARIABLE:
+        EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
+                         Expression::kValue);
+        break;
+      case NAMED_PROPERTY:
+        EmitNamedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+      case KEYED_PROPERTY:
+        EmitKeyedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+    }
+    location_ = saved_location;
+  }
+
+  // Evaluate RHS expression.
+  Expression* rhs = expr->value();
+  VisitForValue(rhs, kAccumulator);
+
+  // If we have a compound assignment: Apply operator.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kAccumulator;
+    EmitBinaryOp(expr->binary_op(), Expression::kValue);
+    location_ = saved_location;
+  }
+
+  // Record source position before possible IC call.
+  SetSourcePosition(expr->position());
+
+  // Store the value.
+  switch (assign_type) {
+    case VARIABLE:
+      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
+                             context_);
+      break;
+    case NAMED_PROPERTY:
+      EmitNamedPropertyAssignment(expr);
+      break;
+    case KEYED_PROPERTY:
+      EmitKeyedPropertyAssignment(expr);
+      break;
+  }
+}
+
+
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
@@ -945,21 +1031,17 @@
     ASSERT(!var->is_this());
     // Assignment to a global variable.  Use inline caching for the
     // assignment.  Right-hand-side value is passed in r0, variable name in
-    // r2, and the global object on the stack.
+    // r2, and the global object in r1.
     __ mov(r2, Operand(var->name()));
-    __ ldr(ip, CodeGenerator::GlobalObject());
-    __ push(ip);
+    __ ldr(r1, CodeGenerator::GlobalObject());
     Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
     __ Call(ic, RelocInfo::CODE_TARGET);
-    // Overwrite the global object on the stack with the result if needed.
-    DropAndApply(1, context, r0);
 
   } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
     __ push(result_register());  // Value.
     __ mov(r1, Operand(var->name()));
     __ stm(db_w, sp, cp.bit() | r1.bit());  // Context and name.
     __ CallRuntime(Runtime::kStoreContextSlot, 3);
-    Apply(context, r0);
 
   } else if (var->slot() != NULL) {
     Slot* slot = var->slot();
@@ -986,13 +1068,13 @@
         UNREACHABLE();
         break;
     }
-    Apply(context, result_register());
 
   } else {
     // Variables rewritten as properties are not treated as variables in
     // assignments.
     UNREACHABLE();
   }
+  Apply(context, result_register());
 }
 
 
@@ -1016,6 +1098,12 @@
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
   __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
+  if (expr->ends_initialization_block()) {
+    __ ldr(r1, MemOperand(sp));
+  } else {
+    __ pop(r1);
+  }
+
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   __ Call(ic, RelocInfo::CODE_TARGET);
 
@@ -1026,9 +1114,10 @@
     __ push(ip);
     __ CallRuntime(Runtime::kToFastProperties, 1);
     __ pop(r0);
+    DropAndApply(1, context_, r0);
+  } else {
+    Apply(context_, r0);
   }
-
-  DropAndApply(1, context_, r0);
 }
 
 
@@ -1087,7 +1176,7 @@
 }
 
 void FullCodeGenerator::EmitCallWithIC(Call* expr,
-                                       Handle<Object> ignored,
+                                       Handle<Object> name,
                                        RelocInfo::Mode mode) {
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
@@ -1095,16 +1184,16 @@
   for (int i = 0; i < arg_count; i++) {
     VisitForValue(args->at(i), kStack);
   }
+  __ mov(r2, Operand(name));
   // Record source position for debugger.
   SetSourcePosition(expr->position());
   // Call the IC initialization code.
-  Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
-                                                         NOT_IN_LOOP);
+  InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
+  Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
   __ Call(ic, mode);
   // Restore context register.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  // Discard the function left on TOS.
-  DropAndApply(1, context_, r0);
+  Apply(context_, r0);
 }
 
 
@@ -1121,7 +1210,6 @@
   __ CallStub(&stub);
   // Restore context register.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  // Discard the function left on TOS.
   DropAndApply(1, context_, r0);
 }
 
@@ -1135,11 +1223,9 @@
     // Call to the identifier 'eval'.
     UNREACHABLE();
   } else if (var != NULL && !var->is_this() && var->is_global()) {
-    // Call to a global variable.
-    __ mov(r1, Operand(var->name()));
-    // Push global object as receiver for the call IC lookup.
+    // Push global object as receiver for the call IC.
     __ ldr(r0, CodeGenerator::GlobalObject());
-    __ stm(db_w, sp, r1.bit() | r0.bit());
+    __ push(r0);
     EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
   } else if (var != NULL && var->slot() != NULL &&
              var->slot()->type() == Slot::LOOKUP) {
@@ -1151,8 +1237,6 @@
     Literal* key = prop->key()->AsLiteral();
     if (key != NULL && key->handle()->IsSymbol()) {
       // Call to a named property, use call IC.
-      __ mov(r0, Operand(key->handle()));
-      __ push(r0);
       VisitForValue(prop->obj(), kStack);
       EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
     } else {
@@ -1238,10 +1322,9 @@
 
   if (expr->is_jsruntime()) {
     // Prepare for calling JS runtime function.
-    __ mov(r1, Operand(expr->name()));
     __ ldr(r0, CodeGenerator::GlobalObject());
     __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
-    __ stm(db_w, sp, r1.bit() | r0.bit());
+    __ push(r0);
   }
 
   // Push the arguments ("left-to-right").
@@ -1252,18 +1335,17 @@
 
   if (expr->is_jsruntime()) {
     // Call the JS runtime function.
+    __ mov(r2, Operand(expr->name()));
     Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
                                                            NOT_IN_LOOP);
     __ Call(ic, RelocInfo::CODE_TARGET);
     // Restore context register.
     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-    // Discard the function left on TOS.
-    DropAndApply(1, context_, r0);
   } else {
     // Call the C runtime function.
     __ CallRuntime(expr->function(), arg_count);
-    Apply(context_, r0);
   }
+  Apply(context_, r0);
 }
 
 
@@ -1548,15 +1630,15 @@
       break;
     case NAMED_PROPERTY: {
       __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
+      __ pop(r1);
       Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
       __ Call(ic, RelocInfo::CODE_TARGET);
       if (expr->is_postfix()) {
-        __ Drop(1);  // Result is on the stack under the receiver.
         if (context_ != Expression::kEffect) {
           ApplyTOS(context_);
         }
       } else {
-        DropAndApply(1, context_, r0);
+        Apply(context_, r0);
       }
       break;
     }
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 19583a9..2a1fef9 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -59,7 +59,7 @@
   // r3 - used as temporary and to hold the capacity of the property
   //      dictionary.
   //
-  // r2 - holds the name of the property and is unchanges.
+  // r2 - holds the name of the property and is unchanged.
 
   Label done;
 
@@ -171,7 +171,7 @@
 
   __ ldr(r0, MemOperand(sp, 0));
 
-  StubCompiler::GenerateLoadStringLength2(masm, r0, r1, r3, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, r0, r1, r3, &miss);
   // Cache miss: Jump to runtime.
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
@@ -200,14 +200,13 @@
 
 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
   Label number, non_number, non_string, boolean, probe, miss;
 
   // Get the receiver of the function from the stack into r1.
   __ ldr(r1, MemOperand(sp, argc * kPointerSize));
-  // Get the name of the function from the stack; 1 ~ receiver.
-  __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
 
   // Probe the stub cache.
   Code::Flags flags =
@@ -276,9 +275,9 @@
 
   // Patch the receiver with the global proxy if necessary.
   if (is_global_object) {
-    __ ldr(r2, MemOperand(sp, argc * kPointerSize));
-    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
-    __ str(r2, MemOperand(sp, argc * kPointerSize));
+    __ ldr(r0, MemOperand(sp, argc * kPointerSize));
+    __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
+    __ str(r0, MemOperand(sp, argc * kPointerSize));
   }
 
   // Invoke the function.
@@ -289,14 +288,13 @@
 
 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
   Label miss, global_object, non_global_object;
 
   // Get the receiver of the function from the stack into r1.
   __ ldr(r1, MemOperand(sp, argc * kPointerSize));
-  // Get the name of the function from the stack; 1 ~ receiver.
-  __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
 
   // Check that the receiver isn't a smi.
   __ tst(r1, Operand(kSmiTagMask));
@@ -349,18 +347,17 @@
 
 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
 
   // Get the receiver of the function from the stack.
-  __ ldr(r2, MemOperand(sp, argc * kPointerSize));
-  // Get the name of the function to call from the stack.
-  __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
+  __ ldr(r3, MemOperand(sp, argc * kPointerSize));
 
   __ EnterInternalFrame();
 
   // Push the receiver and the name of the function.
-  __ stm(db_w, sp, r1.bit() | r2.bit());
+  __ stm(db_w, sp, r2.bit() | r3.bit());
 
   // Call the entry.
   __ mov(r0, Operand(2));
@@ -413,7 +410,7 @@
   StubCache::GenerateProbe(masm, flags, r0, r2, r3, no_reg);
 
   // Cache miss: Jump to runtime.
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
+  GenerateMiss(masm);
 }
 
 
@@ -456,16 +453,11 @@
 
   // Cache miss: Restore receiver from stack and jump to runtime.
   __ bind(&miss);
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
+  GenerateMiss(masm);
 }
 
 
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
-}
-
-
-void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   // ----------- S t a t e -------------
   //  -- r2    : name
   //  -- lr    : return address
@@ -476,7 +468,7 @@
   __ stm(db_w, sp, r2.bit() | r3.bit());
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
 }
 
 
@@ -504,11 +496,6 @@
 
 
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
-}
-
-
-void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- sp[0]  : key
@@ -518,7 +505,21 @@
   __ ldm(ia, sp, r2.bit() | r3.bit());
   __ stm(db_w, sp, r2.bit() | r3.bit());
 
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- sp[0]  : key
+  //  -- sp[4]  : receiver
+  // -----------------------------------
+
+  __ ldm(ia, sp, r2.bit() | r3.bit());
+  __ stm(db_w, sp, r2.bit() | r3.bit());
+
+  __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
 }
 
 
@@ -532,17 +533,11 @@
 
   // 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 isn't a smi.
+  __ BranchOnSmi(r1, &slow);
   // Get the map of the receiver.
   __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
-
   // Check bit field.
   __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
   __ tst(r3, Operand(kSlowCaseBitFieldMask));
@@ -556,6 +551,10 @@
   __ cmp(r2, Operand(JS_OBJECT_TYPE));
   __ b(lt, &slow);
 
+  // Check that the key is a smi.
+  __ BranchOnNotSmi(r0, &slow);
+  __ mov(r0, Operand(r0, ASR, kSmiTagSize));
+
   // Get the elements array of the object.
   __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
   // Check that the object is in fast mode (not dictionary).
@@ -571,10 +570,7 @@
   // Slow case: Push extra copies of the arguments (2).
   __ bind(&slow);
   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1);
-  __ 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, 1);
+  GenerateRuntimeGetProperty(masm);
 
   // Fast case: Do the load.
   __ bind(&fast);
@@ -608,8 +604,47 @@
 }
 
 
-void KeyedStoreIC::Generate(MacroAssembler* masm,
-                            const ExternalReference& f) {
+void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- sp[0]  : key
+  //  -- sp[4]  : receiver
+  // -----------------------------------
+  Label slow;
+
+  // Get the key and receiver object from the stack.
+  __ ldm(ia, sp, r0.bit() | r1.bit());
+
+  // Check that the receiver isn't a smi.
+  __ BranchOnSmi(r1, &slow);
+
+  // Check that the key is a smi.
+  __ BranchOnNotSmi(r0, &slow);
+
+  // Get the map of the receiver.
+  __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
+
+  // Check that it has indexed interceptor and access checks
+  // are not enabled for this object.
+  __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
+  __ and_(r3, r3, Operand(kSlowCaseBitFieldMask));
+  __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor));
+  __ b(ne, &slow);
+
+  // Everything is fine, call runtime.
+  __ push(r1);  // receiver
+  __ push(r0);  // key
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(ExternalReference(
+        IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
+
+  __ bind(&slow);
+  GenerateMiss(masm);
+}
+
+
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- lr     : return address
@@ -620,7 +655,21 @@
   __ ldm(ia, sp, r2.bit() | r3.bit());
   __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
 
-  __ TailCallRuntime(f, 3, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
+}
+
+
+void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- r0     : value
+  //  -- lr     : return address
+  //  -- sp[0]  : key
+  //  -- sp[1]  : receiver
+  // -----------------------------------
+  __ ldm(ia, sp, r1.bit() | r3.bit());  // r0 == value, r1 == key, r3 == object
+  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
+
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 }
 
 
@@ -675,12 +724,9 @@
   __ b(lo, &fast);
 
 
-  // Slow case: Push extra copies of the arguments (3).
+  // Slow case:
   __ 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, 1);
+  GenerateRuntimeSetProperty(masm);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -751,33 +797,15 @@
 }
 
 
-void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
-  // ---------- S t a t e --------------
-  //  -- r0     : value
-  //  -- lr     : return address
-  //  -- sp[0]  : key
-  //  -- sp[1]  : receiver
-  // ----------- S t a t e -------------
-
-  __ ldm(ia, sp, r2.bit() | r3.bit());
-  __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
-
-  // Perform tail call to the entry.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
-}
-
-
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
 
   // Get the receiver from the stack and probe the stub cache.
-  __ ldr(r1, MemOperand(sp));
   Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
                                          NOT_IN_LOOP,
                                          MONOMORPHIC);
@@ -788,33 +816,16 @@
 }
 
 
-void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r2    : name
-  //  -- lr    : return address
-  //  -- [sp]  : receiver
-  // -----------------------------------
-
-  __ ldr(r3, MemOperand(sp));  // copy receiver
-  __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
-
-  // Perform tail call to the entry.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
-}
-
-
 void StoreIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
 
-  __ ldr(r3, MemOperand(sp));  // copy receiver
-  __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
+  __ push(r1);
+  __ stm(db_w, sp, r2.bit() | r0.bit());
 
   // Perform tail call to the entry.
   __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 1f08c7c..b9335f8 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -37,7 +37,6 @@
 
 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -221,7 +220,7 @@
   // remembered set bits in the new space.
   // object: heap object pointer (with tag)
   // offset: offset to store location from the object
-  and_(scratch, object, Operand(Heap::NewSpaceMask()));
+  and_(scratch, object, Operand(ExternalReference::new_space_mask()));
   cmp(scratch, Operand(ExternalReference::new_space_start()));
   b(eq, &done);
 
@@ -331,14 +330,10 @@
 
   // Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
   stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
-  mov(fp, Operand(sp));  // setup new frame pointer
+  mov(fp, Operand(sp));  // Setup new frame pointer.
 
-  if (mode == ExitFrame::MODE_DEBUG) {
-    mov(ip, Operand(Smi::FromInt(0)));
-  } else {
-    mov(ip, Operand(CodeObject()));
-  }
-  push(ip);
+  mov(ip, Operand(CodeObject()));
+  push(ip);  // Accessed from ExitFrame::code_slot.
 
   // Save the frame pointer and the context in top.
   mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
@@ -550,6 +545,21 @@
 }
 
 
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+
+  // Get the function and setup the context.
+  mov(r1, Operand(Handle<JSFunction>(function)));
+  ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
+
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::SaveRegistersToMemory(RegList regs) {
   ASSERT((regs & ~kJSCallerSaved) == 0);
@@ -608,6 +618,15 @@
     }
   }
 }
+
+
+void MacroAssembler::DebugBreak() {
+  ASSERT(allow_stub_calls());
+  mov(r0, Operand(0));
+  mov(r1, Operand(ExternalReference(Runtime::kDebugBreak)));
+  CEntryStub ces(1);
+  Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
 #endif
 
 
@@ -1205,6 +1224,16 @@
 }
 
 
+void MacroAssembler::CallExternalReference(const ExternalReference& ext,
+                                           int num_arguments) {
+  mov(r0, Operand(num_arguments));
+  mov(r1, Operand(ext));
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
                                      int num_arguments,
                                      int result_size) {
@@ -1228,58 +1257,28 @@
 }
 
 
-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Contract with compiled functions is that the function is passed in r1.
-  int builtins_offset =
-      JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
-  ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
-  ldr(r1, FieldMemOperand(r1, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
-}
-
-
 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
                                    InvokeJSFlags flags) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
+  GetBuiltinEntry(r2, id);
   if (flags == CALL_JS) {
-    Call(code, RelocInfo::CODE_TARGET);
+    Call(r2);
   } else {
     ASSERT(flags == JUMP_JS);
-    Jump(code, RelocInfo::CODE_TARGET);
-  }
-
-  if (!resolved) {
-    const char* name = Builtins::GetName(id);
-    int argc = Builtins::GetArgumentsCount(id);
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry = { pc_offset() - kInstrSize, flags, name };
-    unresolved_.Add(entry);
+    Jump(r2);
   }
 }
 
 
 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  mov(target, Operand(code));
-  if (!resolved) {
-    const char* name = Builtins::GetName(id);
-    int argc = Builtins::GetArgumentsCount(id);
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - kInstrSize, flags, name };
-    unresolved_.Add(entry);
-  }
-
+  // Load the JavaScript builtin function from the builtins object.
+  ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
+  int builtins_offset =
+      JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
+  ldr(r1, FieldMemOperand(r1, builtins_offset));
+  // Load the code entry point from the function into the target register.
+  ldr(target, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+  ldr(target, FieldMemOperand(target, SharedFunctionInfo::kCodeOffset));
   add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
 }
 
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 66ef4f9..98cea16 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -135,6 +135,10 @@
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // ---------------------------------------------------------------------------
@@ -146,6 +150,7 @@
   void CopyRegistersFromStackToMemory(Register base,
                                       Register scratch,
                                       RegList regs);
+  void DebugBreak();
 #endif
 
   // ---------------------------------------------------------------------------
@@ -334,6 +339,10 @@
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId fid, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(const ExternalReference& ext,
+                             int num_arguments);
+
   // Tail call of a runtime routine (jump).
   // Like JumpToRuntime, but also takes care of passing the number
   // of parameters.
@@ -352,13 +361,6 @@
   // setup the function in r1.
   void GetBuiltinEntry(Register target, Builtins::JavaScript id);
 
-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }
 
 
@@ -431,23 +433,10 @@
                       Label* done,
                       InvokeFlag flag);
 
-  // Prepares for a call or jump to a builtin by doing two things:
-  // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
-  //    compile time, so that later code can emit instructions to jump or call
-  //    the builtin directly.  If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
-  //    output parameter "resolved" to false.  Code that uses the return value
-  //    should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);
 
-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index d19a683..da73942 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -189,8 +189,9 @@
 }
 
 
-// Generate code to check if an object is a string.  If the object is
-// a string, the map's instance type is left in the scratch1 register.
+// Generate code to check if an object is a string.  If the object is a
+// heap object, its map's instance type is left in the scratch1 register.
+// If this is not needed, scratch1 and scratch2 may be the same register.
 static void GenerateStringCheck(MacroAssembler* masm,
                                 Register receiver,
                                 Register scratch1,
@@ -215,18 +216,16 @@
 // If the receiver object is not a string or a wrapped string object the
 // execution continues at the miss label. The register containing the
 // receiver is potentially clobbered.
-void StubCompiler::GenerateLoadStringLength2(MacroAssembler* masm,
-                                             Register receiver,
-                                             Register scratch1,
-                                             Register scratch2,
-                                             Label* miss) {
-  Label check_string, check_wrapper;
+void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
+                                            Register receiver,
+                                            Register scratch1,
+                                            Register scratch2,
+                                            Label* miss) {
+  Label check_wrapper;
 
-  __ bind(&check_string);
   // Check if the object is a string leaving the instance type in the
   // scratch1 register.
-  GenerateStringCheck(masm, receiver, scratch1, scratch2,
-                      miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
 
   // Load length directly from the string.
   __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset));
@@ -238,9 +237,12 @@
   __ cmp(scratch1, Operand(JS_VALUE_TYPE));
   __ b(ne, miss);
 
-  // Unwrap the value in place and check if the wrapped value is a string.
-  __ ldr(receiver, FieldMemOperand(receiver, JSValue::kValueOffset));
-  __ b(&check_string);
+  // Unwrap the value and check if the wrapped value is a string.
+  __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
+  GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
+  __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
+  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+  __ Ret();
 }
 
 
@@ -256,10 +258,10 @@
 
 
 // Generate StoreField code, value is passed in r0 register.
-// After executing generated code, the receiver_reg and name_reg
-// may be clobbered.
+// When leaving generated code after success, the receiver_reg and name_reg
+// may be clobbered.  Upon branch to miss_label, the receiver and name
+// registers have their original values.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
-                                      Builtins::Name storage_extend,
                                       JSObject* object,
                                       int index,
                                       Map* transition,
@@ -292,11 +294,12 @@
   if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
     // The properties must be extended before we can store the value.
     // We jump to a runtime call that extends the properties array.
+    __ push(receiver_reg);
     __ mov(r2, Operand(Handle<Map>(transition)));
-    // Please note, if we implement keyed store for arm we need
-    // to call the Builtins::KeyedStoreIC_ExtendStorage.
-    Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_ExtendStorage));
-    __ Jump(ic, RelocInfo::CODE_TARGET);
+    __ stm(db_w, sp, r2.bit() | r0.bit());
+    __ TailCallRuntime(
+           ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)),
+           3, 1);
     return;
   }
 
@@ -373,7 +376,7 @@
 
   // Check that the function really is a function.
   __ BranchOnSmi(r1, miss);
-  __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
+  __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
   __ b(ne, miss);
 
   // Patch the receiver on the stack with the global proxy if
@@ -388,68 +391,6 @@
 }
 
 
-static void GenerateCallConstFunction(MacroAssembler* masm,
-                                      JSFunction* function,
-                                      const ParameterCount& arguments) {
-  ASSERT(function->is_compiled());
-
-  // Get the function and setup the context.
-  __ mov(r1, Operand(Handle<JSFunction>(function)));
-  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-
-  // Jump to the cached code (tail call).
-  Handle<Code> code(function->code());
-  ParameterCount expected(function->shared()->formal_parameter_count());
-  __ InvokeCode(code, expected, arguments,
-                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
-}
-
-
-template <class Compiler>
-static void CompileLoadInterceptor(Compiler* compiler,
-                                   StubCompiler* stub_compiler,
-                                   MacroAssembler* masm,
-                                   JSObject* object,
-                                   JSObject* holder,
-                                   String* name,
-                                   LookupResult* lookup,
-                                   Register receiver,
-                                   Register scratch1,
-                                   Register scratch2,
-                                   Label* miss) {
-  ASSERT(holder->HasNamedInterceptor());
-  ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
-
-  // Check that the receiver isn't a smi.
-  __ BranchOnSmi(receiver, miss);
-
-  // Check that the maps haven't changed.
-  Register reg =
-      stub_compiler->CheckPrototypes(object, receiver, holder,
-                                     scratch1, scratch2, name, miss);
-
-  if (lookup->IsValid() && lookup->IsCacheable()) {
-    compiler->CompileCacheable(masm,
-                               stub_compiler,
-                               receiver,
-                               reg,
-                               scratch1,
-                               scratch2,
-                               holder,
-                               lookup,
-                               name,
-                               miss);
-  } else {
-    compiler->CompileRegular(masm,
-                             receiver,
-                             reg,
-                             scratch2,
-                             holder,
-                             miss);
-  }
-}
-
-
 static void PushInterceptorArguments(MacroAssembler* masm,
                                      Register receiver,
                                      Register holder,
@@ -500,7 +441,7 @@
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -523,9 +464,7 @@
     // Note: starting a frame here makes GC aware of pointers pushed below.
     __ EnterInternalFrame();
 
-    if (lookup->type() == CALLBACKS) {
-      __ push(receiver);
-    }
+    __ push(receiver);
     __ push(holder);
     __ push(name_);
 
@@ -546,10 +485,7 @@
     __ bind(&interceptor_failed);
     __ pop(name_);
     __ pop(holder);
-
-    if (lookup->type() == CALLBACKS) {
-      __ pop(receiver);
-    }
+    __ pop(receiver);
 
     __ LeaveInternalFrame();
 
@@ -621,108 +557,48 @@
 };
 
 
-class CallInterceptorCompiler BASE_EMBEDDED {
- public:
-  CallInterceptorCompiler(const ParameterCount& arguments, Register name)
-      : arguments_(arguments), argc_(arguments.immediate()), name_(name) {}
+static void CompileLoadInterceptor(LoadInterceptorCompiler* compiler,
+                                   StubCompiler* stub_compiler,
+                                   MacroAssembler* masm,
+                                   JSObject* object,
+                                   JSObject* holder,
+                                   String* name,
+                                   LookupResult* lookup,
+                                   Register receiver,
+                                   Register scratch1,
+                                   Register scratch2,
+                                   Label* miss) {
+  ASSERT(holder->HasNamedInterceptor());
+  ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
 
-  void CompileCacheable(MacroAssembler* masm,
-                        StubCompiler* stub_compiler,
-                        Register receiver,
-                        Register holder,
-                        Register scratch1,
-                        Register scratch2,
-                        JSObject* holder_obj,
-                        LookupResult* lookup,
-                        String* name,
-                        Label* miss_label) {
-    JSFunction* function = 0;
-    bool optimize = false;
-    // So far the most popular case for failed interceptor is
-    // CONSTANT_FUNCTION sitting below.
-    if (lookup->type() == CONSTANT_FUNCTION) {
-      function = lookup->GetConstantFunction();
-      // JSArray holder is a special case for call constant function
-      // (see the corresponding code).
-      if (function->is_compiled() && !holder_obj->IsJSArray()) {
-        optimize = true;
-      }
-    }
+  // Check that the receiver isn't a smi.
+  __ BranchOnSmi(receiver, miss);
 
-    if (!optimize) {
-      CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
-      return;
-    }
+  // Check that the maps haven't changed.
+  Register reg =
+      stub_compiler->CheckPrototypes(object, receiver, holder,
+                                     scratch1, scratch2, name, miss);
 
-    // Constant functions cannot sit on global object.
-    ASSERT(!lookup->holder()->IsGlobalObject());
-
-    __ EnterInternalFrame();
-    __ push(holder);  // Save the holder.
-    __ push(name_);  // Save the name.
-
-    CompileCallLoadPropertyWithInterceptor(masm,
-                                           receiver,
-                                           holder,
-                                           name_,
-                                           holder_obj);
-
-    ASSERT(!r0.is(name_));
-    ASSERT(!r0.is(scratch1));
-    __ pop(name_);  // Restore the name.
-    __ pop(scratch1);  // Restore the holder.
-    __ LeaveInternalFrame();
-
-    // Compare with no_interceptor_result_sentinel.
-    __ LoadRoot(scratch2, Heap::kNoInterceptorResultSentinelRootIndex);
-    __ cmp(r0, scratch2);
-    Label invoke;
-    __ b(ne, &invoke);
-
-    stub_compiler->CheckPrototypes(holder_obj, scratch1,
-                                   lookup->holder(), scratch1,
-                                   scratch2,
-                                   name,
-                                   miss_label);
-    GenerateCallConstFunction(masm, function, arguments_);
-
-    __ bind(&invoke);
-  }
-
-  void CompileRegular(MacroAssembler* masm,
-                      Register receiver,
-                      Register holder,
-                      Register scratch,
-                      JSObject* holder_obj,
-                      Label* miss_label) {
-    __ EnterInternalFrame();
-    // Save the name_ register across the call.
-    __ push(name_);
-
-    PushInterceptorArguments(masm,
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
+    compiler->CompileCacheable(masm,
+                               stub_compiler,
+                               receiver,
+                               reg,
+                               scratch1,
+                               scratch2,
+                               holder,
+                               lookup,
+                               name,
+                               miss);
+  } else {
+    compiler->CompileRegular(masm,
                              receiver,
+                             reg,
+                             scratch2,
                              holder,
-                             name_,
-                             holder_obj);
-
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ mov(r0, Operand(5));
-    __ mov(r1, Operand(ref));
-
-    CEntryStub stub(1);
-    __ CallStub(&stub);
-
-    // Restore the name_ register.
-    __ pop(name_);
-    __ LeaveInternalFrame();
+                             miss);
   }
-
- private:
-  const ParameterCount& arguments_;
-  int argc_;
-  Register name_;
-};
+}
 
 
 #undef __
@@ -735,7 +611,11 @@
                                        Register holder_reg,
                                        Register scratch,
                                        String* name,
+                                       int save_at_depth,
                                        Label* miss) {
+  // TODO(602): support object saving.
+  ASSERT(save_at_depth == kInvalidProtoDepth);
+
   // Check that the maps haven't changed.
   Register result =
       masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss);
@@ -762,7 +642,7 @@
     object = JSObject::cast(object->GetPrototype());
   }
 
-  // Return the register containin the holder.
+  // Return the register containing the holder.
   return result;
 }
 
@@ -901,12 +781,13 @@
 }
 
 
-Object* CallStubCompiler::CompileCallField(Object* object,
+Object* CallStubCompiler::CompileCallField(JSObject* object,
                                            JSObject* holder,
                                            int index,
                                            String* name) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
   Label miss;
 
@@ -919,8 +800,7 @@
   __ b(eq, &miss);
 
   // Do the right check and compute the holder register.
-  Register reg =
-      CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss);
+  Register reg = CheckPrototypes(object, r0, holder, r1, r3, name, &miss);
   GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
 
   GenerateCallFunction(masm(), object, arguments(), &miss);
@@ -941,7 +821,8 @@
                                               String* name,
                                               CheckType check) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
   Label miss;
 
@@ -962,7 +843,7 @@
   switch (check) {
     case RECEIVER_MAP_CHECK:
       // Check that the maps haven't changed.
-      CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss);
+      CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, name, &miss);
 
       // Patch the receiver on the stack with the global proxy if
       // necessary.
@@ -978,13 +859,13 @@
         __ jmp(&miss);
       } else {
         // Check that the object is a two-byte string or a symbol.
-        __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE);
+        __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE);
         __ b(hs, &miss);
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::STRING_FUNCTION_INDEX,
-                                            r2);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3,
+                                            r0);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3,
                         r1, name, &miss);
       }
       break;
@@ -998,14 +879,14 @@
         // Check that the object is a smi or a heap number.
         __ tst(r1, Operand(kSmiTagMask));
         __ b(eq, &fast);
-        __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE);
+        __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE);
         __ b(ne, &miss);
         __ bind(&fast);
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::NUMBER_FUNCTION_INDEX,
-                                            r2);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3,
+                                            r0);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3,
                         r1, name, &miss);
       }
       break;
@@ -1028,22 +909,22 @@
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::BOOLEAN_FUNCTION_INDEX,
-                                            r2);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3,
+                                            r0);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3,
                         r1, name, &miss);
       }
       break;
     }
 
     case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
-      CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss);
+      CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, name, &miss);
       // Make sure object->HasFastElements().
       // Get the elements array of the object.
       __ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset));
       // Check that the object is in fast mode (not dictionary).
-      __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
+      __ ldr(r0, FieldMemOperand(r3, HeapObject::kMapOffset));
       __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
-      __ cmp(r2, ip);
+      __ cmp(r0, ip);
       __ b(ne, &miss);
       break;
 
@@ -1051,7 +932,7 @@
       UNREACHABLE();
   }
 
-  GenerateCallConstFunction(masm(), function, arguments());
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -1067,14 +948,22 @@
 }
 
 
-Object* CallStubCompiler::CompileCallInterceptor(Object* object,
+Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
+  ASSERT(holder->HasNamedInterceptor());
+  ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
   Label miss;
 
+  const Register receiver = r0;
+  const Register holder_reg = r1;
+  const Register name_reg = r2;
+  const Register scratch = r3;
+
   // Get the number of arguments.
   const int argc = arguments().immediate();
 
@@ -1083,24 +972,79 @@
 
   // Get the receiver from the stack into r0.
   __ ldr(r0, MemOperand(sp, argc * kPointerSize));
-  // Load the name from the stack into r1.
-  __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
 
-  CallInterceptorCompiler compiler(arguments(), r1);
-  CompileLoadInterceptor(&compiler,
-                         this,
-                         masm(),
-                         JSObject::cast(object),
-                         holder,
-                         name,
-                         &lookup,
-                         r0,
-                         r2,
-                         r3,
-                         &miss);
+  // Check that the receiver isn't a smi.
+  __ BranchOnSmi(receiver, &miss);
 
+  // Check that the maps haven't changed.
+  Register reg = CheckPrototypes(object, receiver, holder, holder_reg,
+                                 scratch, name, &miss);
+  if (!reg.is(holder_reg)) {
+    __ mov(holder_reg, reg);
+  }
+
+  // If we call a constant function when the interceptor returns
+  // the no-result sentinel, generate code that optimizes this case.
+  if (lookup.IsProperty() &&
+      lookup.IsCacheable() &&
+      lookup.type() == CONSTANT_FUNCTION &&
+      lookup.GetConstantFunction()->is_compiled() &&
+      !holder->IsJSArray()) {
+    // Constant functions cannot sit on global object.
+    ASSERT(!lookup.holder()->IsGlobalObject());
+
+    // Call the interceptor.
+    __ EnterInternalFrame();
+    __ push(holder_reg);
+    __ push(name_reg);
+    CompileCallLoadPropertyWithInterceptor(masm(),
+                                           receiver,
+                                           holder_reg,
+                                           name_reg,
+                                           holder);
+    __ pop(name_reg);
+    __ pop(holder_reg);
+    __ LeaveInternalFrame();
+    // r0 no longer contains the receiver.
+
+    // If interceptor returns no-result sentinal, call the constant function.
+    __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
+    __ cmp(r0, scratch);
+    Label invoke;
+    __ b(ne, &invoke);
+    // Check the prototypes between the interceptor's holder and the
+    // constant function's holder.
+    CheckPrototypes(holder, holder_reg,
+                    lookup.holder(), r0,
+                    scratch,
+                    name,
+                    &miss);
+
+    __ InvokeFunction(lookup.GetConstantFunction(),
+                      arguments(),
+                      JUMP_FUNCTION);
+
+    __ bind(&invoke);
+
+  } else {
+    // Call a runtime function to load the interceptor property.
+    __ EnterInternalFrame();
+    __ push(name_reg);
+
+    PushInterceptorArguments(masm(), receiver, holder_reg, name_reg, holder);
+
+    __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+        5);
+
+    __ pop(name_reg);
+    __ LeaveInternalFrame();
+  }
+
+  // Move returned value, the function to call, to r1.
+  __ mov(r1, r0);
   // Restore receiver.
-  __ ldr(r0, MemOperand(sp, argc * kPointerSize));
+  __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
 
   GenerateCallFunction(masm(), object, arguments(), &miss);
 
@@ -1120,7 +1064,8 @@
                                             JSFunction* function,
                                             String* name) {
   // ----------- S t a t e -------------
-  //  -- lr: return address
+  //  -- r2    : name
+  //  -- lr    : return address
   // -----------------------------------
   Label miss;
 
@@ -1139,7 +1084,7 @@
   }
 
   // Check that the maps haven't changed.
-  CheckPrototypes(object, r0, holder, r3, r2, name, &miss);
+  CheckPrototypes(object, r0, holder, r3, r1, name, &miss);
 
   // Get the value from the cell.
   __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
@@ -1159,8 +1104,8 @@
 
     // Check the shared function info. Make sure it hasn't changed.
     __ mov(r3, Operand(Handle<SharedFunctionInfo>(function->shared())));
-    __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-    __ cmp(r2, r3);
+    __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+    __ cmp(r4, r3);
     __ b(ne, &miss);
   } else {
     __ cmp(r1, Operand(Handle<JSFunction>(function)));
@@ -1178,7 +1123,7 @@
   __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
 
   // Jump to the cached code (tail call).
-  __ IncrementCounter(&Counters::call_global_inline, 1, r2, r3);
+  __ IncrementCounter(&Counters::call_global_inline, 1, r1, r3);
   ASSERT(function->is_compiled());
   Handle<Code> code(function->code());
   ParameterCount expected(function->shared()->formal_parameter_count());
@@ -1202,25 +1147,19 @@
                                              String* name) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
   Label miss;
 
-  // Get the receiver from the stack.
-  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
-
-  // name register might be clobbered.
   GenerateStoreField(masm(),
-                     Builtins::StoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
-                     r3, r2, r1,
+                     r1, r2, r3,
                      &miss);
   __ bind(&miss);
-  __ mov(r2, Operand(Handle<String>(name)));  // restore name
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
@@ -1234,39 +1173,33 @@
                                                 String* name) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
   Label miss;
 
-  // Get the object from the stack.
-  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ tst(r3, Operand(kSmiTagMask));
+  __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &miss);
 
   // Check that the map of the object hasn't changed.
-  __ ldr(r1, FieldMemOperand(r3, HeapObject::kMapOffset));
-  __ cmp(r1, Operand(Handle<Map>(object->map())));
+  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+  __ cmp(r3, Operand(Handle<Map>(object->map())));
   __ b(ne, &miss);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(r3, r1, &miss);
+    __ CheckAccessGlobalProxy(r1, r3, &miss);
   }
 
   // Stub never generated for non-global objects that require access
   // checks.
   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
 
-  __ ldr(ip, MemOperand(sp));  // receiver
-  __ push(ip);
+  __ push(r1);  // receiver
   __ mov(ip, Operand(Handle<AccessorInfo>(callback)));  // callback info
-  __ push(ip);
-  __ push(r2);  // name
-  __ push(r0);  // value
+  __ stm(db_w, sp, ip.bit() | r2.bit() | r0.bit());
 
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
@@ -1287,37 +1220,33 @@
                                                    String* name) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
   Label miss;
 
-  // Get the object from the stack.
-  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ tst(r3, Operand(kSmiTagMask));
+  __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &miss);
 
   // Check that the map of the object hasn't changed.
-  __ ldr(r1, FieldMemOperand(r3, HeapObject::kMapOffset));
-  __ cmp(r1, Operand(Handle<Map>(receiver->map())));
+  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+  __ cmp(r3, Operand(Handle<Map>(receiver->map())));
   __ b(ne, &miss);
 
   // Perform global security token check if needed.
   if (receiver->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(r3, r1, &miss);
+    __ CheckAccessGlobalProxy(r1, r3, &miss);
   }
 
-  // Stub never generated for non-global objects that require access
+  // Stub is never generated for non-global objects that require access
   // checks.
   ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
 
-  __ ldr(ip, MemOperand(sp));  // receiver
-  __ push(ip);
-  __ push(r2);  // name
-  __ push(r0);  // value
+  __ push(r1);  // receiver.
+  __ push(r2);  // name.
+  __ push(r0);  // value.
 
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
@@ -1339,14 +1268,13 @@
                                               String* name) {
   // ----------- S t a t e -------------
   //  -- r0    : value
+  //  -- r1    : receiver
   //  -- r2    : name
   //  -- lr    : return address
-  //  -- [sp]  : receiver
   // -----------------------------------
   Label miss;
 
   // Check that the map of the global has not changed.
-  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
   __ cmp(r3, Operand(Handle<Map>(object->map())));
   __ b(ne, &miss);
@@ -1355,12 +1283,12 @@
   __ mov(r2, Operand(Handle<JSGlobalPropertyCell>(cell)));
   __ str(r0, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
 
-  __ IncrementCounter(&Counters::named_store_global_inline, 1, r1, r3);
+  __ IncrementCounter(&Counters::named_store_global_inline, 1, r4, r3);
   __ Ret();
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r1, r3);
+  __ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r4, r3);
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
@@ -1672,7 +1600,7 @@
   __ cmp(r2, Operand(Handle<String>(name)));
   __ b(ne, &miss);
 
-  GenerateLoadStringLength2(masm(), r0, r1, r3, &miss);
+  GenerateLoadStringLength(masm(), r0, r1, r3, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3);
 
@@ -1717,7 +1645,6 @@
   __ ldr(r3, MemOperand(sp));
   // r1 is used as scratch register, r3 and r2 might be clobbered.
   GenerateStoreField(masm(),
-                     Builtins::StoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
diff --git a/src/arm/stub-cache-arm.cc.rej b/src/arm/stub-cache-arm.cc.rej
deleted file mode 100644
index f8baa41..0000000
--- a/src/arm/stub-cache-arm.cc.rej
+++ /dev/null
@@ -1,153 +0,0 @@
-*************** void StubCompiler::GenerateLoadInterceptor(JSObject* object,
-*** 491,520 ****
-                                             Register scratch2,
-                                             String* name,
-                                             Label* miss) {
--   // Check that the receiver isn't a smi.
--   __ tst(receiver, Operand(kSmiTagMask));
--   __ b(eq, miss);
-- 
--   // Check that the maps haven't changed.
--   Register reg =
--       CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss);
-- 
--   // Push the arguments on the JS stack of the caller.
--   __ push(receiver);  // receiver
--   __ push(reg);  // holder
--   __ push(name_reg);  // name
-- 
--   InterceptorInfo* interceptor = holder->GetNamedInterceptor();
--   ASSERT(!Heap::InNewSpace(interceptor));
--   __ mov(scratch1, Operand(Handle<Object>(interceptor)));
--   __ push(scratch1);
--   __ ldr(scratch2, FieldMemOperand(scratch1, InterceptorInfo::kDataOffset));
--   __ push(scratch2);
-- 
--   // Do tail-call to the runtime system.
--   ExternalReference load_ic_property =
--       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
--   __ TailCallRuntime(load_ic_property, 5, 1);
-  }
-  
-  
---- 854,871 ----
-                                             Register scratch2,
-                                             String* name,
-                                             Label* miss) {
-+   LoadInterceptorCompiler compiler(name_reg);
-+   CompileLoadInterceptor(&compiler,
-+                          this,
-+                          masm(),
-+                          object,
-+                          holder,
-+                          name,
-+                          lookup,
-+                          receiver,
-+                          scratch1,
-+                          scratch2,
-+                          miss);
-  }
-  
-  
-*************** Object* CallStubCompiler::CompileCallField(Object* object,
-*** 572,593 ****
-        CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss);
-    GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
-  
--   // Check that the function really is a function.
--   __ tst(r1, Operand(kSmiTagMask));
--   __ b(eq, &miss);
--   // Get the map.
--   __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
--   __ b(ne, &miss);
-- 
--   // Patch the receiver on the stack with the global proxy if
--   // necessary.
--   if (object->IsGlobalObject()) {
--     __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
--     __ str(r3, MemOperand(sp, argc * kPointerSize));
--   }
-- 
--   // Invoke the function.
--   __ InvokeFunction(r1, arguments(), JUMP_FUNCTION);
-  
-    // Handle call cache miss.
-    __ bind(&miss);
---- 923,929 ----
-        CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss);
-    GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
-  
-+   GenerateCallFunction(masm(), object, arguments(), &miss);
-  
-    // Handle call cache miss.
-    __ bind(&miss);
-*************** Object* CallStubCompiler::CompileCallConstant(Object* object,
-*** 715,730 ****
-        UNREACHABLE();
-    }
-  
--   // Get the function and setup the context.
--   __ mov(r1, Operand(Handle<JSFunction>(function)));
--   __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-- 
--   // Jump to the cached code (tail call).
--   ASSERT(function->is_compiled());
--   Handle<Code> code(function->code());
--   ParameterCount expected(function->shared()->formal_parameter_count());
--   __ InvokeCode(code, expected, arguments(),
--                 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
-  
-    // Handle call cache miss.
-    __ bind(&miss);
---- 1051,1057 ----
-        UNREACHABLE();
-    }
-  
-+   GenerateCallConstFunction(masm(), function, arguments());
-  
-    // Handle call cache miss.
-    __ bind(&miss);
-*************** Object* CallStubCompiler::CompileCallInterceptor(Object* object,
-*** 748,754 ****
-    // -----------------------------------
-    Label miss;
-  
--   // TODO(1224669): Implement.
-  
-    // Handle call cache miss.
-    __ bind(&miss);
---- 1075,1108 ----
-    // -----------------------------------
-    Label miss;
-  
-+   // Get the number of arguments.
-+   const int argc = arguments().immediate();
-+ 
-+   LookupResult lookup;
-+   LookupPostInterceptor(holder, name, &lookup);
-+ 
-+   // Get the receiver from the stack into r0.
-+   __ ldr(r0, MemOperand(sp, argc * kPointerSize));
-+   // Load the name from the stack into r1.
-+   __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
-+ 
-+   CallInterceptorCompiler compiler(arguments(), r1);
-+   CompileLoadInterceptor(&compiler,
-+                          this,
-+                          masm(),
-+                          JSObject::cast(object),
-+                          holder,
-+                          name,
-+                          &lookup,
-+                          r0,
-+                          r2,
-+                          r3,
-+                          &miss);
-+ 
-+   // Restore receiver.
-+   __ ldr(r0, MemOperand(sp, argc * kPointerSize));
-+ 
-+   GenerateCallFunction(masm(), object, arguments(), &miss);
-  
-    // Handle call cache miss.
-    __ bind(&miss);
diff --git a/src/arm/virtual-frame-arm.cc b/src/arm/virtual-frame-arm.cc
index 7a8ac72..0f7c597 100644
--- a/src/arm/virtual-frame-arm.cc
+++ b/src/arm/virtual-frame-arm.cc
@@ -47,7 +47,7 @@
     : elements_(parameter_count() + local_count() + kPreallocatedElements),
       stack_pointer_(parameter_count()) {  // 0-based index of TOS.
   for (int i = 0; i <= stack_pointer_; i++) {
-    elements_.Add(FrameElement::MemoryElement());
+    elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
   }
   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
     register_locations_[i] = kIllegalIndex;
@@ -233,6 +233,14 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+  ASSERT(cgen()->HasValidEntryRegisters());
+  __ DebugBreak();
+}
+#endif
+
+
 void VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
                                  InvokeJSFlags flags,
                                  int arg_count) {
@@ -305,7 +313,7 @@
 
 void VirtualFrame::EmitPush(Register reg) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
   stack_pointer_++;
   __ push(reg);
 }
diff --git a/src/arm/virtual-frame-arm.h b/src/arm/virtual-frame-arm.h
index 9a2f7d3..a45cfc6 100644
--- a/src/arm/virtual-frame-arm.h
+++ b/src/arm/virtual-frame-arm.h
@@ -68,7 +68,8 @@
   MacroAssembler* masm() { return cgen()->masm(); }
 
   // Create a duplicate of an existing valid frame element.
-  FrameElement CopyElementAt(int index);
+  FrameElement CopyElementAt(int index,
+                             NumberInfo::Type info = NumberInfo::kUnknown);
 
   // The number of elements on the virtual frame.
   int element_count() { return elements_.length(); }
@@ -297,6 +298,10 @@
   void CallRuntime(Runtime::Function* f, int arg_count);
   void CallRuntime(Runtime::FunctionId id, int arg_count);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  void DebugBreak();
+#endif
+
   // Invoke builtin given the number of arguments it expects on (and
   // removes from) the stack.
   void InvokeBuiltin(Builtins::JavaScript id,
@@ -339,7 +344,7 @@
   void EmitPushMultiple(int count, int src_regs);
 
   // Push an element on the virtual frame.
-  void Push(Register reg);
+  void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
   void Push(Handle<Object> value);
   void Push(Smi* value) { Push(Handle<Object>(value)); }
 
diff --git a/src/array.js b/src/array.js
index c3ab179..c28a662 100644
--- a/src/array.js
+++ b/src/array.js
@@ -566,10 +566,11 @@
 function ArraySplice(start, delete_count) {
   var num_arguments = %_ArgumentsLength();
 
-  // SpiderMonkey and KJS return undefined in the case where no
+  // SpiderMonkey and JSC return undefined in the case where no
   // arguments are given instead of using the implicit undefined
   // arguments.  This does not follow ECMA-262, but we do the same for
   // compatibility.
+  // TraceMonkey follows ECMA-262 though.
   if (num_arguments == 0) return;
 
   var len = TO_UINT32(this.length);
@@ -582,7 +583,7 @@
     if (start_i > len) start_i = len;
   }
 
-  // SpiderMonkey and KJS treat the case where no delete count is
+  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
   // given differently from when an undefined delete count is given.
   // This does not follow ECMA-262, but we do the same for
   // compatibility.
diff --git a/src/assembler.cc b/src/assembler.cc
index dbf2742..aaf10ef 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -430,6 +430,11 @@
       return "code target (js construct call)";
     case RelocInfo::CODE_TARGET_CONTEXT:
       return "code target (context)";
+    case RelocInfo::DEBUG_BREAK:
+#ifndef ENABLE_DEBUGGER_SUPPORT
+      UNREACHABLE();
+#endif
+      return "debug break";
     case RelocInfo::CODE_TARGET:
       return "code target";
     case RelocInfo::RUNTIME_ENTRY:
@@ -485,6 +490,11 @@
     case EMBEDDED_OBJECT:
       Object::VerifyPointer(target_object());
       break;
+    case DEBUG_BREAK:
+#ifndef ENABLE_DEBUGGER_SUPPORT
+      UNREACHABLE();
+      break;
+#endif
     case CONSTRUCT_CALL:
     case CODE_TARGET_CONTEXT:
     case CODE_TARGET: {
@@ -569,6 +579,11 @@
 }
 
 
+ExternalReference ExternalReference::transcendental_cache_array_address() {
+  return ExternalReference(TranscendentalCache::cache_array_address());
+}
+
+
 ExternalReference ExternalReference::keyed_lookup_cache_keys() {
   return ExternalReference(KeyedLookupCache::keys_address());
 }
@@ -609,6 +624,11 @@
 }
 
 
+ExternalReference ExternalReference::new_space_mask() {
+  return ExternalReference(reinterpret_cast<Address>(Heap::NewSpaceMask()));
+}
+
+
 ExternalReference ExternalReference::new_space_allocation_top_address() {
   return ExternalReference(Heap::NewSpaceAllocationTopAddress());
 }
diff --git a/src/assembler.h b/src/assembler.h
index 942ce47..004ede3 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -119,6 +119,7 @@
     // Please note the order is important (see IsCodeTarget, IsGCRelocMode).
     CONSTRUCT_CALL,  // code target that is a call to a JavaScript constructor.
     CODE_TARGET_CONTEXT,  // code target used for contextual loads.
+    DEBUG_BREAK,
     CODE_TARGET,         // code target which is not any of the above.
     EMBEDDED_OBJECT,
     EMBEDDED_STRING,
@@ -399,6 +400,7 @@
 
   static ExternalReference perform_gc_function();
   static ExternalReference random_positive_smi_function();
+  static ExternalReference transcendental_cache_array_address();
 
   // Static data in the keyed lookup cache.
   static ExternalReference keyed_lookup_cache_keys();
@@ -426,6 +428,7 @@
 
   // Static variable Heap::NewSpaceStart()
   static ExternalReference new_space_start();
+  static ExternalReference new_space_mask();
   static ExternalReference heap_always_allocate_scope_depth();
 
   // Used for fast allocation in generated code.
diff --git a/src/ast.h b/src/ast.h
index 48d0bfa..927a9f5 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -102,6 +102,7 @@
 // Forward declarations
 class TargetCollector;
 class MaterializedLiteral;
+class DefinitionInfo;
 
 #define DEF_FORWARD_DECLARATION(type) class type;
 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
@@ -182,7 +183,7 @@
 
   static const int kNoLabel = -1;
 
-  Expression() : num_(kNoLabel) {}
+  Expression() : num_(kNoLabel), def_(NULL), defined_vars_(NULL) {}
 
   virtual Expression* AsExpression()  { return this; }
 
@@ -193,6 +194,15 @@
   // names because [] for string objects is handled only by keyed ICs.
   virtual bool IsPropertyName() { return false; }
 
+  // True if the expression does not have (evaluated) subexpressions.
+  // Function literals are leaves because their subexpressions are not
+  // evaluated.
+  virtual bool IsLeaf() { return false; }
+
+  // True if the expression has no side effects and is safe to
+  // evaluate out of order.
+  virtual bool IsTrivial() { return false; }
+
   // Mark the expression as being compiled as an expression
   // statement. This is used to transform postfix increments to
   // (faster) prefix increments.
@@ -206,9 +216,20 @@
   // AST node numbering ordered by evaluation order.
   void set_num(int n) { num_ = n; }
 
+  // Data flow information.
+  DefinitionInfo* var_def() { return def_; }
+  void set_var_def(DefinitionInfo* def) { def_ = def; }
+
+  ZoneList<DefinitionInfo*>* defined_vars() { return defined_vars_; }
+  void set_defined_vars(ZoneList<DefinitionInfo*>* defined_vars) {
+    defined_vars_ = defined_vars;
+  }
+
  private:
   StaticType type_;
   int num_;
+  DefinitionInfo* def_;
+  ZoneList<DefinitionInfo*>* defined_vars_;
 };
 
 
@@ -720,6 +741,9 @@
     return false;
   }
 
+  virtual bool IsLeaf() { return true; }
+  virtual bool IsTrivial() { return true; }
+
   // Identity testers.
   bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
   bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
@@ -802,6 +826,8 @@
   virtual ObjectLiteral* AsObjectLiteral() { return this; }
   virtual void Accept(AstVisitor* v);
 
+  virtual bool IsLeaf() { return properties()->is_empty(); }
+
   Handle<FixedArray> constant_properties() const {
     return constant_properties_;
   }
@@ -825,6 +851,8 @@
 
   virtual void Accept(AstVisitor* v);
 
+  virtual bool IsLeaf() { return true; }
+
   Handle<String> pattern() const { return pattern_; }
   Handle<String> flags() const { return flags_; }
 
@@ -849,6 +877,8 @@
   virtual void Accept(AstVisitor* v);
   virtual ArrayLiteral* AsArrayLiteral() { return this; }
 
+  virtual bool IsLeaf() { return values()->is_empty(); }
+
   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   ZoneList<Expression*>* values() const { return values_; }
 
@@ -896,6 +926,15 @@
     return var_ == NULL ? true : var_->IsValidLeftHandSide();
   }
 
+  virtual bool IsLeaf() {
+    ASSERT(var_ != NULL);  // Variable must be resolved.
+    return var()->is_global() || var()->rewrite()->IsLeaf();
+  }
+
+  // Reading from a mutable variable is a side effect, but 'this' is
+  // immutable.
+  virtual bool IsTrivial() { return is_this(); }
+
   bool IsVariable(Handle<String> n) {
     return !is_this() && name().is_identical_to(n);
   }
@@ -981,6 +1020,8 @@
   // Type testing & conversion
   virtual Slot* AsSlot() { return this; }
 
+  virtual bool IsLeaf() { return true; }
+
   // Accessors
   Variable* var() const { return var_; }
   Type type() const { return type_; }
@@ -1337,6 +1378,8 @@
   // Type testing & conversion
   virtual FunctionLiteral* AsFunctionLiteral()  { return this; }
 
+  virtual bool IsLeaf() { return true; }
+
   Handle<String> name() const  { return name_; }
   Scope* scope() const  { return scope_; }
   ZoneList<Statement*>* body() const  { return body_; }
@@ -1403,6 +1446,8 @@
 
   Handle<JSFunction> boilerplate() const { return boilerplate_; }
 
+  virtual bool IsLeaf() { return true; }
+
   virtual void Accept(AstVisitor* v);
 
  private:
@@ -1413,6 +1458,7 @@
 class ThisFunction: public Expression {
  public:
   virtual void Accept(AstVisitor* v);
+  virtual bool IsLeaf() { return true; }
 };
 
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 62edae5..6e565e0 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -177,116 +177,6 @@
 }
 
 
-// Pending fixups are code positions that refer to builtin code
-// objects that were not available at the time the code was generated.
-// The pending list is processed whenever an environment has been
-// created.
-class PendingFixups : public AllStatic {
- public:
-  static void Add(Code* code, MacroAssembler* masm);
-  static bool Process(Handle<JSBuiltinsObject> builtins);
-
-  static void Iterate(ObjectVisitor* v);
-
- private:
-  static List<Object*> code_;
-  static List<const char*> name_;
-  static List<int> pc_;
-  static List<uint32_t> flags_;
-
-  static void Clear();
-};
-
-
-List<Object*> PendingFixups::code_(0);
-List<const char*> PendingFixups::name_(0);
-List<int> PendingFixups::pc_(0);
-List<uint32_t> PendingFixups::flags_(0);
-
-
-void PendingFixups::Add(Code* code, MacroAssembler* masm) {
-  // Note this code is not only called during bootstrapping.
-  List<MacroAssembler::Unresolved>* unresolved = masm->unresolved();
-  int n = unresolved->length();
-  for (int i = 0; i < n; i++) {
-    const char* name = unresolved->at(i).name;
-    code_.Add(code);
-    name_.Add(name);
-    pc_.Add(unresolved->at(i).pc);
-    flags_.Add(unresolved->at(i).flags);
-    LOG(StringEvent("unresolved", name));
-  }
-}
-
-
-bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) {
-  HandleScope scope;
-  // NOTE: Extra fixups may be added to the list during the iteration
-  // due to lazy compilation of functions during the processing. Do not
-  // cache the result of getting the length of the code list.
-  for (int i = 0; i < code_.length(); i++) {
-    const char* name = name_[i];
-    uint32_t flags = flags_[i];
-    Handle<String> symbol = Factory::LookupAsciiSymbol(name);
-    Object* o = builtins->GetProperty(*symbol);
-#ifdef DEBUG
-    if (!o->IsJSFunction()) {
-      V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name);
-    }
-#endif
-    Handle<SharedFunctionInfo> shared(JSFunction::cast(o)->shared());
-    // Make sure the number of parameters match the formal parameter count.
-    int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags);
-    USE(argc);
-    ASSERT(shared->formal_parameter_count() == argc);
-    // Do lazy compilation if necessary and check for stack overflows.
-    if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) {
-      Clear();
-      return false;
-    }
-    Code* code = Code::cast(code_[i]);
-    Address pc = code->instruction_start() + pc_[i];
-    RelocInfo target(pc, RelocInfo::CODE_TARGET, 0);
-    bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags);
-    if (use_code_object) {
-      target.set_target_object(shared->code());
-    } else {
-      target.set_target_address(shared->code()->instruction_start());
-    }
-    LOG(StringEvent("resolved", name));
-  }
-  Clear();
-
-  // TODO(1240818): We should probably try to avoid doing this for all
-  // the V8 builtin JS files. It should only happen after running
-  // runtime.js - just like there shouldn't be any fixups left after
-  // that.
-  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
-    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
-    Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
-    JSFunction* function = JSFunction::cast(builtins->GetProperty(*name));
-    builtins->set_javascript_builtin(id, function);
-  }
-
-  return true;
-}
-
-
-void PendingFixups::Clear() {
-  code_.Clear();
-  name_.Clear();
-  pc_.Clear();
-  flags_.Clear();
-}
-
-
-void PendingFixups::Iterate(ObjectVisitor* v) {
-  if (!code_.is_empty()) {
-    v->VisitPointers(&code_[0], &code_[0] + code_.length());
-  }
-}
-
-
 class Genesis BASE_EMBEDDED {
  public:
   Genesis(Handle<Object> global_object,
@@ -327,6 +217,10 @@
   // deserialized, leaving the GC to pick it up.
   void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
                          Handle<JSGlobalProxy> global_proxy);
+  // Similarly, we want to use the inner global that has been created by the
+  // templates passed through the API.  The inner global from the snapshot is
+  // detached from the other objects in the snapshot.
+  void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
   // New context initialization.  Used for creating a context from scratch.
   void InitializeGlobal(Handle<GlobalObject> inner_global,
                         Handle<JSFunction> empty_function);
@@ -341,12 +235,10 @@
   static bool InstallExtension(const char* name);
   static bool InstallExtension(v8::RegisteredExtension* current);
   static void InstallSpecialObjects(Handle<Context> global_context);
+  bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
   bool ConfigureApiObject(Handle<JSObject> object,
                           Handle<ObjectTemplateInfo> object_template);
   bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
-  void TransferMapsToDeserializedGlobals(
-    Handle<GlobalObject> inner_global_outside_snapshot,
-    Handle<GlobalObject> inner_global_from_snapshot);
 
   // Migrates all properties from the 'from' object to the 'to'
   // object and overrides the prototype in 'to' with the one from
@@ -385,15 +277,6 @@
 void Bootstrapper::Iterate(ObjectVisitor* v) {
   extensions_cache.Iterate(v);
   v->Synchronize("Extensions");
-  PendingFixups::Iterate(v);
-  v->Synchronize("PendingFixups");
-}
-
-
-// While setting up the environment, we collect code positions that
-// need to be patched before we can run any code in the environment.
-void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) {
-  PendingFixups::Add(code, masm);
 }
 
 
@@ -634,7 +517,7 @@
     Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
     js_global_function =
         Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
-                             JSGlobalObject::kSize + 17 * kPointerSize, code, true);
+                             JSGlobalObject::kSize, code, true);
     // Change the constructor property of the prototype of the
     // hidden global function to refer to the Object function.
     Handle<JSObject> prototype =
@@ -704,6 +587,28 @@
 }
 
 
+void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
+  Handle<GlobalObject> inner_global_from_snapshot(
+      GlobalObject::cast(global_context_->extension()));
+  Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
+  global_context_->set_extension(*inner_global);
+  global_context_->set_global(*inner_global);
+  global_context_->set_security_token(*inner_global);
+  static const PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
+  ForceSetProperty(builtins_global,
+                   Factory::LookupAsciiSymbol("global"),
+                   inner_global,
+                   attributes);
+  // Setup the reference from the global object to the builtins object.
+  JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
+  TransferNamedProperties(inner_global_from_snapshot, inner_global);
+  TransferIndexedProperties(inner_global_from_snapshot, inner_global);
+}
+
+
+// This is only called if we are not using snapshots.  The equivalent
+// work in the snapshot case is done in HookUpInnerGlobal.
 void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
                                Handle<JSFunction> empty_function) {
   // --- G l o b a l   C o n t e x t ---
@@ -865,11 +770,11 @@
 #ifdef DEBUG
     LookupResult lookup;
     result->LocalLookup(Heap::callee_symbol(), &lookup);
-    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);
 
     result->LocalLookup(Heap::length_symbol(), &lookup);
-    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);
 
     ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
@@ -977,6 +882,7 @@
         0,
         extension,
         NULL,
+        Handle<String>::null(),
         use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
     if (boilerplate.is_null()) return false;
     if (cache != NULL) cache->Add(name, boilerplate);
@@ -1003,8 +909,7 @@
   Handle<Object> result =
       Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
   if (has_pending_exception) return false;
-  return PendingFixups::Process(
-      Handle<JSBuiltinsObject>(top_context->builtins()));
+  return true;
 }
 
 
@@ -1024,7 +929,6 @@
   INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
   INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
   INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
-  INSTALL_NATIVE(JSFunction, "ToBoolean", to_boolean_fun);
   INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
   INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
   INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
@@ -1211,6 +1115,10 @@
        i++) {
     Vector<const char> name = Natives::GetScriptName(i);
     if (!CompileBuiltin(i)) return false;
+    // TODO(ager): We really only need to install the JS builtin
+    // functions on the builtins object after compiling and running
+    // runtime.js.
+    if (!InstallJSBuiltins(builtins)) return false;
   }
 
   InstallNativeFunctions();
@@ -1397,17 +1305,19 @@
 }
 
 
-void Genesis::TransferMapsToDeserializedGlobals(
-    Handle<GlobalObject> inner_global_outside_snapshot,
-    Handle<GlobalObject> inner_global_from_snapshot) {
-  Handle<Map> from_map(inner_global_outside_snapshot->map());
-#ifdef DEBUG
-  Handle<Map> to_map(inner_global_from_snapshot->map());
-  ASSERT_EQ(to_map->instance_size(), from_map->instance_size());
-  ASSERT_EQ(0, to_map->inobject_properties());
-  ASSERT_EQ(0, from_map->inobject_properties());
-#endif
-  inner_global_from_snapshot->set_map(*from_map);
+bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
+  HandleScope scope;
+  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
+    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
+    Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
+    Handle<JSFunction> function
+        = Handle<JSFunction>(JSFunction::cast(builtins->GetProperty(*name)));
+    builtins->set_javascript_builtin(id, *function);
+    Handle<SharedFunctionInfo> shared
+        = Handle<SharedFunctionInfo>(function->shared());
+    if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
+  }
+  return true;
 }
 
 
@@ -1415,7 +1325,7 @@
     v8::Handle<v8::ObjectTemplate> global_proxy_template) {
   Handle<JSObject> global_proxy(
       JSObject::cast(global_context()->global_proxy()));
-  Handle<JSObject> js_global(JSObject::cast(global_context()->global()));
+  Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
 
   if (!global_proxy_template.IsEmpty()) {
     // Configure the global proxy object.
@@ -1429,11 +1339,11 @@
     if (!proxy_constructor->prototype_template()->IsUndefined()) {
       Handle<ObjectTemplateInfo> inner_data(
           ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
-      if (!ConfigureApiObject(js_global, inner_data)) return false;
+      if (!ConfigureApiObject(inner_global, inner_data)) return false;
     }
   }
 
-  SetObjectPrototype(global_proxy, js_global);
+  SetObjectPrototype(global_proxy, inner_global);
   return true;
 }
 
@@ -1485,7 +1395,7 @@
           LookupResult result;
           to->LocalLookup(descs->GetKey(i), &result);
           // If the property is already there we skip it
-          if (result.IsValid()) continue;
+          if (result.IsProperty()) continue;
           HandleScope inner;
           ASSERT(!to->HasFastProperties());
           // Add to dictionary.
@@ -1520,7 +1430,7 @@
         // If the property is already there we skip it.
         LookupResult result;
         to->LocalLookup(String::cast(raw_key), &result);
-        if (result.IsValid()) continue;
+        if (result.IsProperty()) continue;
         // Set the property.
         Handle<String> key = Handle<String>(String::cast(raw_key));
         Handle<Object> value = Handle<Object>(properties->ValueAt(i));
@@ -1604,25 +1514,33 @@
 void Genesis::BuildSpecialFunctionTable() {
   HandleScope scope;
   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
-  // Add special versions for Array.prototype.pop and push.
+  // Add special versions for some Array.prototype functions.
   Handle<JSFunction> function =
       Handle<JSFunction>(
           JSFunction::cast(global->GetProperty(Heap::Array_symbol())));
   Handle<JSObject> visible_prototype =
       Handle<JSObject>(JSObject::cast(function->prototype()));
-  // Remember to put push and pop on the hidden prototype if it's there.
-  Handle<JSObject> push_and_pop_prototype;
+  // Remember to put those specializations on the hidden prototype if present.
+  Handle<JSObject> special_prototype;
   Handle<Object> superproto(visible_prototype->GetPrototype());
   if (superproto->IsJSObject() &&
       JSObject::cast(*superproto)->map()->is_hidden_prototype()) {
-    push_and_pop_prototype = Handle<JSObject>::cast(superproto);
+    special_prototype = Handle<JSObject>::cast(superproto);
   } else {
-    push_and_pop_prototype = visible_prototype;
+    special_prototype = visible_prototype;
   }
-  AddSpecialFunction(push_and_pop_prototype, "pop",
+  AddSpecialFunction(special_prototype, "pop",
                      Handle<Code>(Builtins::builtin(Builtins::ArrayPop)));
-  AddSpecialFunction(push_and_pop_prototype, "push",
+  AddSpecialFunction(special_prototype, "push",
                      Handle<Code>(Builtins::builtin(Builtins::ArrayPush)));
+  AddSpecialFunction(special_prototype, "shift",
+                     Handle<Code>(Builtins::builtin(Builtins::ArrayShift)));
+  AddSpecialFunction(special_prototype, "unshift",
+                     Handle<Code>(Builtins::builtin(Builtins::ArrayUnshift)));
+  AddSpecialFunction(special_prototype, "slice",
+                     Handle<Code>(Builtins::builtin(Builtins::ArraySlice)));
+  AddSpecialFunction(special_prototype, "splice",
+                     Handle<Code>(Builtins::builtin(Builtins::ArraySplice)));
 }
 
 
@@ -1648,19 +1566,15 @@
     JSFunction* empty_function =
         JSFunction::cast(result_->function_map()->prototype());
     empty_function_ = Handle<JSFunction>(empty_function);
-    Handle<GlobalObject> inner_global_outside_snapshot;
+    Handle<GlobalObject> inner_global;
     Handle<JSGlobalProxy> global_proxy =
         CreateNewGlobals(global_template,
                          global_object,
-                         &inner_global_outside_snapshot);
-    // CreateNewGlobals returns an inner global that it just made, but
-    // we won't give that to HookUpGlobalProxy because we want to hook
-    // up the global proxy to the one from the snapshot.
-    Handle<GlobalObject> inner_global(
-        GlobalObject::cast(global_context_->extension()));
+                         &inner_global);
+
     HookUpGlobalProxy(inner_global, global_proxy);
-    TransferMapsToDeserializedGlobals(inner_global_outside_snapshot,
-                                      inner_global);
+    HookUpInnerGlobal(inner_global);
+
     if (!ConfigureGlobalObjects(global_template)) return;
   } else {
     // We get here if there was no context snapshot.
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index 19fc39a..f905a28 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -74,9 +74,6 @@
   // Accessors for the native scripts cache. Used in lazy loading.
   static Handle<String> NativesSourceLookup(int index);
 
-  // Append code that needs fixup at the end of boot strapping.
-  static void AddFixup(Code* code, MacroAssembler* masm);
-
   // Tells whether bootstrapping is active.
   static bool IsActive() { return BootstrapperActive::IsActive(); }
 
diff --git a/src/builtins.cc b/src/builtins.cc
index db0770f..ee98769 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -168,28 +168,6 @@
 // ----------------------------------------------------------------------------
 
 
-Handle<Code> Builtins::GetCode(JavaScript id, bool* resolved) {
-  Code* code = Builtins::builtin(Builtins::Illegal);
-  *resolved = false;
-
-  if (Top::context() != NULL) {
-    Object* object = Top::builtins()->javascript_builtin(id);
-    if (object->IsJSFunction()) {
-      Handle<SharedFunctionInfo> shared(JSFunction::cast(object)->shared());
-      // Make sure the number of parameters match the formal parameter count.
-      ASSERT(shared->formal_parameter_count() ==
-             Builtins::GetArgumentsCount(id));
-      if (EnsureCompiled(shared, CLEAR_EXCEPTION)) {
-        code = shared->code();
-        *resolved = true;
-      }
-    }
-  }
-
-  return Handle<Code>(code);
-}
-
-
 BUILTIN(Illegal) {
   UNREACHABLE();
   return Heap::undefined_value();  // Make compiler happy.
@@ -268,19 +246,19 @@
   JSArray* array = JSArray::cast(*args.receiver());
   ASSERT(array->HasFastElements());
 
-  // Make sure we have space for the elements.
   int len = Smi::cast(array->length())->value();
+  int to_add = args.length() - 1;
+  if (to_add == 0) {
+    return Smi::FromInt(len);
+  }
+  // Currently fixed arrays cannot grow too big, so
+  // we should never hit this case.
+  ASSERT(to_add <= (Smi::kMaxValue - len));
 
-  // Set new length.
-  int new_length = len + args.length() - 1;
+  int new_length = len + to_add;
   FixedArray* elms = FixedArray::cast(array->elements());
 
-  if (new_length <= elms->length()) {
-    // Backing storage has extra space for the provided values.
-    for (int index = 0; index < args.length() - 1; index++) {
-      elms->set(index + len, args[index+1]);
-    }
-  } else {
+  if (new_length > elms->length()) {
     // New backing storage is needed.
     int capacity = new_length + (new_length >> 1) + 16;
     Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
@@ -291,16 +269,21 @@
     WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc);
     // Fill out the new array with old elements.
     for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode);
-    // Add the provided values.
-    for (int index = 0; index < args.length() - 1; index++) {
-      new_elms->set(index + len, args[index+1], mode);
-    }
-    // Set the new backing storage.
-    array->set_elements(new_elms);
+    elms = new_elms;
+    array->set_elements(elms);
   }
+
+  AssertNoAllocation no_gc;
+  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
+
+  // Add the provided values.
+  for (int index = 0; index < to_add; index++) {
+    elms->set(index + len, args[index + 1], mode);
+  }
+
   // Set the length.
   array->set_length(Smi::FromInt(new_length));
-  return array->length();
+  return Smi::FromInt(new_length);
 }
 
 
@@ -335,6 +318,355 @@
 }
 
 
+static Object* GetElementToMove(uint32_t index,
+                                FixedArray* elms,
+                                JSObject* prototype) {
+  Object* e = elms->get(index);
+  if (e->IsTheHole() && prototype->HasElement(index)) {
+    e = prototype->GetElement(index);
+  }
+  return e;
+}
+
+
+BUILTIN(ArrayShift) {
+  JSArray* array = JSArray::cast(*args.receiver());
+  ASSERT(array->HasFastElements());
+
+  int len = Smi::cast(array->length())->value();
+  if (len == 0) return Heap::undefined_value();
+
+  // Fetch the prototype.
+  JSFunction* array_function =
+      Top::context()->global_context()->array_function();
+  JSObject* prototype = JSObject::cast(array_function->prototype());
+
+  FixedArray* elms = FixedArray::cast(array->elements());
+
+  // Get first element
+  Object* first = elms->get(0);
+  if (first->IsTheHole()) {
+    first = prototype->GetElement(0);
+  }
+
+  // Shift the elements.
+  for (int i = 0; i < len - 1; i++) {
+    elms->set(i, GetElementToMove(i + 1, elms, prototype));
+  }
+  elms->set(len - 1, Heap::the_hole_value());
+
+  // Set the length.
+  array->set_length(Smi::FromInt(len - 1));
+
+  return first;
+}
+
+
+BUILTIN(ArrayUnshift) {
+  JSArray* array = JSArray::cast(*args.receiver());
+  ASSERT(array->HasFastElements());
+
+  int len = Smi::cast(array->length())->value();
+  int to_add = args.length() - 1;
+  // Note that we cannot quit early if to_add == 0 as
+  // values should be lifted from prototype into
+  // the array.
+
+  int new_length = len + to_add;
+  // Currently fixed arrays cannot grow too big, so
+  // we should never hit this case.
+  ASSERT(to_add <= (Smi::kMaxValue - len));
+
+  FixedArray* elms = FixedArray::cast(array->elements());
+
+  // Fetch the prototype.
+  JSFunction* array_function =
+      Top::context()->global_context()->array_function();
+  JSObject* prototype = JSObject::cast(array_function->prototype());
+
+  if (new_length > elms->length()) {
+    // New backing storage is needed.
+    int capacity = new_length + (new_length >> 1) + 16;
+    Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
+    if (obj->IsFailure()) return obj;
+
+    AssertNoAllocation no_gc;
+    FixedArray* new_elms = FixedArray::cast(obj);
+    WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc);
+    // Fill out the new array with old elements.
+    for (int i = 0; i < len; i++)
+      new_elms->set(to_add + i,
+                    GetElementToMove(i, elms, prototype),
+                    mode);
+
+    elms = new_elms;
+    array->set_elements(elms);
+  } else {
+    AssertNoAllocation no_gc;
+    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
+
+    // Move elements to the right
+    for (int i = 0; i < len; i++) {
+      elms->set(new_length - i - 1,
+                GetElementToMove(len - i - 1, elms, prototype),
+                mode);
+    }
+  }
+
+  // Add the provided values.
+  AssertNoAllocation no_gc;
+  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
+  for (int i = 0; i < to_add; i++) {
+    elms->set(i, args[i + 1], mode);
+  }
+
+  // Set the length.
+  array->set_length(Smi::FromInt(new_length));
+  return Smi::FromInt(new_length);
+}
+
+
+static Object* CallJsBuiltin(const char* name,
+                             BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
+  HandleScope handleScope;
+
+  Handle<Object> js_builtin =
+      GetProperty(Handle<JSObject>(Top::global_context()->builtins()),
+                  name);
+  ASSERT(js_builtin->IsJSFunction());
+  Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin));
+  Vector<Object**> argv(Vector<Object**>::New(args.length() - 1));
+  int n_args = args.length() - 1;
+  for (int i = 0; i < n_args; i++) {
+    argv[i] = &args[i + 1];
+  }
+  bool pending_exception = false;
+  Handle<Object> result = Execution::Call(function,
+                                          args.receiver(),
+                                          n_args,
+                                          argv.start(),
+                                          &pending_exception);
+  if (pending_exception) return Failure::Exception();
+  return *result;
+}
+
+
+BUILTIN(ArraySlice) {
+  JSArray* array = JSArray::cast(*args.receiver());
+  ASSERT(array->HasFastElements());
+
+  int len = Smi::cast(array->length())->value();
+
+  int n_arguments = args.length() - 1;
+
+  // Note carefully choosen defaults---if argument is missing,
+  // it's undefined which gets converted to 0 for relativeStart
+  // and to len for relativeEnd.
+  int relativeStart = 0;
+  int relativeEnd = len;
+  if (n_arguments > 0) {
+    Object* arg1 = args[1];
+    if (arg1->IsSmi()) {
+      relativeStart = Smi::cast(arg1)->value();
+    } else if (!arg1->IsUndefined()) {
+      return CallJsBuiltin("ArraySlice", args);
+    }
+    if (n_arguments > 1) {
+      Object* arg2 = args[2];
+      if (arg2->IsSmi()) {
+        relativeEnd = Smi::cast(arg2)->value();
+      } else if (!arg2->IsUndefined()) {
+        return CallJsBuiltin("ArraySlice", args);
+      }
+    }
+  }
+
+  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
+  int k = (relativeStart < 0) ? Max(len + relativeStart, 0)
+                              : Min(relativeStart, len);
+
+  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
+  int final = (relativeEnd < 0) ? Max(len + relativeEnd, 0)
+                                : Min(relativeEnd, len);
+
+  // Calculate the length of result array.
+  int result_len = final - k;
+  if (result_len < 0) {
+    result_len = 0;
+  }
+
+  JSFunction* array_function =
+      Top::context()->global_context()->array_function();
+  Object* result = Heap::AllocateJSObject(array_function);
+  if (result->IsFailure()) return result;
+  JSArray* result_array = JSArray::cast(result);
+
+  result = Heap::AllocateFixedArrayWithHoles(result_len);
+  if (result->IsFailure()) return result;
+  FixedArray* result_elms = FixedArray::cast(result);
+
+  FixedArray* elms = FixedArray::cast(array->elements());
+
+  // Fetch the prototype.
+  JSObject* prototype = JSObject::cast(array_function->prototype());
+
+  AssertNoAllocation no_gc;
+  WriteBarrierMode mode = result_elms->GetWriteBarrierMode(no_gc);
+
+  // Fill newly created array.
+  for (int i = 0; i < result_len; i++) {
+    result_elms->set(i,
+                     GetElementToMove(k + i, elms, prototype),
+                     mode);
+  }
+
+  // Set elements.
+  result_array->set_elements(result_elms);
+
+  // Set the length.
+  result_array->set_length(Smi::FromInt(result_len));
+  return result_array;
+}
+
+
+BUILTIN(ArraySplice) {
+  JSArray* array = JSArray::cast(*args.receiver());
+  ASSERT(array->HasFastElements());
+
+  int len = Smi::cast(array->length())->value();
+
+  int n_arguments = args.length() - 1;
+
+  // SpiderMonkey and JSC return undefined in the case where no
+  // arguments are given instead of using the implicit undefined
+  // arguments.  This does not follow ECMA-262, but we do the same for
+  // compatibility.
+  // TraceMonkey follows ECMA-262 though.
+  if (n_arguments == 0) {
+    return Heap::undefined_value();
+  }
+
+  int relativeStart = 0;
+  Object* arg1 = args[1];
+  if (arg1->IsSmi()) {
+    relativeStart = Smi::cast(arg1)->value();
+  } else if (!arg1->IsUndefined()) {
+    return CallJsBuiltin("ArraySplice", args);
+  }
+  int actualStart = (relativeStart < 0) ? Max(len + relativeStart, 0)
+                                        : Min(relativeStart, len);
+
+  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+  // given differently from when an undefined delete count is given.
+  // This does not follow ECMA-262, but we do the same for
+  // compatibility.
+  int deleteCount = len;
+  if (n_arguments > 1) {
+    Object* arg2 = args[2];
+    if (arg2->IsSmi()) {
+      deleteCount = Smi::cast(arg2)->value();
+    } else {
+      return CallJsBuiltin("ArraySplice", args);
+    }
+  }
+  int actualDeleteCount = Min(Max(deleteCount, 0), len - actualStart);
+
+  JSFunction* array_function =
+      Top::context()->global_context()->array_function();
+
+  // Allocate result array.
+  Object* result = Heap::AllocateJSObject(array_function);
+  if (result->IsFailure()) return result;
+  JSArray* result_array = JSArray::cast(result);
+
+  result = Heap::AllocateFixedArrayWithHoles(actualDeleteCount);
+  if (result->IsFailure()) return result;
+  FixedArray* result_elms = FixedArray::cast(result);
+
+  FixedArray* elms = FixedArray::cast(array->elements());
+
+  // Fetch the prototype.
+  JSObject* prototype = JSObject::cast(array_function->prototype());
+
+  AssertNoAllocation no_gc;
+  WriteBarrierMode mode = result_elms->GetWriteBarrierMode(no_gc);
+
+  // Fill newly created array.
+  for (int k = 0; k < actualDeleteCount; k++) {
+    result_elms->set(k,
+                     GetElementToMove(actualStart + k, elms, prototype),
+                     mode);
+  }
+
+  // Set elements.
+  result_array->set_elements(result_elms);
+
+  // Set the length.
+  result_array->set_length(Smi::FromInt(actualDeleteCount));
+
+  int itemCount = (n_arguments > 1) ? (n_arguments - 2) : 0;
+
+  int new_length = len - actualDeleteCount + itemCount;
+
+  mode = elms->GetWriteBarrierMode(no_gc);
+  if (itemCount < actualDeleteCount) {
+    // Shrink the array.
+    for (int k = actualStart; k < (len - actualDeleteCount); k++) {
+      elms->set(k + itemCount,
+                GetElementToMove(k + actualDeleteCount, elms, prototype),
+                mode);
+    }
+
+    for (int k = len; k > new_length; k--) {
+      elms->set(k - 1, Heap::the_hole_value());
+    }
+  } else if (itemCount > actualDeleteCount) {
+    // Currently fixed arrays cannot grow too big, so
+    // we should never hit this case.
+    ASSERT((itemCount - actualDeleteCount) <= (Smi::kMaxValue - len));
+
+    FixedArray* source_elms = elms;
+
+    // Check if array need to grow.
+    if (new_length > elms->length()) {
+      // New backing storage is needed.
+      int capacity = new_length + (new_length >> 1) + 16;
+      Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
+      if (obj->IsFailure()) return obj;
+
+      FixedArray* new_elms = FixedArray::cast(obj);
+      mode = new_elms->GetWriteBarrierMode(no_gc);
+
+      // Copy the part before actualStart as is.
+      for (int k = 0; k < actualStart; k++) {
+        new_elms->set(k, elms->get(k), mode);
+      }
+
+      source_elms = elms;
+      elms = new_elms;
+      array->set_elements(elms);
+    }
+
+    for (int k = len - actualDeleteCount; k > actualStart; k--) {
+      elms->set(k + itemCount - 1,
+                GetElementToMove(k + actualDeleteCount - 1,
+                                 source_elms,
+                                 prototype),
+                mode);
+    }
+  }
+
+  for (int k = actualStart; k < actualStart + itemCount; k++) {
+    elms->set(k, args[3 + k - actualStart], mode);
+  }
+
+  // Set the length.
+  array->set_length(Smi::FromInt(new_length));
+
+  return result_array;
+}
+
+
 // -----------------------------------------------------------------------------
 //
 
@@ -474,6 +806,76 @@
 }
 
 
+#ifdef DEBUG
+
+static void VerifyTypeCheck(Handle<JSObject> object,
+                            Handle<JSFunction> function) {
+  FunctionTemplateInfo* info =
+      FunctionTemplateInfo::cast(function->shared()->function_data());
+  if (info->signature()->IsUndefined()) return;
+  SignatureInfo* signature = SignatureInfo::cast(info->signature());
+  Object* receiver_type = signature->receiver();
+  if (receiver_type->IsUndefined()) return;
+  FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type);
+  ASSERT(object->IsInstanceOf(type));
+}
+
+#endif
+
+
+BUILTIN(FastHandleApiCall) {
+  ASSERT(!CalledAsConstructor());
+  const bool is_construct = false;
+
+  // We expect four more arguments: function, callback, call data, and holder.
+  const int args_length = args.length() - 4;
+  ASSERT(args_length >= 0);
+
+  Handle<JSFunction> function = args.at<JSFunction>(args_length);
+  Object* callback_obj = args[args_length + 1];
+  Handle<Object> data_handle = args.at<Object>(args_length + 2);
+  Handle<JSObject> checked_holder = args.at<JSObject>(args_length + 3);
+
+#ifdef DEBUG
+  VerifyTypeCheck(checked_holder, function);
+#endif
+
+  v8::Local<v8::Object> holder = v8::Utils::ToLocal(checked_holder);
+  v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
+  v8::InvocationCallback callback =
+      v8::ToCData<v8::InvocationCallback>(callback_obj);
+  v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
+
+  v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
+      data,
+      holder,
+      callee,
+      is_construct,
+      reinterpret_cast<void**>(&args[0] - 1),
+      args_length - 1);
+
+  HandleScope scope;
+  Object* result;
+  v8::Handle<v8::Value> value;
+  {
+    // Leaving JavaScript.
+    VMState state(EXTERNAL);
+#ifdef ENABLE_LOGGING_AND_PROFILING
+    state.set_external_callback(v8::ToCData<Address>(callback_obj));
+#endif
+    value = callback(new_args);
+  }
+  if (value.IsEmpty()) {
+    result = Heap::undefined_value();
+  } else {
+    result = *reinterpret_cast<Object**>(*value);
+  }
+
+  RETURN_IF_SCHEDULED_EXCEPTION();
+  return result;
+}
+
+
 // Helper function to handle calls to non-function objects created through the
 // API. The object can be called as either a constructor (using new) or just as
 // a function (without new).
@@ -657,6 +1059,10 @@
   KeyedLoadIC::GeneratePreMonomorphic(masm);
 }
 
+static void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) {
+  KeyedLoadIC::GenerateIndexedInterceptor(masm);
+}
+
 
 static void Generate_StoreIC_Initialize(MacroAssembler* masm) {
   StoreIC::GenerateInitialize(masm);
@@ -668,10 +1074,6 @@
 }
 
 
-static void Generate_StoreIC_ExtendStorage(MacroAssembler* masm) {
-  StoreIC::GenerateExtendStorage(masm);
-}
-
 static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
   StoreIC::GenerateMegamorphic(masm);
 }
@@ -720,11 +1122,6 @@
 }
 
 
-static void Generate_KeyedStoreIC_ExtendStorage(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateExtendStorage(masm);
-}
-
-
 static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
   KeyedStoreIC::GenerateMiss(masm);
 }
@@ -869,9 +1266,6 @@
           v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
         }
       }
-      // Add any unresolved jumps or calls to the fixup list in the
-      // bootstrapper.
-      Bootstrapper::AddFixup(Code::cast(code), &masm);
       // Log the event and add the code to the builtins array.
       LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
                           Code::cast(code), functions[i].s_name));
diff --git a/src/builtins.h b/src/builtins.h
index 418948f..13322c2 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -48,8 +48,13 @@
                                                                     \
   V(ArrayPush, NO_EXTRA_ARGUMENTS)                                  \
   V(ArrayPop, NO_EXTRA_ARGUMENTS)                                   \
+  V(ArrayShift, NO_EXTRA_ARGUMENTS)                                 \
+  V(ArrayUnshift, NO_EXTRA_ARGUMENTS)                               \
+  V(ArraySlice, NO_EXTRA_ARGUMENTS)                                 \
+  V(ArraySplice, NO_EXTRA_ARGUMENTS)                                \
                                                                     \
   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                           \
+  V(FastHandleApiCall, NO_EXTRA_ARGUMENTS)                          \
   V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION)                  \
   V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS)                    \
   V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS)
@@ -69,9 +74,6 @@
   V(StoreIC_Miss,               BUILTIN, UNINITIALIZED)                   \
   V(KeyedStoreIC_Miss,          BUILTIN, UNINITIALIZED)                   \
                                                                           \
-  V(StoreIC_ExtendStorage,      BUILTIN, UNINITIALIZED)                   \
-  V(KeyedStoreIC_ExtendStorage, BUILTIN, UNINITIALIZED)                   \
-                                                                          \
   V(LoadIC_Initialize,          LOAD_IC, UNINITIALIZED)                   \
   V(LoadIC_PreMonomorphic,      LOAD_IC, PREMONOMORPHIC)                  \
   V(LoadIC_Normal,              LOAD_IC, MONOMORPHIC)                     \
@@ -91,6 +93,7 @@
   V(KeyedLoadIC_ExternalIntArray,           KEYED_LOAD_IC, MEGAMORPHIC)   \
   V(KeyedLoadIC_ExternalUnsignedIntArray,   KEYED_LOAD_IC, MEGAMORPHIC)   \
   V(KeyedLoadIC_ExternalFloatArray,         KEYED_LOAD_IC, MEGAMORPHIC)   \
+  V(KeyedLoadIC_IndexedInterceptor,         KEYED_LOAD_IC, MEGAMORPHIC)   \
                                                                           \
   V(StoreIC_Initialize,         STORE_IC, UNINITIALIZED)                  \
   V(StoreIC_Megamorphic,        STORE_IC, MEGAMORPHIC)                    \
diff --git a/src/checks.h b/src/checks.h
index 3b0c851..eeb748b 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -125,7 +125,9 @@
                                      const char* expected,
                                      const char* value_source,
                                      const char* value) {
-  if (strcmp(expected, value) != 0) {
+  if ((expected == NULL && value != NULL) ||
+      (expected != NULL && value == NULL) ||
+      (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
     V8_Fatal(file, line,
              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
              expected_source, value_source, expected, value);
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 95f0760..4d0fd29 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -31,6 +31,7 @@
 #include "code-stubs.h"
 #include "factory.h"
 #include "macro-assembler.h"
+#include "oprofile-agent.h"
 
 namespace v8 {
 namespace internal {
@@ -60,8 +61,12 @@
 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
   code->set_major_key(MajorKey());
 
-  // Add unresolved entries in the code to the fixup list.
-  Bootstrapper::AddFixup(code, masm);
+#ifdef ENABLE_OPROFILE_AGENT
+  // Register the generated stub with the OPROFILE agent.
+  OProfileAgent::CreateNativeCodeRegion(GetName(),
+                                        code->instruction_start(),
+                                        code->instruction_size());
+#endif
 
   LOG(CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
   Counters::total_stubs_code_size.Increment(code->instruction_size());
diff --git a/src/code-stubs.h b/src/code-stubs.h
index d502f14..d5189c2 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -48,6 +48,7 @@
   V(FastNewClosure)                      \
   V(FastNewContext)                      \
   V(FastCloneShallowArray)               \
+  V(TranscendentalCache)                 \
   V(GenericUnaryOp)                      \
   V(RevertToNumber)                      \
   V(ToBoolean)                           \
@@ -55,6 +56,7 @@
   V(CounterOp)                           \
   V(ArgumentsAccess)                     \
   V(RegExpExec)                          \
+  V(NumberToString)                      \
   V(CEntry)                              \
   V(JSEntry)                             \
   V(DebuggerStatement)
diff --git a/src/codegen.cc b/src/codegen.cc
index 24eb476..bc722bb 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -31,6 +31,7 @@
 #include "codegen-inl.h"
 #include "compiler.h"
 #include "debug.h"
+#include "liveedit.h"
 #include "oprofile-agent.h"
 #include "prettyprinter.h"
 #include "register-allocator-inl.h"
@@ -197,9 +198,6 @@
   Handle<Code> code =
       Factory::NewCode(desc, &sinfo, flags, masm->CodeObject());
 
-  // Add unresolved entries in the code to the fixup list.
-  Bootstrapper::AddFixup(*code, masm);
-
 #ifdef ENABLE_DISASSEMBLER
   bool print_code = Bootstrapper::IsActive()
       ? FLAG_print_builtin_code
@@ -237,6 +235,7 @@
 // all the pieces into a Code object. This function is only to be called by
 // the compiler.cc code.
 Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
+  LiveEditFunctionTracker live_edit_tracker(info->function());
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
@@ -248,7 +247,8 @@
   MacroAssembler masm(NULL, kInitialBufferSize);
   CodeGenerator cgen(&masm);
   CodeGeneratorScope scope(&cgen);
-  cgen.Generate(info, PRIMARY);
+  live_edit_tracker.RecordFunctionScope(info->function()->scope());
+  cgen.Generate(info);
   if (cgen.HasStackOverflow()) {
     ASSERT(!Top::has_pending_exception());
     return Handle<Code>::null();
@@ -256,7 +256,9 @@
 
   InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_IN_LOOP;
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
-  return MakeCodeEpilogue(cgen.masm(), flags, info);
+  Handle<Code> result = MakeCodeEpilogue(cgen.masm(), flags, info);
+  live_edit_tracker.RecordFunctionCode(result);
+  return result;
 }
 
 
@@ -358,6 +360,7 @@
   {&CodeGenerator::GenerateIsSmi, "_IsSmi"},
   {&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"},
   {&CodeGenerator::GenerateIsArray, "_IsArray"},
+  {&CodeGenerator::GenerateIsRegExp, "_IsRegExp"},
   {&CodeGenerator::GenerateIsConstructCall, "_IsConstructCall"},
   {&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"},
   {&CodeGenerator::GenerateArgumentsAccess, "_Arguments"},
@@ -375,6 +378,9 @@
   {&CodeGenerator::GenerateSubString, "_SubString"},
   {&CodeGenerator::GenerateStringCompare, "_StringCompare"},
   {&CodeGenerator::GenerateRegExpExec, "_RegExpExec"},
+  {&CodeGenerator::GenerateNumberToString, "_NumberToString"},
+  {&CodeGenerator::GenerateMathSin, "_Math_sin"},
+  {&CodeGenerator::GenerateMathCos, "_Math_cos"},
 };
 
 
@@ -525,12 +531,5 @@
   info()->set_load_stub_cache(value);
 }
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
-void DebuggerStatementStub::Generate(MacroAssembler* masm) {
-  Runtime::Function* f = Runtime::FunctionForId(Runtime::kDebugBreak);
-  masm->TailCallRuntime(ExternalReference(f), 0, f->result_size);
-}
-#endif
-
 
 } }  // namespace v8::internal
diff --git a/src/codegen.h b/src/codegen.h
index 3afa041..8dcde84 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -31,6 +31,7 @@
 #include "ast.h"
 #include "code-stubs.h"
 #include "runtime.h"
+#include "number-info.h"
 
 // Include the declaration of the architecture defined class CodeGenerator.
 // The contract  to the shared code is that the the CodeGenerator is a subclass
@@ -415,21 +416,6 @@
 };
 
 
-// Mark the debugger statement to be recognized by debugger (by the MajorKey)
-class DebuggerStatementStub : public CodeStub {
- public:
-  DebuggerStatementStub() { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Major MajorKey() { return DebuggerStatement; }
-  int MinorKey() { return 0; }
-
-  const char* GetName() { return "DebuggerStatementStub"; }
-};
-
-
 class JSEntryStub : public CodeStub {
  public:
   JSEntryStub() { }
@@ -532,14 +518,14 @@
   }
 #endif
 
-  // Minor key encoding in 31 bits AAAAAAAAAAAAAAAAAAAAAFI A(rgs)F(lag)I(nloop).
+  // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
   class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
   class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
-  class ArgcBits: public BitField<int, 2, 29> {};
+  class ArgcBits: public BitField<int, 2, 32 - 2> {};
 
   Major MajorKey() { return CallFunction; }
   int MinorKey() {
-    // Encode the parameters in a unique 31 bit value.
+    // Encode the parameters in a unique 32 bit value.
     return InLoopBits::encode(in_loop_)
            | FlagBits::encode(flags_)
            | ArgcBits::encode(argc_);
diff --git a/src/compiler.cc b/src/compiler.cc
index 6556d37..7b6734a 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -38,6 +38,7 @@
 #include "rewriter.h"
 #include "scopes.h"
 #include "usage-analyzer.h"
+#include "liveedit.h"
 
 namespace v8 {
 namespace internal {
@@ -238,6 +239,7 @@
                                      int line_offset, int column_offset,
                                      v8::Extension* extension,
                                      ScriptDataImpl* input_pre_data,
+                                     Handle<Object> script_data,
                                      NativesFlag natives) {
   int source_length = source->length();
   Counters::total_load_size.Increment(source_length);
@@ -275,6 +277,9 @@
       script->set_column_offset(Smi::FromInt(column_offset));
     }
 
+    script->set_data(script_data.is_null() ? Heap::undefined_value()
+                                           : *script_data);
+
     // Compile the function and add it to the cache.
     result = MakeFunction(true,
                           false,
@@ -429,7 +434,8 @@
   // compiled. These builtins cannot be handled lazily by the parser,
   // since we have to know if a function uses the special natives
   // syntax, which is something the parser records.
-  bool allow_lazy = literal->AllowsLazyCompilation();
+  bool allow_lazy = literal->AllowsLazyCompilation() &&
+      !LiveEditFunctionTracker::IsActive();
 
   // Generate code
   Handle<Code> code;
diff --git a/src/compiler.h b/src/compiler.h
index 88f4479..f972ac9 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -28,8 +28,10 @@
 #ifndef V8_COMPILER_H_
 #define V8_COMPILER_H_
 
+#include "ast.h"
 #include "frame-element.h"
 #include "parser.h"
+#include "register-allocator.h"
 #include "zone.h"
 
 namespace v8 {
@@ -39,6 +41,37 @@
 // is constructed based on the resources available at compile-time.
 class CompilationInfo BASE_EMBEDDED {
  public:
+  // Compilation mode.  Either the compiler is used as the primary
+  // compiler and needs to setup everything or the compiler is used as
+  // the secondary compiler for split compilation and has to handle
+  // bailouts.
+  enum Mode {
+    PRIMARY,
+    SECONDARY
+  };
+
+  // A description of the compilation state at a bailout to the secondary
+  // code generator.
+  //
+  // The state is currently simple: there are no parameters or local
+  // variables to worry about ('this' can be found in the stack frame).
+  // There are at most two live values.
+  //
+  // There is a label that should be bound to the beginning of the bailout
+  // stub code.
+  class Bailout : public ZoneObject {
+   public:
+    Bailout(Register left, Register right) : left_(left), right_(right) {}
+
+    Label* label() { return &label_; }
+
+   private:
+    Register left_;
+    Register right_;
+    Label label_;
+  };
+
+
   // Lazy compilation of a JSFunction.
   CompilationInfo(Handle<JSFunction> closure,
                   int loop_nesting,
@@ -115,9 +148,13 @@
   int loop_nesting() { return loop_nesting_; }
   bool has_receiver() { return !receiver_.is_null(); }
   Handle<Object> receiver() { return receiver_; }
+  List<Bailout*>* bailouts() { return &bailouts_; }
 
-  // Accessors for mutable fields, possibly set by analysis passes with
+  // Accessors for mutable fields (possibly set by analysis passes) with
   // default values given by Initialize.
+  Mode mode() { return mode_; }
+  void set_mode(Mode mode) { mode_ = mode; }
+
   bool has_this_properties() { return has_this_properties_; }
   void set_has_this_properties(bool flag) { has_this_properties_ = flag; }
 
@@ -135,8 +172,19 @@
   // Derived accessors.
   Scope* scope() { return function()->scope(); }
 
+  // Add a bailout with two live values.
+  Label* AddBailout(Register left, Register right) {
+    Bailout* bailout = new Bailout(left, right);
+    bailouts_.Add(bailout);
+    return bailout->label();
+  }
+
+  // Add a bailout with no live values.
+  Label* AddBailout() { return AddBailout(no_reg, no_reg); }
+
  private:
   void Initialize() {
+    mode_ = PRIMARY;
     has_this_properties_ = false;
     has_globals_ = false;
   }
@@ -146,6 +194,7 @@
   Handle<Script> script_;
 
   FunctionLiteral* function_;
+  Mode mode_;
 
   bool is_eval_;
   int loop_nesting_;
@@ -155,6 +204,10 @@
   bool has_this_properties_;
   bool has_globals_;
 
+  // An ordered list of bailout points encountered during fast-path
+  // compilation.
+  List<Bailout*> bailouts_;
+
   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
 };
 
@@ -183,7 +236,8 @@
                                     Handle<Object> script_name,
                                     int line_offset, int column_offset,
                                     v8::Extension* extension,
-                                    ScriptDataImpl* script_Data,
+                                    ScriptDataImpl* pre_data,
+                                    Handle<Object> script_data,
                                     NativesFlag is_natives_code);
 
   // Compile a String source within a context for Eval.
diff --git a/src/contexts.h b/src/contexts.h
index 3feb6ce..2453db7 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -76,7 +76,6 @@
   V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
   V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \
   V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \
-  V(TO_BOOLEAN_FUN_INDEX, JSFunction, to_boolean_fun) \
   V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
   V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun) \
   V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun) \
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 34b7b60..67fc9ef 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -27,8 +27,8 @@
 
 
 #include <cstdio>  // NOLINT
-#include <readline/readline.h>
-#include <readline/history.h>
+#include <readline/readline.h> // NOLINT
+#include <readline/history.h> // NOLINT
 
 
 #include "d8.h"
diff --git a/src/data-flow.cc b/src/data-flow.cc
index 22ec66f..5e9d217 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -199,15 +199,11 @@
 void AstLabeler::VisitAssignment(Assignment* expr) {
   Property* prop = expr->target()->AsProperty();
   ASSERT(prop != NULL);
-  if (prop != NULL) {
-    ASSERT(prop->key()->IsPropertyName());
-    VariableProxy* proxy = prop->obj()->AsVariableProxy();
-    if (proxy != NULL && proxy->var()->is_this()) {
-      info()->set_has_this_properties(true);
-    } else {
-      Visit(prop->obj());
-    }
-  }
+  ASSERT(prop->key()->IsPropertyName());
+  VariableProxy* proxy = prop->obj()->AsVariableProxy();
+  USE(proxy);
+  ASSERT(proxy != NULL && proxy->var()->is_this());
+  info()->set_has_this_properties(true);
   Visit(expr->value());
   expr->set_num(next_number_++);
 }
@@ -219,7 +215,12 @@
 
 
 void AstLabeler::VisitProperty(Property* expr) {
-  UNREACHABLE();
+  ASSERT(expr->key()->IsPropertyName());
+  VariableProxy* proxy = expr->obj()->AsVariableProxy();
+  USE(proxy);
+  ASSERT(proxy != NULL && proxy->var()->is_this());
+  info()->set_has_this_properties(true);
+  expr->set_num(next_number_++);
 }
 
 
@@ -269,4 +270,292 @@
   UNREACHABLE();
 }
 
+
+ZoneList<Expression*>* VarUseMap::Lookup(Variable* var) {
+  HashMap::Entry* entry = HashMap::Lookup(var, var->name()->Hash(), true);
+  if (entry->value == NULL) {
+    entry->value = new ZoneList<Expression*>(1);
+  }
+  return reinterpret_cast<ZoneList<Expression*>*>(entry->value);
+}
+
+
+void LivenessAnalyzer::Analyze(FunctionLiteral* fun) {
+  // Process the function body.
+  VisitStatements(fun->body());
+
+  // All variables are implicitly defined at the function start.
+  // Record a definition of all variables live at function entry.
+  for (HashMap::Entry* p = live_vars_.Start();
+       p != NULL;
+       p = live_vars_.Next(p)) {
+    Variable* var = reinterpret_cast<Variable*>(p->key);
+    RecordDef(var, fun);
+  }
+}
+
+
+void LivenessAnalyzer::VisitStatements(ZoneList<Statement*>* stmts) {
+  // Visit statements right-to-left.
+  for (int i = stmts->length() - 1; i >= 0; i--) {
+    Visit(stmts->at(i));
+  }
+}
+
+
+void LivenessAnalyzer::RecordUse(Variable* var, Expression* expr) {
+  ASSERT(var->is_global() || var->is_this());
+  ZoneList<Expression*>* uses = live_vars_.Lookup(var);
+  uses->Add(expr);
+}
+
+
+void LivenessAnalyzer::RecordDef(Variable* var, Expression* expr) {
+  ASSERT(var->is_global() || var->is_this());
+
+  // We do not support other expressions that can define variables.
+  ASSERT(expr->AsFunctionLiteral() != NULL);
+
+  // Add the variable to the list of defined variables.
+  if (expr->defined_vars() == NULL) {
+    expr->set_defined_vars(new ZoneList<DefinitionInfo*>(1));
+  }
+  DefinitionInfo* def = new DefinitionInfo();
+  expr->AsFunctionLiteral()->defined_vars()->Add(def);
+
+  // Compute the last use of the definition. The variable uses are
+  // inserted in reversed evaluation order. The first element
+  // in the list of live uses is the last use.
+  ZoneList<Expression*>* uses = live_vars_.Lookup(var);
+  while (uses->length() > 0) {
+    Expression* use_site = uses->RemoveLast();
+    use_site->set_var_def(def);
+    if (uses->length() == 0) {
+      def->set_last_use(use_site);
+    }
+  }
+}
+
+
+// Visitor functions for live variable analysis.
+void LivenessAnalyzer::VisitDeclaration(Declaration* decl) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitBlock(Block* stmt) {
+  VisitStatements(stmt->statements());
+}
+
+
+void LivenessAnalyzer::VisitExpressionStatement(
+    ExpressionStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void LivenessAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) {
+  // Do nothing.
+}
+
+
+void LivenessAnalyzer::VisitIfStatement(IfStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitContinueStatement(ContinueStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitBreakStatement(BreakStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitReturnStatement(ReturnStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitWithEnterStatement(
+    WithEnterStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitWithExitStatement(WithExitStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitWhileStatement(WhileStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitForStatement(ForStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitForInStatement(ForInStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitTryCatchStatement(TryCatchStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitTryFinallyStatement(
+    TryFinallyStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitDebuggerStatement(
+    DebuggerStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitFunctionBoilerplateLiteral(
+    FunctionBoilerplateLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitConditional(Conditional* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitSlot(Slot* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitVariableProxy(VariableProxy* expr) {
+  Variable* var = expr->var();
+  ASSERT(var->is_global());
+  ASSERT(!var->is_this());
+  RecordUse(var, expr);
+}
+
+
+void LivenessAnalyzer::VisitLiteral(Literal* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitCatchExtensionObject(
+    CatchExtensionObject* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitAssignment(Assignment* expr) {
+  Property* prop = expr->target()->AsProperty();
+  ASSERT(prop != NULL);
+  ASSERT(prop->key()->IsPropertyName());
+  VariableProxy* proxy = prop->obj()->AsVariableProxy();
+  ASSERT(proxy != NULL && proxy->var()->is_this());
+
+  // Record use of this at the assignment node. Assignments to
+  // this-properties are treated like unary operations.
+  RecordUse(proxy->var(), expr);
+
+  // Visit right-hand side.
+  Visit(expr->value());
+}
+
+
+void LivenessAnalyzer::VisitThrow(Throw* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitProperty(Property* expr) {
+  ASSERT(expr->key()->IsPropertyName());
+  VariableProxy* proxy = expr->obj()->AsVariableProxy();
+  ASSERT(proxy != NULL && proxy->var()->is_this());
+  RecordUse(proxy->var(), expr);
+}
+
+
+void LivenessAnalyzer::VisitCall(Call* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitCallNew(CallNew* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitCallRuntime(CallRuntime* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitCountOperation(CountOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
+  // Visit child nodes in reverse evaluation order.
+  Visit(expr->right());
+  Visit(expr->left());
+}
+
+
+void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) {
+  UNREACHABLE();
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/data-flow.h b/src/data-flow.h
index 7c16d5d..2331944 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -62,6 +62,56 @@
 };
 
 
+class VarUseMap : public HashMap {
+ public:
+  VarUseMap() : HashMap(VarMatch) {}
+
+  ZoneList<Expression*>* Lookup(Variable* var);
+
+ private:
+  static bool VarMatch(void* key1, void* key2) { return key1 == key2; }
+};
+
+
+class DefinitionInfo : public ZoneObject {
+ public:
+  explicit DefinitionInfo() : last_use_(NULL) {}
+
+  Expression* last_use() { return last_use_; }
+  void set_last_use(Expression* expr) { last_use_ = expr; }
+
+ private:
+  Expression* last_use_;
+  Register location_;
+};
+
+
+class LivenessAnalyzer : public AstVisitor {
+ public:
+  LivenessAnalyzer() {}
+
+  void Analyze(FunctionLiteral* fun);
+
+ private:
+  void VisitStatements(ZoneList<Statement*>* stmts);
+
+  void RecordUse(Variable* var, Expression* expr);
+  void RecordDef(Variable* var, Expression* expr);
+
+
+  // AST node visit functions.
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+  AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+  // Map for tracking the live variables.
+  VarUseMap live_vars_;
+
+  DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer);
+};
+
+
 } }  // namespace v8::internal
 
+
 #endif  // V8_DATAFLOW_H_
diff --git a/src/date-delay.js b/src/date-delay.js
deleted file mode 100644
index 7d8f458..0000000
--- a/src/date-delay.js
+++ /dev/null
@@ -1,1138 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// This file relies on the fact that the following declarations have been made
-// in v8natives.js:
-// const $isFinite = GlobalIsFinite;
-
-// -------------------------------------------------------------------
-
-// This file contains date support implemented in JavaScript.
-
-
-// Keep reference to original values of some global properties.  This
-// has the added benefit that the code in this file is isolated from
-// changes to these properties.
-const $Date = global.Date;
-
-// Helper function to throw error.
-function ThrowDateTypeError() {
-  throw new $TypeError('this is not a Date object.');
-}
-
-// ECMA 262 - 5.2
-function Modulo(value, remainder) {
-  var mod = value % remainder;
-  // Guard against returning -0.
-  if (mod == 0) return 0;
-  return mod >= 0 ? mod : mod + remainder;
-}
-
-
-function TimeWithinDay(time) {
-  return Modulo(time, msPerDay);
-}
-
-
-// ECMA 262 - 15.9.1.3
-function DaysInYear(year) {
-  if (year % 4 != 0) return 365;
-  if ((year % 100 == 0) && (year % 400 != 0)) return 365;
-  return 366;
-}
-
-
-function DayFromYear(year) {
-  return 365 * (year-1970)
-      + FLOOR((year-1969)/4)
-      - FLOOR((year-1901)/100)
-      + FLOOR((year-1601)/400);
-}
-
-
-function TimeFromYear(year) {
-  return msPerDay * DayFromYear(year);
-}
-
-
-function InLeapYear(time) {
-  return DaysInYear(YEAR_FROM_TIME(time)) == 366 ? 1 : 0;
-}
-
-
-function DayWithinYear(time) {
-  return DAY(time) - DayFromYear(YEAR_FROM_TIME(time));
-}
-
-
-// ECMA 262 - 15.9.1.9
-function EquivalentYear(year) {
-  // Returns an equivalent year in the range [2008-2035] matching
-  // - leap year.
-  // - week day of first day.
-  var time = TimeFromYear(year);
-  var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) +
-      (WeekDay(time) * 12) % 28;
-  // Find the year in the range 2008..2037 that is equivalent mod 28.
-  // Add 3*28 to give a positive argument to the modulus operator.
-  return 2008 + (recent_year + 3*28 - 2008) % 28;
-}
-
-
-function EquivalentTime(t) {
-  // The issue here is that some library calls don't work right for dates
-  // that cannot be represented using a non-negative signed 32 bit integer
-  // (measured in whole seconds based on the 1970 epoch).
-  // We solve this by mapping the time to a year with same leap-year-ness
-  // and same starting day for the year.  The ECMAscript specification says
-  // we must do this, but for compatibility with other browsers, we use
-  // the actual year if it is in the range 1970..2037
-  if (t >= 0 && t <= 2.1e12) return t;
-  var day = MakeDay(EquivalentYear(YEAR_FROM_TIME(t)), MONTH_FROM_TIME(t), DATE_FROM_TIME(t));
-  return TimeClip(MakeDate(day, TimeWithinDay(t)));
-}
-
-
-// Because computing the DST offset is a pretty expensive operation
-// we keep a cache of last computed offset along with a time interval
-// where we know the cache is valid.
-var DST_offset_cache = {
-  // Cached DST offset.
-  offset: 0,
-  // Time interval where the cached offset is valid.
-  start: 0, end: -1,
-  // Size of next interval expansion.
-  increment: 0
-};
-
-
-// NOTE: The implementation relies on the fact that no time zones have
-// more than one daylight savings offset change per month.
-// If this function is called with NaN it returns NaN.
-function DaylightSavingsOffset(t) {
-  // Load the cache object from the builtins object.
-  var cache = DST_offset_cache;
-
-  // Cache the start and the end in local variables for fast access.
-  var start = cache.start;
-  var end = cache.end;
-
-  if (start <= t) {
-    // If the time fits in the cached interval, return the cached offset.
-    if (t <= end) return cache.offset;
-
-    // Compute a possible new interval end.
-    var new_end = end + cache.increment;
-
-    if (t <= new_end) {
-      var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end));
-      if (cache.offset == end_offset) {
-        // If the offset at the end of the new interval still matches
-        // the offset in the cache, we grow the cached time interval
-        // and return the offset.
-        cache.end = new_end;
-        cache.increment = msPerMonth;
-        return end_offset;
-      } else {
-        var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
-        if (offset == end_offset) {
-          // The offset at the given time is equal to the offset at the
-          // new end of the interval, so that means that we've just skipped
-          // the point in time where the DST offset change occurred. Updated
-          // the interval to reflect this and reset the increment.
-          cache.start = t;
-          cache.end = new_end;
-          cache.increment = msPerMonth;
-        } else {
-          // The interval contains a DST offset change and the given time is
-          // before it. Adjust the increment to avoid a linear search for
-          // the offset change point and change the end of the interval.
-          cache.increment /= 3;
-          cache.end = t;
-        }
-        // Update the offset in the cache and return it.
-        cache.offset = offset;
-        return offset;
-      }
-    }
-  }
-
-  // Compute the DST offset for the time and shrink the cache interval
-  // to only contain the time. This allows fast repeated DST offset
-  // computations for the same time.
-  var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
-  cache.offset = offset;
-  cache.start = cache.end = t;
-  cache.increment = msPerMonth;
-  return offset;
-}
-
-
-var timezone_cache_time = $NaN;
-var timezone_cache_timezone;
-
-function LocalTimezone(t) {
-  if (NUMBER_IS_NAN(t)) return "";
-  if (t == timezone_cache_time) {
-    return timezone_cache_timezone;
-  }
-  var timezone = %DateLocalTimezone(EquivalentTime(t));
-  timezone_cache_time = t;
-  timezone_cache_timezone = timezone;
-  return timezone;
-}
-
-
-function WeekDay(time) {
-  return Modulo(DAY(time) + 4, 7);
-}
-
-var local_time_offset = %DateLocalTimeOffset();
-
-function LocalTime(time) {
-  if (NUMBER_IS_NAN(time)) return time;
-  return time + local_time_offset + DaylightSavingsOffset(time);
-}
-
-function LocalTimeNoCheck(time) {
-  // Inline the DST offset cache checks for speed.
-  var cache = DST_offset_cache;
-  if (cache.start <= time && time <= cache.end) {
-    var dst_offset = cache.offset;
-  } else {
-    var dst_offset = DaylightSavingsOffset(time);
-  }
-  return time + local_time_offset + dst_offset;
-}
-
-
-function UTC(time) {
-  if (NUMBER_IS_NAN(time)) return time;
-  var tmp = time - local_time_offset;
-  return tmp - DaylightSavingsOffset(tmp);
-}
-
-
-// ECMA 262 - 15.9.1.11
-function MakeTime(hour, min, sec, ms) {
-  if (!$isFinite(hour)) return $NaN;
-  if (!$isFinite(min)) return $NaN;
-  if (!$isFinite(sec)) return $NaN;
-  if (!$isFinite(ms)) return $NaN;
-  return TO_INTEGER(hour) * msPerHour
-      + TO_INTEGER(min) * msPerMinute
-      + TO_INTEGER(sec) * msPerSecond
-      + TO_INTEGER(ms);
-}
-
-
-// ECMA 262 - 15.9.1.12
-function TimeInYear(year) {
-  return DaysInYear(year) * msPerDay;
-}
-
-
-// Compute modified Julian day from year, month, date.
-function ToJulianDay(year, month, date) {
-  var jy = (month > 1) ? year : year - 1;
-  var jm = (month > 1) ? month + 2 : month + 14;
-  var ja = FLOOR(jy / 100);
-  return FLOOR(FLOOR(365.25*jy) + FLOOR(30.6001*jm) + date + 1720995) + 2 - ja + FLOOR(0.25*ja);
-}
-
-var four_year_cycle_table = CalculateDateTable();
-
-
-function CalculateDateTable() {
-  var month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-  var four_year_cycle_table = new $Array(1461);
-
-  var cumulative = 0;
-  var position = 0;
-  var leap_position = 0;
-  for (var month = 0; month < 12; month++) {
-    var month_bits = month << kMonthShift;
-    var length = month_lengths[month];
-    for (var day = 1; day <= length; day++) {
-      four_year_cycle_table[leap_position] =
-        month_bits + day;
-      four_year_cycle_table[366 + position] =
-        (1 << kYearShift) + month_bits + day;
-      four_year_cycle_table[731 + position] =
-        (2 << kYearShift) + month_bits + day;
-      four_year_cycle_table[1096 + position] =
-        (3 << kYearShift) + month_bits + day;
-      leap_position++;
-      position++;
-    }
-    if (month == 1) {
-      four_year_cycle_table[leap_position++] = month_bits + 29;
-    }
-  }
-  return four_year_cycle_table;
-}
-
-
-// Constructor for creating objects holding year, month, and date.
-// Introduced to ensure the two return points in FromJulianDay match same map.
-function DayTriplet(year, month, date) {
-  this.year = year;
-  this.month = month;
-  this.date = date;
-}
-
-var julian_day_cache_triplet;
-var julian_day_cache_day = $NaN;
-
-// Compute year, month, and day from modified Julian day.
-// The missing days in 1582 are ignored for JavaScript compatibility.
-function FromJulianDay(julian) {
-  if (julian_day_cache_day == julian) {
-    return julian_day_cache_triplet;
-  }
-  var result;
-  // Avoid floating point and non-Smi maths in common case.  This is also a period of
-  // time where leap years are very regular.  The range is not too large to avoid overflow
-  // when doing the multiply-to-divide trick.
-  if (julian > kDayZeroInJulianDay &&
-      (julian - kDayZeroInJulianDay) < 40177) { // 1970 - 2080
-    var jsimple = (julian - kDayZeroInJulianDay) + 731; // Day 0 is 1st January 1968
-    var y = 1968;
-    // Divide by 1461 by multiplying with 22967 and shifting down by 25!
-    var after_1968 = (jsimple * 22967) >> 25;
-    y += after_1968 << 2;
-    jsimple -= 1461 * after_1968;
-    var four_year_cycle = four_year_cycle_table[jsimple];
-    result = new DayTriplet(y + (four_year_cycle >> kYearShift),
-                            (four_year_cycle & kMonthMask) >> kMonthShift,
-                            four_year_cycle & kDayMask);
-  } else {
-    var jalpha = FLOOR((julian - 1867216.25) / 36524.25);
-    var jb = julian + 1 + jalpha - FLOOR(0.25 * jalpha) + 1524;
-    var jc = FLOOR(6680.0 + ((jb-2439870) - 122.1)/365.25);
-    var jd = FLOOR(365 * jc + (0.25 * jc));
-    var je = FLOOR((jb - jd)/30.6001);
-    var m = je - 1;
-    if (m > 12) m -= 13;
-    var y = jc - 4715;
-    if (m > 2) { --y; --m; }
-    var d = jb - jd - FLOOR(30.6001 * je);
-    result = new DayTriplet(y, m, d);
-  }
-  julian_day_cache_day = julian;
-  julian_day_cache_triplet = result;
-  return result;
-}
-
-
-// Compute number of days given a year, month, date.
-// Note that month and date can lie outside the normal range.
-//   For example:
-//     MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
-//     MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
-//     MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
-function MakeDay(year, month, date) {
-  if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
-
-  // Conversion to integers.
-  year = TO_INTEGER(year);
-  month = TO_INTEGER(month);
-  date = TO_INTEGER(date);
-
-  // Overflow months into year.
-  year = year + FLOOR(month/12);
-  month = month % 12;
-  if (month < 0) {
-    month += 12;
-  }
-
-  // Return days relative to Jan 1 1970.
-  return ToJulianDay(year, month, date) - kDayZeroInJulianDay;
-}
-
-
-// ECMA 262 - 15.9.1.13
-function MakeDate(day, time) {
-  if (!$isFinite(day)) return $NaN;
-  if (!$isFinite(time)) return $NaN;
-  return day * msPerDay + time;
-}
-
-
-// ECMA 262 - 15.9.1.14
-function TimeClip(time) {
-  if (!$isFinite(time)) return $NaN;
-  if ($abs(time) > 8.64E15) return $NaN;
-  return TO_INTEGER(time);
-}
-
-
-// The Date cache is used to limit the cost of parsing the same Date
-// strings over and over again.
-var Date_cache = {
-  // Cached time value.
-  time: $NaN,
-  // Cached year when interpreting the time as a local time. Only
-  // valid when the time matches cached time.
-  year: $NaN,
-  // String input for which the cached time is valid.
-  string: null
-};
-
-
-%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
-  if (!%_IsConstructCall()) {
-    // ECMA 262 - 15.9.2
-    return (new $Date()).toString();
-  }
-
-  // ECMA 262 - 15.9.3
-  var argc = %_ArgumentsLength();
-  var value;
-  if (argc == 0) {
-    value = %DateCurrentTime();
-
-  } else if (argc == 1) {
-    if (IS_NUMBER(year)) {
-      value = TimeClip(year);
-
-    } else if (IS_STRING(year)) {
-      // Probe the Date cache. If we already have a time value for the
-      // given time, we re-use that instead of parsing the string again.
-      var cache = Date_cache;
-      if (cache.string === year) {
-        value = cache.time;
-      } else {
-        value = DateParse(year);
-        if (!NUMBER_IS_NAN(value)) {
-          cache.time = value;
-          cache.year = YEAR_FROM_TIME(LocalTimeNoCheck(value));
-          cache.string = year;
-        }
-      }
-
-    } else {
-      // According to ECMA 262, no hint should be given for this
-      // conversion. However, ToPrimitive defaults to STRING_HINT for
-      // Date objects which will lose precision when the Date
-      // constructor is called with another Date object as its
-      // argument. We therefore use NUMBER_HINT for the conversion,
-      // which is the default for everything else than Date objects.
-      // This makes us behave like KJS and SpiderMonkey.
-      var time = ToPrimitive(year, NUMBER_HINT);
-      value = IS_STRING(time) ? DateParse(time) : TimeClip(ToNumber(time));
-    }
-
-  } else {
-    year = ToNumber(year);
-    month = ToNumber(month);
-    date = argc > 2 ? ToNumber(date) : 1;
-    hours = argc > 3 ? ToNumber(hours) : 0;
-    minutes = argc > 4 ? ToNumber(minutes) : 0;
-    seconds = argc > 5 ? ToNumber(seconds) : 0;
-    ms = argc > 6 ? ToNumber(ms) : 0;
-    year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
-        ? 1900 + TO_INTEGER(year) : year;
-    var day = MakeDay(year, month, date);
-    var time = MakeTime(hours, minutes, seconds, ms);
-    value = TimeClip(UTC(MakeDate(day, time)));
-  }
-  %_SetValueOf(this, value);
-});
-
-
-// Helper functions.
-function GetTimeFrom(aDate) {
-  return DATE_VALUE(aDate);
-}
-
-function GetMillisecondsFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MS_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCMillisecondsFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MS_FROM_TIME(t);
-}
-
-
-function GetSecondsFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return SEC_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCSecondsFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return SEC_FROM_TIME(t);
-}
-
-
-function GetMinutesFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MIN_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCMinutesFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MIN_FROM_TIME(t);
-}
-
-
-function GetHoursFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return HOUR_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCHoursFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return HOUR_FROM_TIME(t);
-}
-
-
-function GetFullYearFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  var cache = Date_cache;
-  if (cache.time === t) return cache.year;
-  return YEAR_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCFullYearFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return YEAR_FROM_TIME(t);
-}
-
-
-function GetMonthFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MONTH_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCMonthFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return MONTH_FROM_TIME(t);
-}
-
-
-function GetDateFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return DATE_FROM_TIME(LocalTimeNoCheck(t));
-}
-
-
-function GetUTCDateFrom(aDate) {
-  var t = DATE_VALUE(aDate);
-  if (NUMBER_IS_NAN(t)) return t;
-  return DATE_FROM_TIME(t);
-}
-
-
-%FunctionSetPrototype($Date, new $Date($NaN));
-
-
-var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
-var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
-
-
-function TwoDigitString(value) {
-  return value < 10 ? "0" + value : "" + value;
-}
-
-
-function DateString(time) {
-  var YMD = FromJulianDay(DAY(time) + kDayZeroInJulianDay);
-  return WeekDays[WeekDay(time)] + ' '
-      + Months[YMD.month] + ' '
-      + TwoDigitString(YMD.date) + ' '
-      + YMD.year;
-}
-
-
-var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
-var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
-
-
-function LongDateString(time) {
-  var YMD = FromJulianDay(DAY(time) + kDayZeroInJulianDay);
-  return LongWeekDays[WeekDay(time)] + ', '
-      + LongMonths[YMD.month] + ' '
-      + TwoDigitString(YMD.date) + ', '
-      + YMD.year;
-}
-
-
-function TimeString(time) {
-  return TwoDigitString(HOUR_FROM_TIME(time)) + ':'
-      + TwoDigitString(MIN_FROM_TIME(time)) + ':'
-      + TwoDigitString(SEC_FROM_TIME(time));
-}
-
-
-function LocalTimezoneString(time) {
-  var timezoneOffset =
-      (local_time_offset + DaylightSavingsOffset(time)) / msPerMinute;
-  var sign = (timezoneOffset >= 0) ? 1 : -1;
-  var hours = FLOOR((sign * timezoneOffset)/60);
-  var min   = FLOOR((sign * timezoneOffset)%60);
-  var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
-      TwoDigitString(hours) + TwoDigitString(min);
-  return gmt + ' (' +  LocalTimezone(time) + ')';
-}
-
-
-function DatePrintString(time) {
-  return DateString(time) + ' ' + TimeString(time);
-}
-
-// -------------------------------------------------------------------
-
-// Reused output buffer. Used when parsing date strings.
-var parse_buffer = $Array(7);
-
-// ECMA 262 - 15.9.4.2
-function DateParse(string) {
-  var arr = %DateParseString(ToString(string), parse_buffer);
-  if (IS_NULL(arr)) return $NaN;
-
-  var day = MakeDay(arr[0], arr[1], arr[2]);
-  var time = MakeTime(arr[3], arr[4], arr[5], 0);
-  var date = MakeDate(day, time);
-
-  if (IS_NULL(arr[6])) {
-    return TimeClip(UTC(date));
-  } else {
-    return TimeClip(date - arr[6] * 1000);
-  }
-}
-
-
-// ECMA 262 - 15.9.4.3
-function DateUTC(year, month, date, hours, minutes, seconds, ms) {
-  year = ToNumber(year);
-  month = ToNumber(month);
-  var argc = %_ArgumentsLength();
-  date = argc > 2 ? ToNumber(date) : 1;
-  hours = argc > 3 ? ToNumber(hours) : 0;
-  minutes = argc > 4 ? ToNumber(minutes) : 0;
-  seconds = argc > 5 ? ToNumber(seconds) : 0;
-  ms = argc > 6 ? ToNumber(ms) : 0;
-  year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
-      ? 1900 + TO_INTEGER(year) : year;
-  var day = MakeDay(year, month, date);
-  var time = MakeTime(hours, minutes, seconds, ms);
-  return %_SetValueOf(this, TimeClip(MakeDate(day, time)));
-}
-
-
-// Mozilla-specific extension. Returns the number of milliseconds
-// elapsed since 1 January 1970 00:00:00 UTC.
-function DateNow() {
-  return %DateCurrentTime();
-}
-
-
-// ECMA 262 - 15.9.5.2
-function DateToString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  return DatePrintString(LocalTimeNoCheck(t)) + LocalTimezoneString(t);
-}
-
-
-// ECMA 262 - 15.9.5.3
-function DateToDateString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  return DateString(LocalTimeNoCheck(t));
-}
-
-
-// ECMA 262 - 15.9.5.4
-function DateToTimeString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  var lt = LocalTimeNoCheck(t);
-  return TimeString(lt) + LocalTimezoneString(lt);
-}
-
-
-// ECMA 262 - 15.9.5.5
-function DateToLocaleString() {
-  return DateToString.call(this);
-}
-
-
-// ECMA 262 - 15.9.5.6
-function DateToLocaleDateString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  return LongDateString(LocalTimeNoCheck(t));
-}
-
-
-// ECMA 262 - 15.9.5.7
-function DateToLocaleTimeString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  var lt = LocalTimeNoCheck(t);
-  return TimeString(lt);
-}
-
-
-// ECMA 262 - 15.9.5.8
-function DateValueOf() {
-  return DATE_VALUE(this);
-}
-
-
-// ECMA 262 - 15.9.5.9
-function DateGetTime() {
-  return DATE_VALUE(this);
-}
-
-
-// ECMA 262 - 15.9.5.10
-function DateGetFullYear() {
-  return GetFullYearFrom(this)
-}
-
-
-// ECMA 262 - 15.9.5.11
-function DateGetUTCFullYear() {
-  return GetUTCFullYearFrom(this)
-}
-
-
-// ECMA 262 - 15.9.5.12
-function DateGetMonth() {
-  return GetMonthFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.13
-function DateGetUTCMonth() {
-  return GetUTCMonthFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.14
-function DateGetDate() {
-  return GetDateFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.15
-function DateGetUTCDate() {
-  return GetUTCDateFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.16
-function DateGetDay() {
-  var t = %_ValueOf(this);
-  if (NUMBER_IS_NAN(t)) return t;
-  return WeekDay(LocalTimeNoCheck(t));
-}
-
-
-// ECMA 262 - 15.9.5.17
-function DateGetUTCDay() {
-  var t = %_ValueOf(this);
-  if (NUMBER_IS_NAN(t)) return t;
-  return WeekDay(t);
-}
-
-
-// ECMA 262 - 15.9.5.18
-function DateGetHours() {
-  return GetHoursFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.19
-function DateGetUTCHours() {
-  return GetUTCHoursFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.20
-function DateGetMinutes() {
-  return GetMinutesFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.21
-function DateGetUTCMinutes() {
-  return GetUTCMinutesFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.22
-function DateGetSeconds() {
-  return GetSecondsFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.23
-function DateGetUTCSeconds() {
-  return GetUTCSecondsFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.24
-function DateGetMilliseconds() {
-  return GetMillisecondsFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.25
-function DateGetUTCMilliseconds() {
-  return GetUTCMillisecondsFrom(this);
-}
-
-
-// ECMA 262 - 15.9.5.26
-function DateGetTimezoneOffset() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return t;
-  return (t - LocalTimeNoCheck(t)) / msPerMinute;
-}
-
-
-// ECMA 262 - 15.9.5.27
-function DateSetTime(ms) {
-  if (!IS_DATE(this)) ThrowDateTypeError();
-  return %_SetValueOf(this, TimeClip(ToNumber(ms)));
-}
-
-
-// ECMA 262 - 15.9.5.28
-function DateSetMilliseconds(ms) {
-  var t = LocalTime(DATE_VALUE(this));
-  ms = ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
-}
-
-
-// ECMA 262 - 15.9.5.29
-function DateSetUTCMilliseconds(ms) {
-  var t = DATE_VALUE(this);
-  ms = ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms);
-  return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
-}
-
-
-// ECMA 262 - 15.9.5.30
-function DateSetSeconds(sec, ms) {
-  var t = LocalTime(DATE_VALUE(this));
-  sec = ToNumber(sec);
-  ms = %_ArgumentsLength() < 2 ? GetMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
-}
-
-
-// ECMA 262 - 15.9.5.31
-function DateSetUTCSeconds(sec, ms) {
-  var t = DATE_VALUE(this);
-  sec = ToNumber(sec);
-  ms = %_ArgumentsLength() < 2 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
-  return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
-}
-
-
-// ECMA 262 - 15.9.5.33
-function DateSetMinutes(min, sec, ms) {
-  var t = LocalTime(DATE_VALUE(this));
-  min = ToNumber(min);
-  var argc = %_ArgumentsLength();
-  sec = argc < 2 ? GetSecondsFrom(this) : ToNumber(sec);
-  ms = argc < 3 ? GetMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
-}
-
-
-// ECMA 262 - 15.9.5.34
-function DateSetUTCMinutes(min, sec, ms) {
-  var t = DATE_VALUE(this);
-  min = ToNumber(min);
-  var argc = %_ArgumentsLength();
-  sec = argc < 2 ? GetUTCSecondsFrom(this) : ToNumber(sec);
-  ms = argc < 3 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
-  return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
-}
-
-
-// ECMA 262 - 15.9.5.35
-function DateSetHours(hour, min, sec, ms) {
-  var t = LocalTime(DATE_VALUE(this));
-  hour = ToNumber(hour);
-  var argc = %_ArgumentsLength();
-  min = argc < 2 ? GetMinutesFrom(this) : ToNumber(min);
-  sec = argc < 3 ? GetSecondsFrom(this) : ToNumber(sec);
-  ms = argc < 4 ? GetMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(hour, min, sec, ms);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
-}
-
-
-// ECMA 262 - 15.9.5.34
-function DateSetUTCHours(hour, min, sec, ms) {
-  var t = DATE_VALUE(this);
-  hour = ToNumber(hour);
-  var argc = %_ArgumentsLength();
-  min = argc < 2 ? GetUTCMinutesFrom(this) : ToNumber(min);
-  sec = argc < 3 ? GetUTCSecondsFrom(this) : ToNumber(sec);
-  ms = argc < 4 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
-  var time = MakeTime(hour, min, sec, ms);
-  return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
-}
-
-
-// ECMA 262 - 15.9.5.36
-function DateSetDate(date) {
-  var t = LocalTime(DATE_VALUE(this));
-  date = ToNumber(date);
-  var day = MakeDay(YEAR_FROM_TIME(t), MONTH_FROM_TIME(t), date);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-}
-
-
-// ECMA 262 - 15.9.5.37
-function DateSetUTCDate(date) {
-  var t = DATE_VALUE(this);
-  date = ToNumber(date);
-  var day = MakeDay(YEAR_FROM_TIME(t), MONTH_FROM_TIME(t), date);
-  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-}
-
-
-// ECMA 262 - 15.9.5.38
-function DateSetMonth(month, date) {
-  var t = LocalTime(DATE_VALUE(this));
-  month = ToNumber(month);
-  date = %_ArgumentsLength() < 2 ? GetDateFrom(this) : ToNumber(date);
-  var day = MakeDay(YEAR_FROM_TIME(t), month, date);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-}
-
-
-// ECMA 262 - 15.9.5.39
-function DateSetUTCMonth(month, date) {
-  var t = DATE_VALUE(this);
-  month = ToNumber(month);
-  date = %_ArgumentsLength() < 2 ? GetUTCDateFrom(this) : ToNumber(date);
-  var day = MakeDay(YEAR_FROM_TIME(t), month, date);
-  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-}
-
-
-// ECMA 262 - 15.9.5.40
-function DateSetFullYear(year, month, date) {
-  var t = DATE_VALUE(this);
-  t = NUMBER_IS_NAN(t) ? 0 : LocalTimeNoCheck(t);
-  year = ToNumber(year);
-  var argc = %_ArgumentsLength();
-  month = argc < 2 ? MONTH_FROM_TIME(t) : ToNumber(month);
-  date = argc < 3 ? DATE_FROM_TIME(t) : ToNumber(date);
-  var day = MakeDay(year, month, date);
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-}
-
-
-// ECMA 262 - 15.9.5.41
-function DateSetUTCFullYear(year, month, date) {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) t = 0;
-  var argc = %_ArgumentsLength();
-  year = ToNumber(year);
-  month = argc < 2 ? MONTH_FROM_TIME(t) : ToNumber(month);
-  date = argc < 3 ? DATE_FROM_TIME(t) : ToNumber(date);
-  var day = MakeDay(year, month, date);
-  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-}
-
-
-// ECMA 262 - 15.9.5.42
-function DateToUTCString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
-  return WeekDays[WeekDay(t)] + ', '
-      + TwoDigitString(DATE_FROM_TIME(t)) + ' '
-      + Months[MONTH_FROM_TIME(t)] + ' '
-      + YEAR_FROM_TIME(t) + ' '
-      + TimeString(t) + ' GMT';
-}
-
-
-// ECMA 262 - B.2.4
-function DateGetYear() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return $NaN;
-  return YEAR_FROM_TIME(LocalTimeNoCheck(t)) - 1900;
-}
-
-
-// ECMA 262 - B.2.5
-function DateSetYear(year) {
-  var t = LocalTime(DATE_VALUE(this));
-  if (NUMBER_IS_NAN(t)) t = 0;
-  year = ToNumber(year);
-  if (NUMBER_IS_NAN(year)) return %_SetValueOf(this, $NaN);
-  year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
-      ? 1900 + TO_INTEGER(year) : year;
-  var day = MakeDay(year, MONTH_FROM_TIME(t), DATE_FROM_TIME(t));
-  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-}
-
-
-// ECMA 262 - B.2.6
-//
-// Notice that this does not follow ECMA 262 completely.  ECMA 262
-// says that toGMTString should be the same Function object as
-// toUTCString.  JSC does not do this, so for compatibility we do not
-// do that either.  Instead, we create a new function whose name
-// property will return toGMTString.
-function DateToGMTString() {
-  return DateToUTCString.call(this);
-}
-
-
-function PadInt(n, digits) {
-  if (digits == 1) return n;
-  return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
-}
-
-
-function DateToISOString() {
-  var t = DATE_VALUE(this);
-  if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  return this.getUTCFullYear() + '-' + PadInt(this.getUTCMonth() + 1, 2) +
-      '-' + PadInt(this.getUTCDate(), 2) + 'T' + PadInt(this.getUTCHours(), 2) +
-      ':' + PadInt(this.getUTCMinutes(), 2) + ':' + PadInt(this.getUTCSeconds(), 2) +
-      '.' + PadInt(this.getUTCMilliseconds(), 3) +
-      'Z';
-}
-
-
-function DateToJSON(key) {
-  return CheckJSONPrimitive(this.toISOString());
-}
-
-
-// -------------------------------------------------------------------
-
-function SetupDate() {
-  // Setup non-enumerable properties of the Date object itself.
-  InstallFunctions($Date, DONT_ENUM, $Array(
-    "UTC", DateUTC,
-    "parse", DateParse,
-    "now", DateNow
-  ));
-
-  // Setup non-enumerable constructor property of the Date prototype object.
-  %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
-
-  // Setup non-enumerable functions of the Date prototype object and
-  // set their names.
-  InstallFunctionsOnHiddenPrototype($Date.prototype, DONT_ENUM, $Array(
-    "toString", DateToString,
-    "toDateString", DateToDateString,
-    "toTimeString", DateToTimeString,
-    "toLocaleString", DateToLocaleString,
-    "toLocaleDateString", DateToLocaleDateString,
-    "toLocaleTimeString", DateToLocaleTimeString,
-    "valueOf", DateValueOf,
-    "getTime", DateGetTime,
-    "getFullYear", DateGetFullYear,
-    "getUTCFullYear", DateGetUTCFullYear,
-    "getMonth", DateGetMonth,
-    "getUTCMonth", DateGetUTCMonth,
-    "getDate", DateGetDate,
-    "getUTCDate", DateGetUTCDate,
-    "getDay", DateGetDay,
-    "getUTCDay", DateGetUTCDay,
-    "getHours", DateGetHours,
-    "getUTCHours", DateGetUTCHours,
-    "getMinutes", DateGetMinutes,
-    "getUTCMinutes", DateGetUTCMinutes,
-    "getSeconds", DateGetSeconds,
-    "getUTCSeconds", DateGetUTCSeconds,
-    "getMilliseconds", DateGetMilliseconds,
-    "getUTCMilliseconds", DateGetUTCMilliseconds,
-    "getTimezoneOffset", DateGetTimezoneOffset,
-    "setTime", DateSetTime,
-    "setMilliseconds", DateSetMilliseconds,
-    "setUTCMilliseconds", DateSetUTCMilliseconds,
-    "setSeconds", DateSetSeconds,
-    "setUTCSeconds", DateSetUTCSeconds,
-    "setMinutes", DateSetMinutes,
-    "setUTCMinutes", DateSetUTCMinutes,
-    "setHours", DateSetHours,
-    "setUTCHours", DateSetUTCHours,
-    "setDate", DateSetDate,
-    "setUTCDate", DateSetUTCDate,
-    "setMonth", DateSetMonth,
-    "setUTCMonth", DateSetUTCMonth,
-    "setFullYear", DateSetFullYear,
-    "setUTCFullYear", DateSetUTCFullYear,
-    "toGMTString", DateToGMTString,
-    "toUTCString", DateToUTCString,
-    "getYear", DateGetYear,
-    "setYear", DateSetYear,
-    "toISOString", DateToISOString,
-    "toJSON", DateToJSON
-  ));
-}
-
-SetupDate();
diff --git a/src/date.js b/src/date.js
index 2ffd006..7d8f458 100644
--- a/src/date.js
+++ b/src/date.js
@@ -730,8 +730,7 @@
 
 
 // ECMA 262 - 15.9.5.9
-function DateGetTime(logMarker) {
-  if (logMarker) %ProfileLogMarker(logMarker);
+function DateGetTime() {
   return DATE_VALUE(this);
 }
 
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 14d8c88..55c25a9 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -1202,11 +1202,16 @@
         throw new Error('Command not specified');
       }
 
-      // TODO(yurys): remove request.arguments.compactFormat check once
-      // ChromeDevTools are switched to 'inlineRefs'
-      if (request.arguments && (request.arguments.inlineRefs ||
-                                request.arguments.compactFormat)) {
-        response.setOption('inlineRefs', true);
+      if (request.arguments) {
+        var args = request.arguments;
+        // TODO(yurys): remove request.arguments.compactFormat check once
+        // ChromeDevTools are switched to 'inlineRefs'
+        if (args.inlineRefs || args.compactFormat) {
+          response.setOption('inlineRefs', true);
+        }
+        if (!IS_UNDEFINED(args.maxStringLength)) {
+          response.setOption('maxStringLength', args.maxStringLength);
+        }
       }
 
       if (request.command == 'continue') {
@@ -1934,10 +1939,14 @@
   if (isNaN(modules)) {
     return response.failed('Modules is not an integer');
   }
+  var tag = parseInt(request.arguments.tag);
+  if (isNaN(tag)) {
+    tag = 0;
+  }
   if (request.arguments.command == 'resume') {
-    %ProfilerResume(modules);
+    %ProfilerResume(modules, tag);
   } else if (request.arguments.command == 'pause') {
-    %ProfilerPause(modules);
+    %ProfilerPause(modules, tag);
   } else {
     return response.failed('Unknown command');
   }
diff --git a/src/debug-delay.js b/src/debug-delay.js
deleted file mode 100644
index 14d8c88..0000000
--- a/src/debug-delay.js
+++ /dev/null
@@ -1,2073 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Default number of frames to include in the response to backtrace request.
-const kDefaultBacktraceLength = 10;
-
-const Debug = {};
-
-// Regular expression to skip "crud" at the beginning of a source line which is
-// not really code. Currently the regular expression matches whitespace and
-// comments.
-const sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
-
-// Debug events which can occour in the V8 JavaScript engine. These originate
-// from the API include file debug.h.
-Debug.DebugEvent = { Break: 1,
-                     Exception: 2,
-                     NewFunction: 3,
-                     BeforeCompile: 4,
-                     AfterCompile: 5,
-                     ScriptCollected: 6 };
-
-// Types of exceptions that can be broken upon.
-Debug.ExceptionBreak = { All : 0,
-                         Uncaught: 1 };
-
-// The different types of steps.
-Debug.StepAction = { StepOut: 0,
-                     StepNext: 1,
-                     StepIn: 2,
-                     StepMin: 3,
-                     StepInMin: 4 };
-
-// The different types of scripts matching enum ScriptType in objects.h.
-Debug.ScriptType = { Native: 0,
-                     Extension: 1,
-                     Normal: 2 };
-
-// The different types of script compilations matching enum
-// Script::CompilationType in objects.h.
-Debug.ScriptCompilationType = { Host: 0,
-                                Eval: 1,
-                                JSON: 2 };
-
-// The different script break point types.
-Debug.ScriptBreakPointType = { ScriptId: 0,
-                               ScriptName: 1 };
-
-function ScriptTypeFlag(type) {
-  return (1 << type);
-}
-
-// Globals.
-var next_response_seq = 0;
-var next_break_point_number = 1;
-var break_points = [];
-var script_break_points = [];
-
-
-// Create a new break point object and add it to the list of break points.
-function MakeBreakPoint(source_position, opt_line, opt_column, opt_script_break_point) {
-  var break_point = new BreakPoint(source_position, opt_line, opt_column, opt_script_break_point);
-  break_points.push(break_point);
-  return break_point;
-}
-
-
-// Object representing a break point.
-// NOTE: This object does not have a reference to the function having break
-// point as this would cause function not to be garbage collected when it is
-// not used any more. We do not want break points to keep functions alive.
-function BreakPoint(source_position, opt_line, opt_column, opt_script_break_point) {
-  this.source_position_ = source_position;
-  this.source_line_ = opt_line;
-  this.source_column_ = opt_column;
-  if (opt_script_break_point) {
-    this.script_break_point_ = opt_script_break_point;
-  } else {
-    this.number_ = next_break_point_number++;
-  }
-  this.hit_count_ = 0;
-  this.active_ = true;
-  this.condition_ = null;
-  this.ignoreCount_ = 0;
-}
-
-
-BreakPoint.prototype.number = function() {
-  return this.number_;
-};
-
-
-BreakPoint.prototype.func = function() {
-  return this.func_;
-};
-
-
-BreakPoint.prototype.source_position = function() {
-  return this.source_position_;
-};
-
-
-BreakPoint.prototype.hit_count = function() {
-  return this.hit_count_;
-};
-
-
-BreakPoint.prototype.active = function() {
-  if (this.script_break_point()) {
-    return this.script_break_point().active();
-  }
-  return this.active_;
-};
-
-
-BreakPoint.prototype.condition = function() {
-  if (this.script_break_point() && this.script_break_point().condition()) {
-    return this.script_break_point().condition();
-  }
-  return this.condition_;
-};
-
-
-BreakPoint.prototype.ignoreCount = function() {
-  return this.ignoreCount_;
-};
-
-
-BreakPoint.prototype.script_break_point = function() {
-  return this.script_break_point_;
-};
-
-
-BreakPoint.prototype.enable = function() {
-  this.active_ = true;
-};
-
-
-BreakPoint.prototype.disable = function() {
-  this.active_ = false;
-};
-
-
-BreakPoint.prototype.setCondition = function(condition) {
-  this.condition_ = condition;
-};
-
-
-BreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
-  this.ignoreCount_ = ignoreCount;
-};
-
-
-BreakPoint.prototype.isTriggered = function(exec_state) {
-  // Break point not active - not triggered.
-  if (!this.active()) return false;
-
-  // Check for conditional break point.
-  if (this.condition()) {
-    // If break point has condition try to evaluate it in the top frame.
-    try {
-      var mirror = exec_state.frame(0).evaluate(this.condition());
-      // If no sensible mirror or non true value break point not triggered.
-      if (!(mirror instanceof ValueMirror) || !%ToBoolean(mirror.value_)) {
-        return false;
-      }
-    } catch (e) {
-      // Exception evaluating condition counts as not triggered.
-      return false;
-    }
-  }
-
-  // Update the hit count.
-  this.hit_count_++;
-  if (this.script_break_point_) {
-    this.script_break_point_.hit_count_++;
-  }
-
-  // If the break point has an ignore count it is not triggered.
-  if (this.ignoreCount_ > 0) {
-    this.ignoreCount_--;
-    return false;
-  }
-
-  // Break point triggered.
-  return true;
-};
-
-
-// Function called from the runtime when a break point is hit. Returns true if
-// the break point is triggered and supposed to break execution.
-function IsBreakPointTriggered(break_id, break_point) {
-  return break_point.isTriggered(MakeExecutionState(break_id));
-}
-
-
-// Object representing a script break point. The script is referenced by its
-// script name or script id and the break point is represented as line and
-// column.
-function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                          opt_groupId) {
-  this.type_ = type;
-  if (type == Debug.ScriptBreakPointType.ScriptId) {
-    this.script_id_ = script_id_or_name;
-  } else {  // type == Debug.ScriptBreakPointType.ScriptName
-    this.script_name_ = script_id_or_name;
-  }
-  this.line_ = opt_line || 0;
-  this.column_ = opt_column;
-  this.groupId_ = opt_groupId;
-  this.hit_count_ = 0;
-  this.active_ = true;
-  this.condition_ = null;
-  this.ignoreCount_ = 0;
-}
-
-
-ScriptBreakPoint.prototype.number = function() {
-  return this.number_;
-};
-
-
-ScriptBreakPoint.prototype.groupId = function() {
-  return this.groupId_;
-};
-
-
-ScriptBreakPoint.prototype.type = function() {
-  return this.type_;
-};
-
-
-ScriptBreakPoint.prototype.script_id = function() {
-  return this.script_id_;
-};
-
-
-ScriptBreakPoint.prototype.script_name = function() {
-  return this.script_name_;
-};
-
-
-ScriptBreakPoint.prototype.line = function() {
-  return this.line_;
-};
-
-
-ScriptBreakPoint.prototype.column = function() {
-  return this.column_;
-};
-
-
-ScriptBreakPoint.prototype.hit_count = function() {
-  return this.hit_count_;
-};
-
-
-ScriptBreakPoint.prototype.active = function() {
-  return this.active_;
-};
-
-
-ScriptBreakPoint.prototype.condition = function() {
-  return this.condition_;
-};
-
-
-ScriptBreakPoint.prototype.ignoreCount = function() {
-  return this.ignoreCount_;
-};
-
-
-ScriptBreakPoint.prototype.enable = function() {
-  this.active_ = true;
-};
-
-
-ScriptBreakPoint.prototype.disable = function() {
-  this.active_ = false;
-};
-
-
-ScriptBreakPoint.prototype.setCondition = function(condition) {
-  this.condition_ = condition;
-};
-
-
-ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
-  this.ignoreCount_ = ignoreCount;
-
-  // Set ignore count on all break points created from this script break point.
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].script_break_point() === this) {
-      break_points[i].setIgnoreCount(ignoreCount);
-    }
-  }
-};
-
-
-// Check whether a script matches this script break point. Currently this is
-// only based on script name.
-ScriptBreakPoint.prototype.matchesScript = function(script) {
-  if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
-    return this.script_id_ == script.id;
-  } else {  // this.type_ == Debug.ScriptBreakPointType.ScriptName
-    return this.script_name_ == script.name &&
-           script.line_offset <= this.line_  &&
-           this.line_ < script.line_offset + script.lineCount();
-  }
-};
-
-
-// Set the script break point in a script.
-ScriptBreakPoint.prototype.set = function (script) {
-  var column = this.column();
-  var line = this.line();
-  // If the column is undefined the break is on the line. To help locate the
-  // first piece of breakable code on the line try to find the column on the
-  // line which contains some source.
-  if (IS_UNDEFINED(column)) {
-    var source_line = script.sourceLine(this.line());
-
-    // Allocate array for caching the columns where the actual source starts.
-    if (!script.sourceColumnStart_) {
-      script.sourceColumnStart_ = new Array(script.lineCount());
-    }
-
-    // Fill cache if needed and get column where the actual source starts.
-    if (IS_UNDEFINED(script.sourceColumnStart_[line])) {
-      script.sourceColumnStart_[line] =
-          source_line.match(sourceLineBeginningSkip)[0].length;
-    }
-    column = script.sourceColumnStart_[line];
-  }
-
-  // Convert the line and column into an absolute position within the script.
-  var pos = Debug.findScriptSourcePosition(script, this.line(), column);
-
-  // If the position is not found in the script (the script might be shorter
-  // than it used to be) just ignore it.
-  if (pos === null) return;
-
-  // Create a break point object and set the break point.
-  break_point = MakeBreakPoint(pos, this.line(), this.column(), this);
-  break_point.setIgnoreCount(this.ignoreCount());
-  %SetScriptBreakPoint(script, pos, break_point);
-
-  return break_point;
-};
-
-
-// Clear all the break points created from this script break point
-ScriptBreakPoint.prototype.clear = function () {
-  var remaining_break_points = [];
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].script_break_point() &&
-        break_points[i].script_break_point() === this) {
-      %ClearBreakPoint(break_points[i]);
-    } else {
-      remaining_break_points.push(break_points[i]);
-    }
-  }
-  break_points = remaining_break_points;
-};
-
-
-// Function called from runtime when a new script is compiled to set any script
-// break points set in this script.
-function UpdateScriptBreakPoints(script) {
-  for (var i = 0; i < script_break_points.length; i++) {
-    if (script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptName &&
-        script_break_points[i].matchesScript(script)) {
-      script_break_points[i].set(script);
-    }
-  }
-}
-
-
-Debug.setListener = function(listener, opt_data) {
-  if (!IS_FUNCTION(listener) && !IS_UNDEFINED(listener) && !IS_NULL(listener)) {
-    throw new Error('Parameters have wrong types.');
-  }
-  %SetDebugEventListener(listener, opt_data);
-};
-
-
-Debug.breakExecution = function(f) {
-  %Break();
-};
-
-Debug.breakLocations = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %GetBreakLocations(f);
-};
-
-// Returns a Script object. If the parameter is a function the return value
-// is the script in which the function is defined. If the parameter is a string
-// the return value is the script for which the script name has that string
-// value.  If it is a regexp and there is a unique script whose name matches
-// we return that, otherwise undefined.
-Debug.findScript = function(func_or_script_name) {
-  if (IS_FUNCTION(func_or_script_name)) {
-    return %FunctionGetScript(func_or_script_name);
-  } else if (IS_REGEXP(func_or_script_name)) {
-    var scripts = Debug.scripts();
-    var last_result = null;
-    var result_count = 0;
-    for (var i in scripts) {
-      var script = scripts[i];
-      if (func_or_script_name.test(script.name)) {
-        last_result = script;
-        result_count++;
-      }
-    }
-    // Return the unique script matching the regexp.  If there are more
-    // than one we don't return a value since there is no good way to
-    // decide which one to return.  Returning a "random" one, say the
-    // first, would introduce nondeterminism (or something close to it)
-    // because the order is the heap iteration order.
-    if (result_count == 1) {
-      return last_result;
-    } else {
-      return undefined;
-    }
-  } else {
-    return %GetScript(func_or_script_name);
-  }
-};
-
-// Returns the script source. If the parameter is a function the return value
-// is the script source for the script in which the function is defined. If the
-// parameter is a string the return value is the script for which the script
-// name has that string value.
-Debug.scriptSource = function(func_or_script_name) {
-  return this.findScript(func_or_script_name).source;
-};
-
-Debug.source = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %FunctionGetSourceCode(f);
-};
-
-Debug.disassemble = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %DebugDisassembleFunction(f);
-};
-
-Debug.disassembleConstructor = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %DebugDisassembleConstructor(f);
-};
-
-Debug.sourcePosition = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %FunctionGetScriptSourcePosition(f);
-};
-
-
-Debug.findFunctionSourceLocation = function(func, opt_line, opt_column) {
-  var script = %FunctionGetScript(func);
-  var script_offset = %FunctionGetScriptSourcePosition(func);
-  return script.locationFromLine(opt_line, opt_column, script_offset);
-}
-
-
-// Returns the character position in a script based on a line number and an
-// optional position within that line.
-Debug.findScriptSourcePosition = function(script, opt_line, opt_column) {
-  var location = script.locationFromLine(opt_line, opt_column);
-  return location ? location.position : null;
-}
-
-
-Debug.findBreakPoint = function(break_point_number, remove) {
-  var break_point;
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].number() == break_point_number) {
-      break_point = break_points[i];
-      // Remove the break point from the list if requested.
-      if (remove) {
-        break_points.splice(i, 1);
-      }
-      break;
-    }
-  }
-  if (break_point) {
-    return break_point;
-  } else {
-    return this.findScriptBreakPoint(break_point_number, remove);
-  }
-};
-
-
-Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
-  if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.');
-  // Break points in API functions are not supported.
-  if (%FunctionIsAPIFunction(func)) {
-    throw new Error('Cannot set break point in native code.');
-  }
-  // Find source position relative to start of the function
-  var break_position =
-      this.findFunctionSourceLocation(func, opt_line, opt_column).position;
-  var source_position = break_position - this.sourcePosition(func);
-  // Find the script for the function.
-  var script = %FunctionGetScript(func);
-  // Break in builtin JavaScript code is not supported.
-  if (script.type == Debug.ScriptType.Native) {
-    throw new Error('Cannot set break point in native code.');
-  }
-  // If the script for the function has a name convert this to a script break
-  // point.
-  if (script && script.id) {
-    // Adjust the source position to be script relative.
-    source_position += %FunctionGetScriptSourcePosition(func);
-    // Find line and column for the position in the script and set a script
-    // break point from that.
-    var location = script.locationFromPosition(source_position, false);
-    return this.setScriptBreakPointById(script.id,
-                                        location.line, location.column,
-                                        opt_condition);
-  } else {
-    // Set a break point directly on the function.
-    var break_point = MakeBreakPoint(source_position, opt_line, opt_column);
-    %SetFunctionBreakPoint(func, source_position, break_point);
-    break_point.setCondition(opt_condition);
-    return break_point.number();
-  }
-};
-
-
-Debug.enableBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.enable();
-};
-
-
-Debug.disableBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.disable();
-};
-
-
-Debug.changeBreakPointCondition = function(break_point_number, condition) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.setCondition(condition);
-};
-
-
-Debug.changeBreakPointIgnoreCount = function(break_point_number, ignoreCount) {
-  if (ignoreCount < 0) {
-    throw new Error('Invalid argument');
-  }
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.setIgnoreCount(ignoreCount);
-};
-
-
-Debug.clearBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, true);
-  if (break_point) {
-    return %ClearBreakPoint(break_point);
-  } else {
-    break_point = this.findScriptBreakPoint(break_point_number, true);
-    if (!break_point) {
-      throw new Error('Invalid breakpoint');
-    }
-  }
-};
-
-
-Debug.clearAllBreakPoints = function() {
-  for (var i = 0; i < break_points.length; i++) {
-    break_point = break_points[i];
-    %ClearBreakPoint(break_point);
-  }
-  break_points = [];
-};
-
-
-Debug.findScriptBreakPoint = function(break_point_number, remove) {
-  var script_break_point;
-  for (var i = 0; i < script_break_points.length; i++) {
-    if (script_break_points[i].number() == break_point_number) {
-      script_break_point = script_break_points[i];
-      // Remove the break point from the list if requested.
-      if (remove) {
-        script_break_point.clear();
-        script_break_points.splice(i,1);
-      }
-      break;
-    }
-  }
-  return script_break_point;
-}
-
-
-// Sets a breakpoint in a script identified through id or name at the
-// specified source line and column within that line.
-Debug.setScriptBreakPoint = function(type, script_id_or_name,
-                                     opt_line, opt_column, opt_condition,
-                                     opt_groupId) {
-  // Create script break point object.
-  var script_break_point =
-      new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                           opt_groupId);
-
-  // Assign number to the new script break point and add it.
-  script_break_point.number_ = next_break_point_number++;
-  script_break_point.setCondition(opt_condition);
-  script_break_points.push(script_break_point);
-
-  // Run through all scripts to see if this script break point matches any
-  // loaded scripts.
-  var scripts = this.scripts();
-  for (var i = 0; i < scripts.length; i++) {
-    if (script_break_point.matchesScript(scripts[i])) {
-      script_break_point.set(scripts[i]);
-    }
-  }
-
-  return script_break_point.number();
-}
-
-
-Debug.setScriptBreakPointById = function(script_id,
-                                         opt_line, opt_column,
-                                         opt_condition, opt_groupId) {
-  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
-                                  script_id, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
-}
-
-
-Debug.setScriptBreakPointByName = function(script_name,
-                                           opt_line, opt_column,
-                                           opt_condition, opt_groupId) {
-  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName,
-                                  script_name, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
-}
-
-
-Debug.enableScriptBreakPoint = function(break_point_number) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.enable();
-};
-
-
-Debug.disableScriptBreakPoint = function(break_point_number) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.disable();
-};
-
-
-Debug.changeScriptBreakPointCondition = function(break_point_number, condition) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.setCondition(condition);
-};
-
-
-Debug.changeScriptBreakPointIgnoreCount = function(break_point_number, ignoreCount) {
-  if (ignoreCount < 0) {
-    throw new Error('Invalid argument');
-  }
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.setIgnoreCount(ignoreCount);
-};
-
-
-Debug.scriptBreakPoints = function() {
-  return script_break_points;
-}
-
-
-Debug.clearStepping = function() {
-  %ClearStepping();
-}
-
-Debug.setBreakOnException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.All, true);
-};
-
-Debug.clearBreakOnException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.All, false);
-};
-
-Debug.setBreakOnUncaughtException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, true);
-};
-
-Debug.clearBreakOnUncaughtException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
-};
-
-Debug.showBreakPoints = function(f, full) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  var source = full ? this.scriptSource(f) : this.source(f);
-  var offset = full ? this.sourcePosition(f) : 0;
-  var locations = this.breakLocations(f);
-  if (!locations) return source;
-  locations.sort(function(x, y) { return x - y; });
-  var result = "";
-  var prev_pos = 0;
-  var pos;
-  for (var i = 0; i < locations.length; i++) {
-    pos = locations[i] - offset;
-    result += source.slice(prev_pos, pos);
-    result += "[B" + i + "]";
-    prev_pos = pos;
-  }
-  pos = source.length;
-  result += source.substring(prev_pos, pos);
-  return result;
-};
-
-
-// Get all the scripts currently loaded. Locating all the scripts is based on
-// scanning the heap.
-Debug.scripts = function() {
-  // Collect all scripts in the heap.
-  return %DebugGetLoadedScripts();
-}
-
-function MakeExecutionState(break_id) {
-  return new ExecutionState(break_id);
-}
-
-function ExecutionState(break_id) {
-  this.break_id = break_id;
-  this.selected_frame = 0;
-}
-
-ExecutionState.prototype.prepareStep = function(opt_action, opt_count) {
-  var action = Debug.StepAction.StepIn;
-  if (!IS_UNDEFINED(opt_action)) action = %ToNumber(opt_action);
-  var count = opt_count ? %ToNumber(opt_count) : 1;
-
-  return %PrepareStep(this.break_id, action, count);
-}
-
-ExecutionState.prototype.evaluateGlobal = function(source, disable_break) {
-  return MakeMirror(
-      %DebugEvaluateGlobal(this.break_id, source, Boolean(disable_break)));
-};
-
-ExecutionState.prototype.frameCount = function() {
-  return %GetFrameCount(this.break_id);
-};
-
-ExecutionState.prototype.threadCount = function() {
-  return %GetThreadCount(this.break_id);
-};
-
-ExecutionState.prototype.frame = function(opt_index) {
-  // If no index supplied return the selected frame.
-  if (opt_index == null) opt_index = this.selected_frame;
-  return new FrameMirror(this.break_id, opt_index);
-};
-
-ExecutionState.prototype.cframesValue = function(opt_from_index, opt_to_index) {
-  return %GetCFrames(this.break_id);
-};
-
-ExecutionState.prototype.setSelectedFrame = function(index) {
-  var i = %ToNumber(index);
-  if (i < 0 || i >= this.frameCount()) throw new Error('Illegal frame index.');
-  this.selected_frame = i;
-};
-
-ExecutionState.prototype.selectedFrame = function() {
-  return this.selected_frame;
-};
-
-ExecutionState.prototype.debugCommandProcessor = function(opt_is_running) {
-  return new DebugCommandProcessor(this, opt_is_running);
-};
-
-
-function MakeBreakEvent(exec_state, break_points_hit) {
-  return new BreakEvent(exec_state, break_points_hit);
-}
-
-
-function BreakEvent(exec_state, break_points_hit) {
-  this.exec_state_ = exec_state;
-  this.break_points_hit_ = break_points_hit;
-}
-
-
-BreakEvent.prototype.executionState = function() {
-  return this.exec_state_;
-};
-
-
-BreakEvent.prototype.eventType = function() {
-  return Debug.DebugEvent.Break;
-};
-
-
-BreakEvent.prototype.func = function() {
-  return this.exec_state_.frame(0).func();
-};
-
-
-BreakEvent.prototype.sourceLine = function() {
-  return this.exec_state_.frame(0).sourceLine();
-};
-
-
-BreakEvent.prototype.sourceColumn = function() {
-  return this.exec_state_.frame(0).sourceColumn();
-};
-
-
-BreakEvent.prototype.sourceLineText = function() {
-  return this.exec_state_.frame(0).sourceLineText();
-};
-
-
-BreakEvent.prototype.breakPointsHit = function() {
-  return this.break_points_hit_;
-};
-
-
-BreakEvent.prototype.toJSONProtocol = function() {
-  var o = { seq: next_response_seq++,
-            type: "event",
-            event: "break",
-            body: { invocationText: this.exec_state_.frame(0).invocationText(),
-                  }
-          };
-
-  // Add script related information to the event if available.
-  var script = this.func().script();
-  if (script) {
-    o.body.sourceLine = this.sourceLine(),
-    o.body.sourceColumn = this.sourceColumn(),
-    o.body.sourceLineText = this.sourceLineText(),
-    o.body.script = MakeScriptObject_(script, false);
-  }
-
-  // Add an Array of break points hit if any.
-  if (this.breakPointsHit()) {
-    o.body.breakpoints = [];
-    for (var i = 0; i < this.breakPointsHit().length; i++) {
-      // Find the break point number. For break points originating from a
-      // script break point supply the script break point number.
-      var breakpoint = this.breakPointsHit()[i];
-      var script_break_point = breakpoint.script_break_point();
-      var number;
-      if (script_break_point) {
-        number = script_break_point.number();
-      } else {
-        number = breakpoint.number();
-      }
-      o.body.breakpoints.push(number);
-    }
-  }
-  return JSON.stringify(ObjectToProtocolObject_(o));
-};
-
-
-function MakeExceptionEvent(exec_state, exception, uncaught) {
-  return new ExceptionEvent(exec_state, exception, uncaught);
-}
-
-
-function ExceptionEvent(exec_state, exception, uncaught) {
-  this.exec_state_ = exec_state;
-  this.exception_ = exception;
-  this.uncaught_ = uncaught;
-}
-
-
-ExceptionEvent.prototype.executionState = function() {
-  return this.exec_state_;
-};
-
-
-ExceptionEvent.prototype.eventType = function() {
-  return Debug.DebugEvent.Exception;
-};
-
-
-ExceptionEvent.prototype.exception = function() {
-  return this.exception_;
-}
-
-
-ExceptionEvent.prototype.uncaught = function() {
-  return this.uncaught_;
-}
-
-
-ExceptionEvent.prototype.func = function() {
-  return this.exec_state_.frame(0).func();
-};
-
-
-ExceptionEvent.prototype.sourceLine = function() {
-  return this.exec_state_.frame(0).sourceLine();
-};
-
-
-ExceptionEvent.prototype.sourceColumn = function() {
-  return this.exec_state_.frame(0).sourceColumn();
-};
-
-
-ExceptionEvent.prototype.sourceLineText = function() {
-  return this.exec_state_.frame(0).sourceLineText();
-};
-
-
-ExceptionEvent.prototype.toJSONProtocol = function() {
-  var o = new ProtocolMessage();
-  o.event = "exception";
-  o.body = { uncaught: this.uncaught_,
-             exception: MakeMirror(this.exception_)
-           };
-
-  // Exceptions might happen whithout any JavaScript frames.
-  if (this.exec_state_.frameCount() > 0) {
-    o.body.sourceLine = this.sourceLine();
-    o.body.sourceColumn = this.sourceColumn();
-    o.body.sourceLineText = this.sourceLineText();
-
-    // Add script information to the event if available.
-    var script = this.func().script();
-    if (script) {
-      o.body.script = MakeScriptObject_(script, false);
-    }
-  } else {
-    o.body.sourceLine = -1;
-  }
-
-  return o.toJSONProtocol();
-};
-
-
-function MakeCompileEvent(exec_state, script, before) {
-  return new CompileEvent(exec_state, script, before);
-}
-
-
-function CompileEvent(exec_state, script, before) {
-  this.exec_state_ = exec_state;
-  this.script_ = MakeMirror(script);
-  this.before_ = before;
-}
-
-
-CompileEvent.prototype.executionState = function() {
-  return this.exec_state_;
-};
-
-
-CompileEvent.prototype.eventType = function() {
-  if (this.before_) {
-    return Debug.DebugEvent.BeforeCompile;
-  } else {
-    return Debug.DebugEvent.AfterCompile;
-  }
-};
-
-
-CompileEvent.prototype.script = function() {
-  return this.script_;
-};
-
-
-CompileEvent.prototype.toJSONProtocol = function() {
-  var o = new ProtocolMessage();
-  o.running = true;
-  if (this.before_) {
-    o.event = "beforeCompile";
-  } else {
-    o.event = "afterCompile";
-  }
-  o.body = {};
-  o.body.script = this.script_;
-
-  return o.toJSONProtocol();
-}
-
-
-function MakeNewFunctionEvent(func) {
-  return new NewFunctionEvent(func);
-}
-
-
-function NewFunctionEvent(func) {
-  this.func = func;
-}
-
-
-NewFunctionEvent.prototype.eventType = function() {
-  return Debug.DebugEvent.NewFunction;
-};
-
-
-NewFunctionEvent.prototype.name = function() {
-  return this.func.name;
-};
-
-
-NewFunctionEvent.prototype.setBreakPoint = function(p) {
-  Debug.setBreakPoint(this.func, p || 0);
-};
-
-
-function MakeScriptCollectedEvent(exec_state, id) {
-  return new ScriptCollectedEvent(exec_state, id);
-}
-
-
-function ScriptCollectedEvent(exec_state, id) {
-  this.exec_state_ = exec_state;
-  this.id_ = id;
-}
-
-
-ScriptCollectedEvent.prototype.id = function() {
-  return this.id_;
-};
-
-
-ScriptCollectedEvent.prototype.executionState = function() {
-  return this.exec_state_;
-};
-
-
-ScriptCollectedEvent.prototype.toJSONProtocol = function() {
-  var o = new ProtocolMessage();
-  o.running = true;
-  o.event = "scriptCollected";
-  o.body = {};
-  o.body.script = { id: this.id() };
-  return o.toJSONProtocol();
-}
-
-
-function MakeScriptObject_(script, include_source) {
-  var o = { id: script.id(),
-            name: script.name(),
-            lineOffset: script.lineOffset(),
-            columnOffset: script.columnOffset(),
-            lineCount: script.lineCount(),
-          };
-  if (!IS_UNDEFINED(script.data())) {
-    o.data = script.data();
-  }
-  if (include_source) {
-    o.source = script.source();
-  }
-  return o;
-};
-
-
-function DebugCommandProcessor(exec_state, opt_is_running) {
-  this.exec_state_ = exec_state;
-  this.running_ = opt_is_running || false;
-};
-
-
-DebugCommandProcessor.prototype.processDebugRequest = function (request) {
-  return this.processDebugJSONRequest(request);
-}
-
-
-function ProtocolMessage(request) {
-  // Update sequence number.
-  this.seq = next_response_seq++;
-
-  if (request) {
-    // If message is based on a request this is a response. Fill the initial
-    // response from the request.
-    this.type = 'response';
-    this.request_seq = request.seq;
-    this.command = request.command;
-  } else {
-    // If message is not based on a request it is a dabugger generated event.
-    this.type = 'event';
-  }
-  this.success = true;
-  // Handler may set this field to control debugger state.
-  this.running = undefined;
-}
-
-
-ProtocolMessage.prototype.setOption = function(name, value) {
-  if (!this.options_) {
-    this.options_ = {};
-  }
-  this.options_[name] = value;
-}
-
-
-ProtocolMessage.prototype.failed = function(message) {
-  this.success = false;
-  this.message = message;
-}
-
-
-ProtocolMessage.prototype.toJSONProtocol = function() {
-  // Encode the protocol header.
-  var json = {};
-  json.seq= this.seq;
-  if (this.request_seq) {
-    json.request_seq = this.request_seq;
-  }
-  json.type = this.type;
-  if (this.event) {
-    json.event = this.event;
-  }
-  if (this.command) {
-    json.command = this.command;
-  }
-  if (this.success) {
-    json.success = this.success;
-  } else {
-    json.success = false;
-  }
-  if (this.body) {
-    // Encode the body part.
-    var bodyJson;
-    var serializer = MakeMirrorSerializer(true, this.options_);
-    if (this.body instanceof Mirror) {
-      bodyJson = serializer.serializeValue(this.body);
-    } else if (this.body instanceof Array) {
-      bodyJson = [];
-      for (var i = 0; i < this.body.length; i++) {
-        if (this.body[i] instanceof Mirror) {
-          bodyJson.push(serializer.serializeValue(this.body[i]));
-        } else {
-          bodyJson.push(ObjectToProtocolObject_(this.body[i], serializer));
-        }
-      }
-    } else {
-      bodyJson = ObjectToProtocolObject_(this.body, serializer);
-    }
-    json.body = bodyJson;
-    json.refs = serializer.serializeReferencedObjects();
-  }
-  if (this.message) {
-    json.message = this.message;
-  }
-  json.running = this.running;
-  return JSON.stringify(json);
-}
-
-
-DebugCommandProcessor.prototype.createResponse = function(request) {
-  return new ProtocolMessage(request);
-};
-
-
-DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request) {
-  var request;  // Current request.
-  var response;  // Generated response.
-  try {
-    try {
-      // Convert the JSON string to an object.
-      request = %CompileString('(' + json_request + ')', false)();
-
-      // Create an initial response.
-      response = this.createResponse(request);
-
-      if (!request.type) {
-        throw new Error('Type not specified');
-      }
-
-      if (request.type != 'request') {
-        throw new Error("Illegal type '" + request.type + "' in request");
-      }
-
-      if (!request.command) {
-        throw new Error('Command not specified');
-      }
-
-      // TODO(yurys): remove request.arguments.compactFormat check once
-      // ChromeDevTools are switched to 'inlineRefs'
-      if (request.arguments && (request.arguments.inlineRefs ||
-                                request.arguments.compactFormat)) {
-        response.setOption('inlineRefs', true);
-      }
-
-      if (request.command == 'continue') {
-        this.continueRequest_(request, response);
-      } else if (request.command == 'break') {
-        this.breakRequest_(request, response);
-      } else if (request.command == 'setbreakpoint') {
-        this.setBreakPointRequest_(request, response);
-      } else if (request.command == 'changebreakpoint') {
-        this.changeBreakPointRequest_(request, response);
-      } else if (request.command == 'clearbreakpoint') {
-        this.clearBreakPointRequest_(request, response);
-      } else if (request.command == 'clearbreakpointgroup') {
-        this.clearBreakPointGroupRequest_(request, response);
-      } else if (request.command == 'backtrace') {
-        this.backtraceRequest_(request, response);
-      } else if (request.command == 'frame') {
-        this.frameRequest_(request, response);
-      } else if (request.command == 'scopes') {
-        this.scopesRequest_(request, response);
-      } else if (request.command == 'scope') {
-        this.scopeRequest_(request, response);
-      } else if (request.command == 'evaluate') {
-        this.evaluateRequest_(request, response);
-      } else if (request.command == 'lookup') {
-        this.lookupRequest_(request, response);
-      } else if (request.command == 'references') {
-        this.referencesRequest_(request, response);
-      } else if (request.command == 'source') {
-        this.sourceRequest_(request, response);
-      } else if (request.command == 'scripts') {
-        this.scriptsRequest_(request, response);
-      } else if (request.command == 'threads') {
-        this.threadsRequest_(request, response);
-      } else if (request.command == 'suspend') {
-        this.suspendRequest_(request, response);
-      } else if (request.command == 'version') {
-        this.versionRequest_(request, response);
-      } else if (request.command == 'profile') {
-        this.profileRequest_(request, response);
-      } else {
-        throw new Error('Unknown command "' + request.command + '" in request');
-      }
-    } catch (e) {
-      // If there is no response object created one (without command).
-      if (!response) {
-        response = this.createResponse();
-      }
-      response.success = false;
-      response.message = %ToString(e);
-    }
-
-    // Return the response as a JSON encoded string.
-    try {
-      if (!IS_UNDEFINED(response.running)) {
-        // Response controls running state.
-        this.running_ = response.running;
-      }
-      response.running = this.running_; 
-      return response.toJSONProtocol();
-    } catch (e) {
-      // Failed to generate response - return generic error.
-      return '{"seq":' + response.seq + ',' +
-              '"request_seq":' + request.seq + ',' +
-              '"type":"response",' +
-              '"success":false,' +
-              '"message":"Internal error: ' + %ToString(e) + '"}';
-    }
-  } catch (e) {
-    // Failed in one of the catch blocks above - most generic error.
-    return '{"seq":0,"type":"response","success":false,"message":"Internal error"}';
-  }
-};
-
-
-DebugCommandProcessor.prototype.continueRequest_ = function(request, response) {
-  // Check for arguments for continue.
-  if (request.arguments) {
-    var count = 1;
-    var action = Debug.StepAction.StepIn;
-
-    // Pull out arguments.
-    var stepaction = request.arguments.stepaction;
-    var stepcount = request.arguments.stepcount;
-
-    // Get the stepcount argument if any.
-    if (stepcount) {
-      count = %ToNumber(stepcount);
-      if (count < 0) {
-        throw new Error('Invalid stepcount argument "' + stepcount + '".');
-      }
-    }
-
-    // Get the stepaction argument.
-    if (stepaction) {
-      if (stepaction == 'in') {
-        action = Debug.StepAction.StepIn;
-      } else if (stepaction == 'min') {
-        action = Debug.StepAction.StepMin;
-      } else if (stepaction == 'next') {
-        action = Debug.StepAction.StepNext;
-      } else if (stepaction == 'out') {
-        action = Debug.StepAction.StepOut;
-      } else {
-        throw new Error('Invalid stepaction argument "' + stepaction + '".');
-      }
-    }
-
-    // Setup the VM for stepping.
-    this.exec_state_.prepareStep(action, count);
-  }
-
-  // VM should be running after executing this request.
-  response.running = true;
-};
-
-
-DebugCommandProcessor.prototype.breakRequest_ = function(request, response) {
-  // Ignore as break command does not do anything when broken.
-};
-
-
-DebugCommandProcessor.prototype.setBreakPointRequest_ =
-    function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var type = request.arguments.type;
-  var target = request.arguments.target;
-  var line = request.arguments.line;
-  var column = request.arguments.column;
-  var enabled = IS_UNDEFINED(request.arguments.enabled) ?
-      true : request.arguments.enabled;
-  var condition = request.arguments.condition;
-  var ignoreCount = request.arguments.ignoreCount;
-  var groupId = request.arguments.groupId;
-
-  // Check for legal arguments.
-  if (!type || IS_UNDEFINED(target)) {
-    response.failed('Missing argument "type" or "target"');
-    return;
-  }
-  if (type != 'function' && type != 'handle' &&
-      type != 'script' && type != 'scriptId') {
-    response.failed('Illegal type "' + type + '"');
-    return;
-  }
-
-  // Either function or script break point.
-  var break_point_number;
-  if (type == 'function') {
-    // Handle function break point.
-    if (!IS_STRING(target)) {
-      response.failed('Argument "target" is not a string value');
-      return;
-    }
-    var f;
-    try {
-      // Find the function through a global evaluate.
-      f = this.exec_state_.evaluateGlobal(target).value();
-    } catch (e) {
-      response.failed('Error: "' + %ToString(e) +
-                      '" evaluating "' + target + '"');
-      return;
-    }
-    if (!IS_FUNCTION(f)) {
-      response.failed('"' + target + '" does not evaluate to a function');
-      return;
-    }
-
-    // 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 =
-        Debug.setScriptBreakPointByName(target, line, column, condition,
-                                        groupId);
-  } else {  // type == 'scriptId.
-    break_point_number =
-        Debug.setScriptBreakPointById(target, line, column, condition, groupId);
-  }
-
-  // Set additional break point properties.
-  var break_point = Debug.findBreakPoint(break_point_number);
-  if (ignoreCount) {
-    Debug.changeBreakPointIgnoreCount(break_point_number, ignoreCount);
-  }
-  if (!enabled) {
-    Debug.disableBreakPoint(break_point_number);
-  }
-
-  // Add the break point number to the response.
-  response.body = { type: type,
-                    breakpoint: break_point_number }
-
-  // Add break point information to the response.
-  if (break_point instanceof ScriptBreakPoint) {
-    if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
-      response.body.type = 'scriptId';
-      response.body.script_id = break_point.script_id();
-    } else {
-      response.body.type = 'scriptName';
-      response.body.script_name = break_point.script_name();
-    }
-    response.body.line = break_point.line();
-    response.body.column = break_point.column();
-  } else {
-    response.body.type = 'function';
-  }
-};
-
-
-DebugCommandProcessor.prototype.changeBreakPointRequest_ = function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var break_point = %ToNumber(request.arguments.breakpoint);
-  var enabled = request.arguments.enabled;
-  var condition = request.arguments.condition;
-  var ignoreCount = request.arguments.ignoreCount;
-
-  // Check for legal arguments.
-  if (!break_point) {
-    response.failed('Missing argument "breakpoint"');
-    return;
-  }
-
-  // Change enabled state if supplied.
-  if (!IS_UNDEFINED(enabled)) {
-    if (enabled) {
-      Debug.enableBreakPoint(break_point);
-    } else {
-      Debug.disableBreakPoint(break_point);
-    }
-  }
-
-  // Change condition if supplied
-  if (!IS_UNDEFINED(condition)) {
-    Debug.changeBreakPointCondition(break_point, condition);
-  }
-
-  // Change ignore count if supplied
-  if (!IS_UNDEFINED(ignoreCount)) {
-    Debug.changeBreakPointIgnoreCount(break_point, ignoreCount);
-  }
-}
-
-
-DebugCommandProcessor.prototype.clearBreakPointGroupRequest_ = function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var group_id = request.arguments.groupId;
-
-  // Check for legal arguments.
-  if (!group_id) {
-    response.failed('Missing argument "groupId"');
-    return;
-  }
-
-  var cleared_break_points = [];
-  var new_script_break_points = [];
-  for (var i = 0; i < script_break_points.length; i++) {
-    var next_break_point = script_break_points[i];
-    if (next_break_point.groupId() == group_id) {
-      cleared_break_points.push(next_break_point.number());
-      next_break_point.clear();
-    } else {
-      new_script_break_points.push(next_break_point);
-    }
-  }
-  script_break_points = new_script_break_points;
-
-  // Add the cleared break point numbers to the response.
-  response.body = { breakpoints: cleared_break_points };
-}
-
-
-DebugCommandProcessor.prototype.clearBreakPointRequest_ = function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var break_point = %ToNumber(request.arguments.breakpoint);
-
-  // Check for legal arguments.
-  if (!break_point) {
-    response.failed('Missing argument "breakpoint"');
-    return;
-  }
-
-  // Clear break point.
-  Debug.clearBreakPoint(break_point);
-
-  // Add the cleared break point number to the response.
-  response.body = { breakpoint: break_point }
-}
-
-
-DebugCommandProcessor.prototype.backtraceRequest_ = function(request, response) {
-  // Get the number of frames.
-  var total_frames = this.exec_state_.frameCount();
-
-  // Create simple response if there are no frames.
-  if (total_frames == 0) {
-    response.body = {
-      totalFrames: total_frames
-    }
-    return;
-  }
-
-  // Default frame range to include in backtrace.
-  var from_index = 0
-  var to_index = kDefaultBacktraceLength;
-
-  // Get the range from the arguments.
-  if (request.arguments) {
-    if (request.arguments.fromFrame) {
-      from_index = request.arguments.fromFrame;
-    }
-    if (request.arguments.toFrame) {
-      to_index = request.arguments.toFrame;
-    }
-    if (request.arguments.bottom) {
-      var tmp_index = total_frames - from_index;
-      from_index = total_frames - to_index
-      to_index = tmp_index;
-    }
-    if (from_index < 0 || to_index < 0) {
-      return response.failed('Invalid frame number');
-    }
-  }
-
-  // Adjust the index.
-  to_index = Math.min(total_frames, to_index);
-
-  if (to_index <= from_index) {
-    var error = 'Invalid frame range';
-    return response.failed(error);
-  }
-
-  // Create the response body.
-  var frames = [];
-  for (var i = from_index; i < to_index; i++) {
-    frames.push(this.exec_state_.frame(i));
-  }
-  response.body = {
-    fromFrame: from_index,
-    toFrame: to_index,
-    totalFrames: total_frames,
-    frames: frames
-  }
-};
-
-
-DebugCommandProcessor.prototype.backtracec = function(cmd, args) {
-  return this.exec_state_.cframesValue();
-};
-
-
-DebugCommandProcessor.prototype.frameRequest_ = function(request, response) {
-  // No frames no source.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No frames');
-  }
-
-  // With no arguments just keep the selected frame.
-  if (request.arguments) {
-    var index = request.arguments.number;
-    if (index < 0 || this.exec_state_.frameCount() <= index) {
-      return response.failed('Invalid frame number');
-    }
-
-    this.exec_state_.setSelectedFrame(request.arguments.number);
-  }
-  response.body = this.exec_state_.frame();
-};
-
-
-DebugCommandProcessor.prototype.frameForScopeRequest_ = function(request) {
-  // Get the frame for which the scope or scopes are requested. With no frameNumber
-  // argument use the currently selected frame.
-  if (request.arguments && !IS_UNDEFINED(request.arguments.frameNumber)) {
-    frame_index = request.arguments.frameNumber;
-    if (frame_index < 0 || this.exec_state_.frameCount() <= frame_index) {
-      return response.failed('Invalid frame number');
-    }
-    return this.exec_state_.frame(frame_index);
-  } else {
-    return this.exec_state_.frame();
-  }
-}
-
-
-DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
-  // No frames no scopes.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No scopes');
-  }
-
-  // Get the frame for which the scopes are requested.
-  var frame = this.frameForScopeRequest_(request);
-
-  // Fill all scopes for this frame.
-  var total_scopes = frame.scopeCount();
-  var scopes = [];
-  for (var i = 0; i < total_scopes; i++) {
-    scopes.push(frame.scope(i));
-  }
-  response.body = {
-    fromScope: 0,
-    toScope: total_scopes,
-    totalScopes: total_scopes,
-    scopes: scopes
-  }
-};
-
-
-DebugCommandProcessor.prototype.scopeRequest_ = function(request, response) {
-  // No frames no scopes.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No scopes');
-  }
-
-  // Get the frame for which the scope is requested.
-  var frame = this.frameForScopeRequest_(request);
-
-  // With no scope argument just return top scope.
-  var scope_index = 0;
-  if (request.arguments && !IS_UNDEFINED(request.arguments.number)) {
-    scope_index = %ToNumber(request.arguments.number);
-    if (scope_index < 0 || frame.scopeCount() <= scope_index) {
-      return response.failed('Invalid scope number');
-    }
-  }
-
-  response.body = frame.scope(scope_index);
-};
-
-
-DebugCommandProcessor.prototype.evaluateRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var expression = request.arguments.expression;
-  var frame = request.arguments.frame;
-  var global = request.arguments.global;
-  var disable_break = request.arguments.disable_break;
-
-  // The expression argument could be an integer so we convert it to a
-  // string.
-  try {
-    expression = String(expression);
-  } catch(e) {
-    return response.failed('Failed to convert expression argument to string');
-  }
-
-  // Check for legal arguments.
-  if (!IS_UNDEFINED(frame) && global) {
-    return response.failed('Arguments "frame" and "global" are exclusive');
-  }
-
-  // Global evaluate.
-  if (global) {
-    // Evaluate in the global context.
-    response.body =
-        this.exec_state_.evaluateGlobal(expression, Boolean(disable_break));
-    return;
-  }
-
-  // Default value for disable_break is true.
-  if (IS_UNDEFINED(disable_break)) {
-    disable_break = true;
-  }
-
-  // No frames no evaluate in frame.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No frames');
-  }
-
-  // Check whether a frame was specified.
-  if (!IS_UNDEFINED(frame)) {
-    var frame_number = %ToNumber(frame);
-    if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
-      return response.failed('Invalid frame "' + frame + '"');
-    }
-    // Evaluate in the specified frame.
-    response.body = this.exec_state_.frame(frame_number).evaluate(
-        expression, Boolean(disable_break));
-    return;
-  } else {
-    // Evaluate in the selected frame.
-    response.body = this.exec_state_.frame().evaluate(
-        expression, Boolean(disable_break));
-    return;
-  }
-};
-
-
-DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var handles = request.arguments.handles;
-
-  // Check for legal arguments.
-  if (IS_UNDEFINED(handles)) {
-    return response.failed('Argument "handles" missing');
-  }
-
-  // Set 'includeSource' option for script lookup.
-  if (!IS_UNDEFINED(request.arguments.includeSource)) {
-    includeSource = %ToBoolean(request.arguments.includeSource);
-    response.setOption('includeSource', includeSource);
-  }
-
-  // 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;
-};
-
-
-DebugCommandProcessor.prototype.referencesRequest_ =
-    function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var type = request.arguments.type;
-  var handle = request.arguments.handle;
-
-  // Check for legal arguments.
-  if (IS_UNDEFINED(type)) {
-    return response.failed('Argument "type" missing');
-  }
-  if (IS_UNDEFINED(handle)) {
-    return response.failed('Argument "handle" missing');
-  }
-  if (type != 'referencedBy' && type != 'constructedBy') {
-    return response.failed('Invalid type "' + type + '"');
-  }
-
-  // Lookup handle and return objects with references the object.
-  var mirror = LookupMirror(handle);
-  if (mirror) {
-    if (type == 'referencedBy') {
-      response.body = mirror.referencedBy();
-    } else {
-      response.body = mirror.constructedBy();
-    }
-  } else {
-    return response.failed('Object #' + handle + '# not found');
-  }
-};
-
-
-DebugCommandProcessor.prototype.sourceRequest_ = function(request, response) {
-  // No frames no source.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No source');
-  }
-
-  var from_line;
-  var to_line;
-  var frame = this.exec_state_.frame();
-  if (request.arguments) {
-    // Pull out arguments.
-    from_line = request.arguments.fromLine;
-    to_line = request.arguments.toLine;
-
-    if (!IS_UNDEFINED(request.arguments.frame)) {
-      var frame_number = %ToNumber(request.arguments.frame);
-      if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
-        return response.failed('Invalid frame "' + frame + '"');
-      }
-      frame = this.exec_state_.frame(frame_number);
-    }
-  }
-
-  // Get the script selected.
-  var script = frame.func().script();
-  if (!script) {
-    return response.failed('No source');
-  }
-
-  // Get the source slice and fill it into the response.
-  var slice = script.sourceSlice(from_line, to_line);
-  if (!slice) {
-    return response.failed('Invalid line interval');
-  }
-  response.body = {};
-  response.body.source = slice.sourceText();
-  response.body.fromLine = slice.from_line;
-  response.body.toLine = slice.to_line;
-  response.body.fromPosition = slice.from_position;
-  response.body.toPosition = slice.to_position;
-  response.body.totalLines = script.lineCount();
-};
-
-
-DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
-  var types = ScriptTypeFlag(Debug.ScriptType.Normal);
-  var includeSource = false;
-  var idsToInclude = null;
-  if (request.arguments) {
-    // Pull out arguments.
-    if (!IS_UNDEFINED(request.arguments.types)) {
-      types = %ToNumber(request.arguments.types);
-      if (isNaN(types) || types < 0) {
-        return response.failed('Invalid types "' + request.arguments.types + '"');
-      }
-    }
-    
-    if (!IS_UNDEFINED(request.arguments.includeSource)) {
-      includeSource = %ToBoolean(request.arguments.includeSource);
-      response.setOption('includeSource', includeSource);
-    }
-    
-    if (IS_ARRAY(request.arguments.ids)) {
-      idsToInclude = {};
-      var ids = request.arguments.ids;
-      for (var i = 0; i < ids.length; i++) {
-        idsToInclude[ids[i]] = true;
-      }
-    }
-  }
-
-  // Collect all scripts in the heap.
-  var scripts = %DebugGetLoadedScripts();
-
-  response.body = [];
-
-  for (var i = 0; i < scripts.length; i++) {
-    if (idsToInclude && !idsToInclude[scripts[i].id]) {
-      continue;
-    }
-    if (types & ScriptTypeFlag(scripts[i].type)) {
-      response.body.push(MakeMirror(scripts[i]));
-    }
-  }
-};
-
-
-DebugCommandProcessor.prototype.threadsRequest_ = function(request, response) {
-  // Get the number of threads.
-  var total_threads = this.exec_state_.threadCount();
-
-  // Get information for all threads.
-  var threads = [];
-  for (var i = 0; i < total_threads; i++) {
-    var details = %GetThreadDetails(this.exec_state_.break_id, i);
-    var thread_info = { current: details[0],
-                        id: details[1]
-                      }
-    threads.push(thread_info);
-  }
-
-  // Create the response body.
-  response.body = {
-    totalThreads: total_threads,
-    threads: threads
-  }
-};
-
-
-DebugCommandProcessor.prototype.suspendRequest_ = function(request, response) {
-  response.running = false;
-};
-
-
-DebugCommandProcessor.prototype.versionRequest_ = function(request, response) {
-  response.body = {
-    V8Version: %GetV8Version()
-  }
-};
-
-
-DebugCommandProcessor.prototype.profileRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-  var modules = parseInt(request.arguments.modules);
-  if (isNaN(modules)) {
-    return response.failed('Modules is not an integer');
-  }
-  if (request.arguments.command == 'resume') {
-    %ProfilerResume(modules);
-  } else if (request.arguments.command == 'pause') {
-    %ProfilerPause(modules);
-  } else {
-    return response.failed('Unknown command');
-  }
-  response.body = {};
-};
-
-
-// Check whether the previously processed command caused the VM to become
-// running.
-DebugCommandProcessor.prototype.isRunning = function() {
-  return this.running_;
-}
-
-
-DebugCommandProcessor.prototype.systemBreak = function(cmd, args) {
-  return %SystemBreak();
-};
-
-
-function NumberToHex8Str(n) {
-  var r = "";
-  for (var i = 0; i < 8; ++i) {
-    var c = hexCharArray[n & 0x0F];  // hexCharArray is defined in uri.js
-    r = c + r;
-    n = n >>> 4;
-  }
-  return r;
-};
-
-DebugCommandProcessor.prototype.formatCFrames = function(cframes_value) {
-  var result = "";
-  if (cframes_value == null || cframes_value.length == 0) {
-    result += "(stack empty)";
-  } else {
-    for (var i = 0; i < cframes_value.length; ++i) {
-      if (i != 0) result += "\n";
-      result += this.formatCFrame(cframes_value[i]);
-    }
-  }
-  return result;
-};
-
-
-DebugCommandProcessor.prototype.formatCFrame = function(cframe_value) {
-  var result = "";
-  result += "0x" + NumberToHex8Str(cframe_value.address);
-  if (!IS_UNDEFINED(cframe_value.text)) {
-    result += " " + cframe_value.text;
-  }
-  return result;
-}
-
-
-/**
- * Convert an Object to its debugger protocol representation. The representation
- * may be serilized to a JSON object using JSON.stringify().
- * This implementation simply runs through all string property names, converts
- * each property value to a protocol value and adds the property to the result
- * object. For type "object" the function will be called recursively. Note that
- * circular structures will cause infinite recursion.
- * @param {Object} object The object to format as protocol object.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {Object} Protocol object value.
- */
-function ObjectToProtocolObject_(object, mirror_serializer) {
-  var content = {};
-  for (var key in object) {
-    // Only consider string keys.
-    if (typeof key == 'string') {
-      // Format the value based on its type.
-      var property_value_json = ValueToProtocolValue_(object[key],
-                                                      mirror_serializer);
-      // Add the property if relevant.
-      if (!IS_UNDEFINED(property_value_json)) {
-        content[key] = property_value_json;
-      }
-    }
-  }
-  
-  return content;
-}
-
-
-/**
- * Convert an array to its debugger protocol representation. It will convert
- * each array element to a protocol value.
- * @param {Array} array The array to format as protocol array.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {Array} Protocol array value.
- */
-function ArrayToProtocolArray_(array, mirror_serializer) {
-  var json = [];
-  for (var i = 0; i < array.length; i++) {
-    json.push(ValueToProtocolValue_(array[i], mirror_serializer));
-  }
-  return json;
-}
-
-
-/**
- * Convert a value to its debugger protocol representation. 
- * @param {*} value The value to format as protocol value.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {*} Protocol value.
- */
-function ValueToProtocolValue_(value, mirror_serializer) {
-  // Format the value based on its type.
-  var json;
-  switch (typeof value) {
-    case 'object':
-      if (value instanceof Mirror) {
-        json = mirror_serializer.serializeValue(value);
-      } else if (IS_ARRAY(value)){
-        json = ArrayToProtocolArray_(value, mirror_serializer);
-      } else {
-        json = ObjectToProtocolObject_(value, mirror_serializer);
-      }
-      break;
-
-    case 'boolean':
-    case 'string':
-    case 'number':
-      json = value;
-      break
-
-    default:
-      json = null;
-  }
-  return json;
-}
diff --git a/src/debug.cc b/src/debug.cc
index 68f8d1e..c71a98f 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -31,6 +31,7 @@
 #include "arguments.h"
 #include "bootstrapper.h"
 #include "code-stubs.h"
+#include "codegen.h"
 #include "compilation-cache.h"
 #include "compiler.h"
 #include "debug.h"
@@ -453,15 +454,7 @@
 
 
 bool BreakLocationIterator::IsDebuggerStatement() {
-  if (RelocInfo::IsCodeTarget(rmode())) {
-    Address target = original_rinfo()->target_address();
-    Code* code = Code::GetCodeFromTargetAddress(target);
-    if (code->kind() == Code::STUB) {
-      CodeStub::Major major_key = code->major_key();
-      return (major_key == CodeStub::DebuggerStatement);
-    }
-  }
-  return false;
+  return RelocInfo::DEBUG_BREAK == rmode();
 }
 
 
@@ -696,6 +689,7 @@
                                   0,
                                   NULL,
                                   NULL,
+                                  Handle<String>::null(),
                                   NATIVES_CODE);
   FLAG_allow_natives_syntax = allow_natives_syntax;
 
diff --git a/src/execution.cc b/src/execution.cc
index a79af23..2068413 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -91,7 +91,7 @@
     JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
 
     // Call the function through the right JS entry stub.
-    byte* entry_address= func->code()->entry();
+    byte* entry_address = func->code()->entry();
     JSFunction* function = *func;
     Object* receiver_pointer = *receiver;
     value = CALL_GENERATED_CODE(entry, entry_address, function,
diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc
index 36d7297..602d6b8 100644
--- a/src/fast-codegen.cc
+++ b/src/fast-codegen.cc
@@ -89,10 +89,10 @@
 
 
 void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
-  for (int i = 0, len = stmts->length(); i < len; i++) {
-    Visit(stmts->at(i));
-    CHECK_BAILOUT;
+  if (stmts->length() != 1) {
+    BAILOUT("Function body is not a singleton statement.");
   }
+  Visit(stmts->at(0));
 }
 
 
@@ -220,8 +220,16 @@
   if (info()->has_global_object()) {
     LookupResult lookup;
     info()->global_object()->Lookup(*expr->name(), &lookup);
-    if (!lookup.IsValid() || !lookup.IsDontDelete()) {
-      BAILOUT("Non-existing or deletable global variable");
+    if (!lookup.IsProperty()) {
+      BAILOUT("Non-existing global variable");
+    }
+    // We do not handle global variables with accessors or interceptors.
+    if (lookup.type() != NORMAL) {
+      BAILOUT("Global variable with accessors or interceptors.");
+    }
+    // We do not handle deletable global variables.
+    if (!lookup.IsDontDelete()) {
+      BAILOUT("Deletable global variable");
     }
   }
 }
@@ -276,6 +284,9 @@
     Handle<String> name = Handle<String>::cast(key->handle());
     LookupResult lookup;
     receiver->Lookup(*name, &lookup);
+    if (!lookup.IsProperty()) {
+      BAILOUT("Assigned property not found at compile time");
+    }
     if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
     if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment");
   } else {
@@ -293,7 +304,33 @@
 
 
 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
-  BAILOUT("Property");
+  // We support named this property references.
+  VariableProxy* proxy = expr->obj()->AsVariableProxy();
+  if (proxy == NULL || !proxy->var()->is_this()) {
+    BAILOUT("Non-this-property reference");
+  }
+  if (!expr->key()->IsPropertyName()) {
+    BAILOUT("Non-named-property reference");
+  }
+
+  // We will only specialize for fields on the object itself.
+  // Expression::IsPropertyName implies that the name is a literal
+  // symbol but we do not assume that.
+  Literal* key = expr->key()->AsLiteral();
+  if (key != NULL && key->handle()->IsString()) {
+    Handle<Object> receiver = info()->receiver();
+    Handle<String> name = Handle<String>::cast(key->handle());
+    LookupResult lookup;
+    receiver->Lookup(*name, &lookup);
+    if (!lookup.IsProperty()) {
+      BAILOUT("Referenced property not found at compile time");
+    }
+    if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
+    if (!lookup.type() == FIELD) BAILOUT("Non-field property reference");
+  } else {
+    UNREACHABLE();
+    BAILOUT("Unexpected non-string-literal property key");
+  }
 }
 
 
@@ -323,7 +360,58 @@
 
 
 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
-  BAILOUT("BinaryOperation");
+  // We support bitwise OR.
+  switch (expr->op()) {
+    case Token::COMMA:
+      BAILOUT("BinaryOperation COMMA");
+    case Token::OR:
+      BAILOUT("BinaryOperation OR");
+    case Token::AND:
+      BAILOUT("BinaryOperation AND");
+
+    case Token::BIT_OR:
+      // We support expressions nested on the left because they only require
+      // a pair of registers to keep all intermediate values in registers
+      // (i.e., the expression stack has height no more than two).
+      if (!expr->right()->IsLeaf()) BAILOUT("expression nested on right");
+
+      // We do not allow subexpressions with side effects because we
+      // (currently) bail out to the beginning of the full function.  The
+      // only expressions with side effects that we would otherwise handle
+      // are assignments.
+      if (expr->left()->AsAssignment() != NULL ||
+          expr->right()->AsAssignment() != NULL) {
+        BAILOUT("subexpression of binary operation has side effects");
+      }
+
+      Visit(expr->left());
+      CHECK_BAILOUT;
+      Visit(expr->right());
+      break;
+
+    case Token::BIT_XOR:
+      BAILOUT("BinaryOperation BIT_XOR");
+    case Token::BIT_AND:
+      BAILOUT("BinaryOperation BIT_AND");
+    case Token::SHL:
+      BAILOUT("BinaryOperation SHL");
+    case Token::SAR:
+      BAILOUT("BinaryOperation SAR");
+    case Token::SHR:
+      BAILOUT("BinaryOperation SHR");
+    case Token::ADD:
+      BAILOUT("BinaryOperation ADD");
+    case Token::SUB:
+      BAILOUT("BinaryOperation SUB");
+    case Token::MUL:
+      BAILOUT("BinaryOperation MUL");
+    case Token::DIV:
+      BAILOUT("BinaryOperation DIV");
+    case Token::MOD:
+      BAILOUT("BinaryOperation MOD");
+    default:
+      UNREACHABLE();
+  }
 }
 
 
@@ -348,6 +436,9 @@
   AstLabeler labeler;
   labeler.Label(info);
 
+  LivenessAnalyzer analyzer;
+  analyzer.Analyze(info->function());
+
   CodeGenerator::MakeCodePrologue(info);
 
   const int kInitialBufferSize = 4 * KB;
@@ -365,7 +456,8 @@
   // macro assembler.
   CodeGenerator cgen(&masm);
   CodeGeneratorScope scope(&cgen);
-  cgen.Generate(info, CodeGenerator::SECONDARY);
+  info->set_mode(CompilationInfo::SECONDARY);
+  cgen.Generate(info);
   if (cgen.HasStackOverflow()) {
     ASSERT(!Top::has_pending_exception());
     return Handle<Code>::null();
@@ -489,21 +581,28 @@
 
 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   ASSERT(expr->var()->is_global() && !expr->var()->is_this());
-  Comment cmnt(masm(), ";; Global");
-  if (FLAG_print_ir) {
-    SmartPointer<char> name = expr->name()->ToCString();
-    PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
-  }
-
   // Check if we can compile a global variable load directly from the cell.
   ASSERT(info()->has_global_object());
   LookupResult lookup;
   info()->global_object()->Lookup(*expr->name(), &lookup);
-  // We only support DontDelete properties for now.
-  ASSERT(lookup.IsValid());
+  // We only support normal (non-accessor/interceptor) DontDelete properties
+  // for now.
+  ASSERT(lookup.IsProperty());
+  ASSERT_EQ(NORMAL, lookup.type());
   ASSERT(lookup.IsDontDelete());
   Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
-  EmitGlobalVariableLoad(cell);
+
+  // Global variable lookups do not have side effects, so we do not need to
+  // emit code if we are in an effect context.
+  if (!destination().is(no_reg)) {
+    Comment cmnt(masm(), ";; Global");
+    if (FLAG_print_ir) {
+      SmartPointer<char> name = expr->name()->ToCString();
+      PrintF("%d: t%d = Global(%s)  // last_use = %d\n", expr->num(),
+             expr->num(), *name, expr->var_def()->last_use()->num());
+    }
+    EmitGlobalVariableLoad(cell);
+  }
 }
 
 
@@ -533,8 +632,13 @@
 
 
 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
-  // Known to be a simple this property assignment.
-  Visit(expr->value());
+  // Known to be a simple this property assignment.  Effectively a unary
+  // operation.
+  { Register my_destination = destination();
+    set_destination(accumulator0());
+    Visit(expr->value());
+    set_destination(my_destination);
+  }
 
   Property* prop = expr->target()->AsProperty();
   ASSERT_NOT_NULL(prop);
@@ -544,11 +648,14 @@
   Handle<String> name =
       Handle<String>::cast(prop->key()->AsLiteral()->handle());
 
-  Comment cmnt(masm(), ";; Store(this)");
+  Comment cmnt(masm(), ";; Store to this");
   if (FLAG_print_ir) {
     SmartPointer<char> name_string = name->ToCString();
-    PrintF("%d: t%d = Store(this, \"%s\", t%d)\n",
-           expr->num(), expr->num(), *name_string, expr->value()->num());
+    PrintF("%d: ", expr->num());
+    if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+    PrintF("Store(this, \"%s\", t%d)  // last_use(this) = %d\n", *name_string,
+           expr->value()->num(),
+           expr->var_def()->last_use()->num());
   }
 
   EmitThisPropertyStore(name);
@@ -561,7 +668,22 @@
 
 
 void FastCodeGenerator::VisitProperty(Property* expr) {
-  UNREACHABLE();
+  ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
+  ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
+  ASSERT(expr->key()->IsPropertyName());
+  if (!destination().is(no_reg)) {
+    Handle<String> name =
+        Handle<String>::cast(expr->key()->AsLiteral()->handle());
+
+    Comment cmnt(masm(), ";; Load from this");
+    if (FLAG_print_ir) {
+      SmartPointer<char> name_string = name->ToCString();
+      PrintF("%d: t%d = Load(this, \"%s\")  // last_use(this) = %d\n",
+             expr->num(), expr->num(), *name_string,
+             expr->var_def()->last_use()->num());
+    }
+    EmitThisPropertyLoad(name);
+  }
 }
 
 
@@ -591,7 +713,26 @@
 
 
 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
-  UNREACHABLE();
+  // We support limited binary operations: bitwise OR only allowed to be
+  // nested on the left.
+  ASSERT(expr->op() == Token::BIT_OR);
+  ASSERT(expr->right()->IsLeaf());
+
+  { Register my_destination = destination();
+    set_destination(accumulator1());
+    Visit(expr->left());
+    set_destination(accumulator0());
+    Visit(expr->right());
+    set_destination(my_destination);
+  }
+
+  Comment cmnt(masm(), ";; BIT_OR");
+  if (FLAG_print_ir) {
+    PrintF("%d: ", expr->num());
+    if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+    PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
+  }
+  EmitBitOr();
 }
 
 
diff --git a/src/fast-codegen.h b/src/fast-codegen.h
index cbcb5bf..e96daf6 100644
--- a/src/fast-codegen.h
+++ b/src/fast-codegen.h
@@ -28,10 +28,15 @@
 #ifndef V8_FAST_CODEGEN_H_
 #define V8_FAST_CODEGEN_H_
 
+#if V8_TARGET_ARCH_IA32
+#include "ia32/fast-codegen-ia32.h"
+#else
+
 #include "v8.h"
 
 #include "ast.h"
 #include "compiler.h"
+#include "list.h"
 
 namespace v8 {
 namespace internal {
@@ -65,7 +70,9 @@
 
 class FastCodeGenerator: public AstVisitor {
  public:
-  explicit FastCodeGenerator(MacroAssembler* masm) : masm_(masm), info_(NULL) {}
+  explicit FastCodeGenerator(MacroAssembler* masm)
+      : masm_(masm), info_(NULL), destination_(no_reg), smi_bits_(0) {
+  }
 
   static Handle<Code> MakeCode(CompilationInfo* info);
 
@@ -74,42 +81,73 @@
  private:
   MacroAssembler* masm() { return masm_; }
   CompilationInfo* info() { return info_; }
-  Label* bailout() { return &bailout_; }
+
+  Register destination() { return destination_; }
+  void set_destination(Register reg) { destination_ = reg; }
 
   FunctionLiteral* function() { return info_->function(); }
   Scope* scope() { return info_->scope(); }
 
+  // Platform-specific fixed registers, all guaranteed distinct.
+  Register accumulator0();
+  Register accumulator1();
+  Register scratch0();
+  Register scratch1();
+  Register receiver_reg();
+  Register context_reg();
+
+  Register other_accumulator(Register reg) {
+    ASSERT(reg.is(accumulator0()) || reg.is(accumulator1()));
+    return (reg.is(accumulator0())) ? accumulator1() : accumulator0();
+  }
+
+  // Flags are true if the respective register is statically known to hold a
+  // smi.  We do not track every register, only the accumulator registers.
+  bool is_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    return (smi_bits_ & reg.bit()) != 0;
+  }
+  void set_as_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    smi_bits_ = smi_bits_ | reg.bit();
+  }
+  void clear_as_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    smi_bits_ = smi_bits_ & ~reg.bit();
+  }
+
   // AST node visit functions.
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
-  // Emit code to load the receiver from the stack into a given register.
-  void EmitLoadReceiver(Register reg);
+  // Emit code to load the receiver from the stack into receiver_reg.
+  void EmitLoadReceiver();
 
-  // Emit code to check that the receiver has the same map as the
-  // compile-time receiver.  Receiver is expected in {ia32-edx, x64-rdx,
-  // arm-r1}.  Emit a branch to the (single) bailout label if check fails.
-  void EmitReceiverMapCheck();
-
-  // Emit code to check that the global object has the same map as the
-  // global object seen at compile time.
-  void EmitGlobalMapCheck();
-
-  // Emit code to load a global variable directly from a global
-  // property cell into {ia32-eax, x64-rax, arm-r0}.
+  // Emit code to load a global variable directly from a global property
+  // cell into the destination register.
   void EmitGlobalVariableLoad(Handle<Object> cell);
 
   // Emit a store to an own property of this.  The stored value is expected
-  // in {ia32-eax, x64-rax, arm-r0} and the receiver in {is32-edx, x64-rdx,
-  // arm-r1}.  Both are preserve.
+  // in accumulator0 and the receiver in receiver_reg.  The receiver
+  // register is preserved and the result (the stored value) is left in the
+  // destination register.
   void EmitThisPropertyStore(Handle<String> name);
 
+  // Emit a load from an own property of this.  The receiver is expected in
+  // receiver_reg.  The receiver register is preserved and the result is
+  // left in the destination register.
+  void EmitThisPropertyLoad(Handle<String> name);
+
+  // Emit a bitwise or operation.  The left operand is in accumulator1 and
+  // the right is in accumulator0.  The result should be left in the
+  // destination register.
+  void EmitBitOr();
+
   MacroAssembler* masm_;
-
   CompilationInfo* info_;
-
-  Label bailout_;
+  Register destination_;
+  uint32_t smi_bits_;
 
   DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator);
 };
@@ -117,4 +155,6 @@
 
 } }  // namespace v8::internal
 
+#endif  // V8_TARGET_ARCH_IA32
+
 #endif  // V8_FAST_CODEGEN_H_
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 9afdea4..dbb9ce7 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -384,7 +384,7 @@
 DEFINE_bool(log_regexp, false, "Log regular expression execution.")
 DEFINE_bool(sliding_state_window, false,
             "Update sliding state window counters.")
-DEFINE_string(logfile, "/sdcard/v8.log", "Specify the name of the log file.")
+DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
 DEFINE_bool(oprofile, false, "Enable JIT agent for OProfile.")
 
 //
diff --git a/src/frame-element.cc b/src/frame-element.cc
index e6bc2ea..1455559 100644
--- a/src/frame-element.cc
+++ b/src/frame-element.cc
@@ -32,10 +32,6 @@
 namespace v8 {
 namespace internal {
 
-// -------------------------------------------------------------------------
-// FrameElement implementation.
-
-
 FrameElement::ZoneObjectList* FrameElement::ConstantList() {
   static ZoneObjectList list(10);
   return &list;
diff --git a/src/frame-element.h b/src/frame-element.h
index ccdecf1..5762814 100644
--- a/src/frame-element.h
+++ b/src/frame-element.h
@@ -28,7 +28,8 @@
 #ifndef V8_FRAME_ELEMENT_H_
 #define V8_FRAME_ELEMENT_H_
 
-#include "register-allocator-inl.h"
+#include "number-info.h"
+#include "macro-assembler.h"
 
 namespace v8 {
 namespace internal {
@@ -52,11 +53,31 @@
     SYNCED
   };
 
+  inline NumberInfo::Type number_info() {
+    // Copied elements do not have number info. Instead
+    // we have to inspect their backing element in the frame.
+    ASSERT(!is_copy());
+    if (!is_constant()) return NumberInfoField::decode(value_);
+    Handle<Object> value = handle();
+    if (value->IsSmi()) return NumberInfo::kSmi;
+    if (value->IsHeapNumber()) return NumberInfo::kHeapNumber;
+    return NumberInfo::kUnknown;
+  }
+
+  inline void set_number_info(NumberInfo::Type info) {
+    // Copied elements do not have number info. Instead
+    // we have to inspect their backing element in the frame.
+    ASSERT(!is_copy());
+    value_ = value_ & ~NumberInfoField::mask();
+    value_ = value_ | NumberInfoField::encode(info);
+  }
+
   // The default constructor creates an invalid frame element.
   FrameElement() {
     value_ = TypeField::encode(INVALID)
         | CopiedField::encode(false)
         | SyncedField::encode(false)
+        | NumberInfoField::encode(NumberInfo::kUninitialized)
         | DataField::encode(0);
   }
 
@@ -67,15 +88,16 @@
   }
 
   // Factory function to construct an in-memory frame element.
-  static FrameElement MemoryElement() {
-    FrameElement result(MEMORY, no_reg, SYNCED);
+  static FrameElement MemoryElement(NumberInfo::Type info) {
+    FrameElement result(MEMORY, no_reg, SYNCED, info);
     return result;
   }
 
   // Factory function to construct an in-register frame element.
   static FrameElement RegisterElement(Register reg,
-                                      SyncFlag is_synced) {
-    return FrameElement(REGISTER, reg, is_synced);
+                                      SyncFlag is_synced,
+                                      NumberInfo::Type info) {
+    return FrameElement(REGISTER, reg, is_synced, info);
   }
 
   // Factory function to construct a frame element whose value is known at
@@ -185,10 +207,14 @@
   };
 
   // Used to construct memory and register elements.
-  FrameElement(Type type, Register reg, SyncFlag is_synced) {
+  FrameElement(Type type,
+               Register reg,
+               SyncFlag is_synced,
+               NumberInfo::Type info) {
     value_ = TypeField::encode(type)
         | CopiedField::encode(false)
         | SyncedField::encode(is_synced != NOT_SYNCED)
+        | NumberInfoField::encode(info)
         | DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
   }
 
@@ -197,6 +223,7 @@
     value_ = TypeField::encode(CONSTANT)
         | CopiedField::encode(false)
         | SyncedField::encode(is_synced != NOT_SYNCED)
+        | NumberInfoField::encode(NumberInfo::kUninitialized)
         | DataField::encode(ConstantList()->length());
     ConstantList()->Add(value);
   }
@@ -223,9 +250,10 @@
   uint32_t value_;
 
   class TypeField: public BitField<Type, 0, 3> {};
-  class CopiedField: public BitField<uint32_t, 3, 1> {};
-  class SyncedField: public BitField<uint32_t, 4, 1> {};
-  class DataField: public BitField<uint32_t, 5, 32 - 6> {};
+  class CopiedField: public BitField<bool, 3, 1> {};
+  class SyncedField: public BitField<bool, 4, 1> {};
+  class NumberInfoField: public BitField<NumberInfo::Type, 5, 3> {};
+  class DataField: public BitField<uint32_t, 8, 32 - 8> {};
 
   friend class VirtualFrame;
 };
diff --git a/src/frames.cc b/src/frames.cc
index 0550740..06896ea 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -410,12 +410,7 @@
 
 
 Code* ExitFrame::code() const {
-  Object* code = code_slot();
-  if (code->IsSmi()) {
-    return Heap::debugger_statement_code();
-  } else {
-    return Code::cast(code);
-  }
+  return Code::cast(code_slot());
 }
 
 
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 22510e9..6371439 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -32,6 +32,7 @@
 #include "full-codegen.h"
 #include "stub-cache.h"
 #include "debug.h"
+#include "liveedit.h"
 
 namespace v8 {
 namespace internal {
@@ -448,6 +449,8 @@
   CodeGenerator::MakeCodePrologue(info);
   const int kInitialBufferSize = 4 * KB;
   MacroAssembler masm(NULL, kInitialBufferSize);
+  LiveEditFunctionTracker live_edit_tracker(info->function());
+
   FullCodeGenerator cgen(&masm);
   cgen.Generate(info, PRIMARY);
   if (cgen.HasStackOverflow()) {
@@ -455,7 +458,9 @@
     return Handle<Code>::null();
   }
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
-  return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
+  Handle<Code> result = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
+  live_edit_tracker.RecordFunctionCode(result);
+  return result;
 }
 
 
@@ -986,8 +991,7 @@
   Comment cmnt(masm_, "[ DebuggerStatement");
   SetStatementPosition(stmt);
 
-  DebuggerStatementStub ces;
-  __ CallStub(&ces);
+  __ DebugBreak();
   // Ignore the return value.
 #endif
 }
@@ -1032,86 +1036,6 @@
 }
 
 
-void FullCodeGenerator::VisitAssignment(Assignment* expr) {
-  Comment cmnt(masm_, "[ Assignment");
-  ASSERT(expr->op() != Token::INIT_CONST);
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
-  Property* prop = expr->target()->AsProperty();
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
-
-  // Evaluate LHS expression.
-  switch (assign_type) {
-    case VARIABLE:
-      // Nothing to do here.
-      break;
-    case NAMED_PROPERTY:
-      VisitForValue(prop->obj(), kStack);
-      break;
-    case KEYED_PROPERTY:
-      VisitForValue(prop->obj(), kStack);
-      VisitForValue(prop->key(), kStack);
-      break;
-  }
-
-  // If we have a compound assignment: Get value of LHS expression and
-  // store in on top of the stack.
-  if (expr->is_compound()) {
-    Location saved_location = location_;
-    location_ = kStack;
-    switch (assign_type) {
-      case VARIABLE:
-        EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
-                         Expression::kValue);
-        break;
-      case NAMED_PROPERTY:
-        EmitNamedPropertyLoad(prop);
-        __ push(result_register());
-        break;
-      case KEYED_PROPERTY:
-        EmitKeyedPropertyLoad(prop);
-        __ push(result_register());
-        break;
-    }
-    location_ = saved_location;
-  }
-
-  // Evaluate RHS expression.
-  Expression* rhs = expr->value();
-  VisitForValue(rhs, kAccumulator);
-
-  // If we have a compound assignment: Apply operator.
-  if (expr->is_compound()) {
-    Location saved_location = location_;
-    location_ = kAccumulator;
-    EmitBinaryOp(expr->binary_op(), Expression::kValue);
-    location_ = saved_location;
-  }
-
-  // Record source position before possible IC call.
-  SetSourcePosition(expr->position());
-
-  // Store the value.
-  switch (assign_type) {
-    case VARIABLE:
-      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
-                             context_);
-      break;
-    case NAMED_PROPERTY:
-      EmitNamedPropertyAssignment(expr);
-      break;
-    case KEYED_PROPERTY:
-      EmitKeyedPropertyAssignment(expr);
-      break;
-  }
-}
-
-
 void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
   // Call runtime routine to allocate the catch extension object and
   // assign the exception value to the catch variable.
diff --git a/src/handles.cc b/src/handles.cc
index 05f561e..c9a2877 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -309,6 +309,12 @@
 }
 
 
+Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) {
+  const bool skip_hidden_prototypes = false;
+  CALL_HEAP_FUNCTION(obj->SetPrototype(*value, skip_hidden_prototypes), Object);
+}
+
+
 Handle<Object> GetHiddenProperties(Handle<JSObject> obj,
                                    bool create_if_needed) {
   Object* holder = obj->BypassGlobalProxy();
@@ -486,25 +492,25 @@
 int GetScriptLineNumber(Handle<Script> script, int code_pos) {
   InitScriptLineEnds(script);
   AssertNoAllocation no_allocation;
-  FixedArray* line_ends_array =
-      FixedArray::cast(script->line_ends());
+  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
   const int line_ends_len = line_ends_array->length();
 
-  int line = -1;
-  if (line_ends_len > 0 &&
-      code_pos <= (Smi::cast(line_ends_array->get(0)))->value()) {
-    line = 0;
-  } else {
-    for (int i = 1; i < line_ends_len; ++i) {
-      if ((Smi::cast(line_ends_array->get(i - 1)))->value() < code_pos &&
-          code_pos <= (Smi::cast(line_ends_array->get(i)))->value()) {
-        line = i;
-        break;
-      }
+  if (!line_ends_len)
+    return -1;
+
+  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos)
+    return script->line_offset()->value();
+
+  int left = 0;
+  int right = line_ends_len;
+  while (int half = (right - left) / 2) {
+    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
+      right -= half;
+    } else {
+      left += half;
     }
   }
-
-  return line != -1 ? line + script->line_offset()->value() : line;
+  return right + script->line_offset()->value();
 }
 
 
diff --git a/src/handles.h b/src/handles.h
index caa9966..7902909 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -245,6 +245,8 @@
 
 Handle<Object> GetPrototype(Handle<Object> obj);
 
+Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value);
+
 // Return the object's hidden properties object. If the object has no hidden
 // properties and create_if_needed is true, then a new hidden property object
 // will be allocated. Otherwise the Heap::undefined_value is returned.
diff --git a/src/heap.cc b/src/heap.cc
index 7263e23..cfb786a 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1498,14 +1498,6 @@
 #endif
 
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
-void Heap::CreateCEntryDebugBreakStub() {
-  DebuggerStatementStub stub;
-  set_debugger_statement_code(*stub.GetCode());
-}
-#endif
-
-
 void Heap::CreateJSEntryStub() {
   JSEntryStub stub;
   set_js_entry_code(*stub.GetCode());
@@ -1533,9 +1525,6 @@
   // }
   // To workaround the problem, make separate functions without inlining.
   Heap::CreateCEntryStub();
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  Heap::CreateCEntryDebugBreakStub();
-#endif
   Heap::CreateJSEntryStub();
   Heap::CreateJSConstructEntryStub();
 #if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP
@@ -1778,6 +1767,7 @@
 
 
 Object* Heap::NumberToString(Object* number) {
+  Counters::number_to_string_runtime.Increment();
   Object* cached = GetNumberStringCache(number);
   if (cached != undefined_value()) {
     return cached;
@@ -2393,12 +2383,13 @@
   map->set_unused_property_fields(in_object_properties);
   map->set_prototype(prototype);
 
-  // If the function has only simple this property assignments add field
-  // descriptors for these to the initial map as the object cannot be
-  // constructed without having these properties.
+  // If the function has only simple this property assignments add
+  // field descriptors for these to the initial map as the object
+  // cannot be constructed without having these properties.  Guard by
+  // the inline_new flag so we only change the map if we generate a
+  // specialized construct stub.
   ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields);
-  if (fun->shared()->has_only_simple_this_property_assignments() &&
-      fun->shared()->this_property_assignments_count() > 0) {
+  if (fun->shared()->CanGenerateInlineConstructor(prototype)) {
     int count = fun->shared()->this_property_assignments_count();
     if (count > in_object_properties) {
       count = in_object_properties;
@@ -4120,7 +4111,7 @@
   // Uses only lower 32 bits if pointers are larger.
   uintptr_t addr_hash =
       static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift;
-  return (addr_hash ^ name->Hash()) & kCapacityMask;
+  return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask);
 }
 
 
diff --git a/src/heap.h b/src/heap.h
index 7e1a743..b107318 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -101,7 +101,6 @@
   V(Code, js_entry_code, JsEntryCode)                                          \
   V(Code, js_construct_entry_code, JsConstructEntryCode)                       \
   V(Code, c_entry_code, CEntryCode)                                            \
-  V(Code, debugger_statement_code, DebuggerStatementCode)                      \
   V(FixedArray, number_string_cache, NumberStringCache)                        \
   V(FixedArray, single_character_string_cache, SingleCharacterStringCache)     \
   V(FixedArray, natives_source_cache, NativesSourceCache)                      \
@@ -1051,7 +1050,6 @@
   // These four Create*EntryStub functions are here because of a gcc-4.4 bug
   // that assigns wrong vtable entries.
   static void CreateCEntryStub();
-  static void CreateCEntryDebugBreakStub();
   static void CreateJSEntryStub();
   static void CreateJSConstructEntryStub();
   static void CreateRegExpCEntryStub();
@@ -1390,9 +1388,9 @@
  private:
   static int Hash(DescriptorArray* array, String* name) {
     // Uses only lower 32 bits if pointers are larger.
-    uintptr_t array_hash =
+    uint32_t array_hash =
         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2;
-    uintptr_t name_hash =
+    uint32_t name_hash =
         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2;
     return (array_hash ^ name_hash) % kLength;
   }
@@ -1617,6 +1615,7 @@
     if (e.in[0] == c.integers[0] &&
         e.in[1] == c.integers[1]) {
       ASSERT(e.output != NULL);
+      Counters::transcendental_cache_hit.Increment();
       return e.output;
     }
     double answer = Calculate(input);
@@ -1626,6 +1625,7 @@
       elements_[hash].in[1] = c.integers[1];
       elements_[hash].output = heap_number;
     }
+    Counters::transcendental_cache_miss.Increment();
     return heap_number;
   }
 
@@ -1666,6 +1666,17 @@
     hash ^= hash >> 8;
     return (hash & (kCacheSize - 1));
   }
+
+  static Address cache_array_address() {
+    // Used to create an external reference.
+    return reinterpret_cast<Address>(caches_);
+  }
+
+  // Allow access to the caches_ array as an ExternalReference.
+  friend class ExternalReference;
+  // Inline implementation of the caching.
+  friend class TranscendentalCacheStub;
+
   static TranscendentalCache* caches_[kNumberOfCaches];
   Element elements_[kCacheSize];
   Type type_;
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index ffcefe0..89708aa 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -1637,6 +1637,13 @@
 }
 
 
+void Assembler::fstp(int i) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_farith(0xDD, 0xD8, i);
+}
+
+
 void Assembler::fld1() {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
@@ -1645,6 +1652,14 @@
 }
 
 
+void Assembler::fldpi() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xD9);
+  EMIT(0xEB);
+}
+
+
 void Assembler::fldz() {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
@@ -1685,6 +1700,14 @@
 }
 
 
+void Assembler::fst_d(const Operand& adr) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xDD);
+  emit_operand(edx, adr);
+}
+
+
 void Assembler::fild_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index f0cf4f1..36aad5e 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -231,7 +231,8 @@
   times_8 = 3,
   times_int_size = times_4,
   times_half_pointer_size = times_2,
-  times_pointer_size = times_4
+  times_pointer_size = times_4,
+  times_twice_pointer_size = times_8
 };
 
 
@@ -667,6 +668,7 @@
   void call(Label* L);
   void call(byte* entry, RelocInfo::Mode rmode);
   void call(const Operand& adr);
+  void call(const ExternalReference& target);
   void call(Handle<Code> code, RelocInfo::Mode rmode);
 
   // Jumps
@@ -682,15 +684,18 @@
 
   // Floating-point operations
   void fld(int i);
+  void fstp(int i);
 
   void fld1();
   void fldz();
+  void fldpi();
 
   void fld_s(const Operand& adr);
   void fld_d(const Operand& adr);
 
   void fstp_s(const Operand& adr);
   void fstp_d(const Operand& adr);
+  void fst_d(const Operand& adr);
 
   void fild_s(const Operand& adr);
   void fild_d(const Operand& adr);
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 2c5b1d1..54ef382 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -93,7 +93,10 @@
   // edi: called object
   // eax: number of arguments
   __ bind(&non_function_call);
-
+  // CALL_NON_FUNCTION expects the non-function constructor as receiver
+  // (instead of the original receiver from the call site).  The receiver is
+  // stack element argc+1.
+  __ mov(Operand(esp, eax, times_4, kPointerSize), edi);
   // Set expected number of arguments to zero (not changing eax).
   __ Set(ebx, Immediate(0));
   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
@@ -437,33 +440,26 @@
     __ bind(&done);
   }
 
-  // 2. Get the function to call from the stack.
-  { Label done, non_function, function;
-    // +1 ~ return address.
-    __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));
-    __ test(edi, Immediate(kSmiTagMask));
-    __ j(zero, &non_function, not_taken);
-    __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
-    __ j(equal, &function, taken);
+  // 2. Get the function to call (passed as receiver) from the stack, check
+  //    if it is a function.
+  Label non_function;
+  // 1 ~ return address.
+  __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
+  __ test(edi, Immediate(kSmiTagMask));
+  __ j(zero, &non_function, not_taken);
+  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+  __ j(not_equal, &non_function, not_taken);
 
-    // Non-function called: Clear the function to force exception.
-    __ bind(&non_function);
-    __ xor_(edi, Operand(edi));
-    __ jmp(&done);
 
-    // Function called: Change context eagerly to get the right global object.
-    __ bind(&function);
+  // 3a. Patch the first argument if necessary when calling a function.
+  Label shift_arguments;
+  { Label convert_to_object, use_global_receiver, patch_receiver;
+    // Change context eagerly in case we need the global receiver.
     __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
-    __ bind(&done);
-  }
-
-  // 3. Make sure first argument is an object; convert if necessary.
-  { Label call_to_object, use_global_receiver, patch_receiver, done;
-    __ mov(ebx, Operand(esp, eax, times_4, 0));
-
+    __ mov(ebx, Operand(esp, eax, times_4, 0));  // First argument.
     __ test(ebx, Immediate(kSmiTagMask));
-    __ j(zero, &call_to_object);
+    __ j(zero, &convert_to_object);
 
     __ cmp(ebx, Factory::null_value());
     __ j(equal, &use_global_receiver);
@@ -473,31 +469,28 @@
     __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
     __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
     __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
-    __ j(less, &call_to_object);
+    __ j(below, &convert_to_object);
     __ cmp(ecx, LAST_JS_OBJECT_TYPE);
-    __ j(less_equal, &done);
+    __ j(below_equal, &shift_arguments);
 
-    __ bind(&call_to_object);
-    __ EnterInternalFrame();  // preserves eax, ebx, edi
-
-    // Store the arguments count on the stack (smi tagged).
+    __ bind(&convert_to_object);
+    __ EnterInternalFrame();  // In order to preserve argument count.
     __ SmiTag(eax);
     __ push(eax);
 
-    __ push(edi);  // save edi across the call
     __ push(ebx);
     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
     __ mov(ebx, eax);
-    __ pop(edi);  // restore edi after the call
 
-    // Get the arguments count and untag it.
     __ pop(eax);
     __ SmiUntag(eax);
-
     __ LeaveInternalFrame();
+    // Restore the function to edi.
+    __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
     __ jmp(&patch_receiver);
 
-    // Use the global receiver object from the called function as the receiver.
+    // Use the global receiver object from the called function as the
+    // receiver.
     __ bind(&use_global_receiver);
     const int kGlobalIndex =
         Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
@@ -509,50 +502,55 @@
     __ bind(&patch_receiver);
     __ mov(Operand(esp, eax, times_4, 0), ebx);
 
-    __ bind(&done);
+    __ jmp(&shift_arguments);
   }
 
-  // 4. Check that the function really is a function.
-  { Label done;
-    __ test(edi, Operand(edi));
-    __ j(not_zero, &done, taken);
-    __ xor_(ebx, Operand(ebx));
-    // CALL_NON_FUNCTION will expect to find the non-function callee on the
-    // expression stack of the caller.  Transfer it from receiver to the
-    // caller's expression stack (and make the first argument the receiver
-    // for CALL_NON_FUNCTION) by decrementing the argument count.
-    __ dec(eax);
-    __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
-    __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
-           RelocInfo::CODE_TARGET);
-    __ bind(&done);
-  }
+  // 3b. Patch the first argument when calling a non-function.  The
+  //     CALL_NON_FUNCTION builtin expects the non-function callee as
+  //     receiver, so overwrite the first argument which will ultimately
+  //     become the receiver.
+  __ bind(&non_function);
+  __ mov(Operand(esp, eax, times_4, 0), edi);
+  // Clear edi to indicate a non-function being called.
+  __ xor_(edi, Operand(edi));
 
-  // 5. Shift arguments and return address one slot down on the stack
-  //    (overwriting the receiver).
+  // 4. Shift arguments and return address one slot down on the stack
+  //    (overwriting the original receiver).  Adjust argument count to make
+  //    the original first argument the new receiver.
+  __ bind(&shift_arguments);
   { Label loop;
     __ mov(ecx, eax);
     __ bind(&loop);
     __ mov(ebx, Operand(esp, ecx, times_4, 0));
     __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
     __ dec(ecx);
-    __ j(not_sign, &loop);
+    __ j(not_sign, &loop);  // While non-negative (to copy return address).
     __ pop(ebx);  // Discard copy of return address.
     __ dec(eax);  // One fewer argument (first argument is new receiver).
   }
 
-  // 6. Get the code to call from the function and check that the number of
-  //    expected arguments matches what we're providing.
-  { __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-    __ mov(ebx,
-           FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
-    __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
-    __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-    __ cmp(eax, Operand(ebx));
-    __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline)));
+  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
+  { Label function;
+    __ test(edi, Operand(edi));
+    __ j(not_zero, &function, taken);
+    __ xor_(ebx, Operand(ebx));
+    __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+    __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
+           RelocInfo::CODE_TARGET);
+    __ bind(&function);
   }
 
-  // 7. Jump (tail-call) to the code in register edx without checking arguments.
+  // 5b. Get the code to call from the function and check that the number of
+  //     expected arguments matches what we're providing.  If so, jump
+  //     (tail-call) to the code in register edx without checking arguments.
+  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+  __ mov(ebx,
+         FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
+  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
+  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+  __ cmp(eax, Operand(ebx));
+  __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline)));
+
   ParameterCount expected(0);
   __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
 }
@@ -647,9 +645,7 @@
   __ mov(eax, Operand(ebp, kIndexOffset));
   __ jmp(&entry);
   __ bind(&loop);
-  __ mov(ecx, Operand(ebp, 2 * kPointerSize));  // load arguments
-  __ push(ecx);
-  __ push(eax);
+  __ mov(edx, Operand(ebp, 2 * kPointerSize));  // load arguments
 
   // Use inline caching to speed up access to arguments.
   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
@@ -659,8 +655,7 @@
   // we have generated an inline version of the keyed load.  In this
   // case, we know that we are not generating a test instruction next.
 
-  // Remove IC arguments from the stack and push the nth argument.
-  __ add(Operand(esp), Immediate(2 * kPointerSize));
+  // Push the nth argument.
   __ push(eax);
 
   // Update the index on the stack and in register eax.
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index d0fbabb..ecb4c49 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -125,7 +125,7 @@
 // edi: called JS function
 // esi: callee's context
 
-void CodeGenerator::Generate(CompilationInfo* info, Mode mode) {
+void CodeGenerator::Generate(CompilationInfo* info) {
   // Record the position for debugging purposes.
   CodeForFunctionPosition(info->function());
 
@@ -164,7 +164,7 @@
     // esi: callee's context
     allocator_->Initialize();
 
-    if (mode == PRIMARY) {
+    if (info->mode() == CompilationInfo::PRIMARY) {
       frame_->Enter();
 
       // Allocate space for locals and initialize them.
@@ -255,6 +255,12 @@
       // frame to match this state.
       frame_->Adjust(3);
       allocator_->Unuse(edi);
+
+      // Bind all the bailout labels to the beginning of the function.
+      List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
+      for (int i = 0; i < bailouts->length(); i++) {
+        __ bind(bailouts->at(i)->label());
+      }
     }
 
     // Initialize the function return target after the locals are set
@@ -574,7 +580,9 @@
   } else if (variable != NULL && variable->slot() != NULL) {
     // For a variable that rewrites to a slot, we signal it is the immediate
     // subexpression of a typeof.
-    LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
+    Result result =
+        LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
+    frame()->Push(&result);
   } else {
     // Anything else can be handled normally.
     Load(expr);
@@ -623,8 +631,7 @@
     // We have to skip storing into the arguments slot if it has already
     // been written to. This can happen if the a function has a local
     // variable named 'arguments'.
-    LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
-    Result probe = frame_->Pop();
+    Result probe = LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
     if (probe.is_constant()) {
       // We have to skip updating the arguments object if it has
       // been assigned a proper value.
@@ -688,6 +695,11 @@
     // The expression is a variable proxy that does not rewrite to a
     // property.  Global variables are treated as named property references.
     if (var->is_global()) {
+      // If eax is free, the register allocator prefers it.  Thus the code
+      // generator will load the global object into eax, which is where
+      // LoadIC wants it.  Most uses of Reference call LoadIC directly
+      // after the reference is created.
+      frame_->Spill(eax);
       LoadGlobal();
       ref->set_type(Reference::NAMED);
     } else {
@@ -721,35 +733,54 @@
   // The value to convert should be popped from the frame.
   Result value = frame_->Pop();
   value.ToRegister();
-  // Fast case checks.
 
-  // 'false' => false.
-  __ cmp(value.reg(), Factory::false_value());
-  dest->false_target()->Branch(equal);
+  if (value.is_number()) {
+    Comment cmnt(masm_, "ONLY_NUMBER");
+    // Fast case if NumberInfo indicates only numbers.
+    if (FLAG_debug_code) {
+      __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
+    }
+    // Smi => false iff zero.
+    ASSERT(kSmiTag == 0);
+    __ test(value.reg(), Operand(value.reg()));
+    dest->false_target()->Branch(zero);
+    __ test(value.reg(), Immediate(kSmiTagMask));
+    dest->true_target()->Branch(zero);
+    __ fldz();
+    __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset));
+    __ FCmp();
+    value.Unuse();
+    dest->Split(not_zero);
+  } else {
+    // Fast case checks.
+    // 'false' => false.
+    __ cmp(value.reg(), Factory::false_value());
+    dest->false_target()->Branch(equal);
 
-  // 'true' => true.
-  __ cmp(value.reg(), Factory::true_value());
-  dest->true_target()->Branch(equal);
+    // 'true' => true.
+    __ cmp(value.reg(), Factory::true_value());
+    dest->true_target()->Branch(equal);
 
-  // 'undefined' => false.
-  __ cmp(value.reg(), Factory::undefined_value());
-  dest->false_target()->Branch(equal);
+    // 'undefined' => false.
+    __ cmp(value.reg(), Factory::undefined_value());
+    dest->false_target()->Branch(equal);
 
-  // Smi => false iff zero.
-  ASSERT(kSmiTag == 0);
-  __ test(value.reg(), Operand(value.reg()));
-  dest->false_target()->Branch(zero);
-  __ test(value.reg(), Immediate(kSmiTagMask));
-  dest->true_target()->Branch(zero);
+    // Smi => false iff zero.
+    ASSERT(kSmiTag == 0);
+    __ test(value.reg(), Operand(value.reg()));
+    dest->false_target()->Branch(zero);
+    __ test(value.reg(), Immediate(kSmiTagMask));
+    dest->true_target()->Branch(zero);
 
-  // Call the stub for all other cases.
-  frame_->Push(&value);  // Undo the Pop() from above.
-  ToBooleanStub stub;
-  Result temp = frame_->CallStub(&stub, 1);
-  // Convert the result to a condition code.
-  __ test(temp.reg(), Operand(temp.reg()));
-  temp.Unuse();
-  dest->Split(not_equal);
+    // Call the stub for all other cases.
+    frame_->Push(&value);  // Undo the Pop() from above.
+    ToBooleanStub stub;
+    Result temp = frame_->CallStub(&stub, 1);
+    // Convert the result to a condition code.
+    __ test(temp.reg(), Operand(temp.reg()));
+    temp.Unuse();
+    dest->Split(not_equal);
+  }
 }
 
 
@@ -789,6 +820,10 @@
   static void LoadAsIntegers(MacroAssembler* masm,
                              bool use_sse3,
                              Label* operand_conversion_failure);
+  // Test if operands are smis or heap numbers and load them
+  // into xmm0 and xmm1 if they are. Operands are in edx and eax.
+  // Leaves operands unchanged.
+  static void LoadSSE2Operands(MacroAssembler* masm);
   // Test if operands are numbers (smi or HeapNumber objects), and load
   // them into xmm0 and xmm1 if they are.  Jump to label not_numbers if
   // either operand is not a number.  Operands are in edx and eax.
@@ -816,12 +851,13 @@
   }
 
   OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "GenericBinaryOpStub_%s_%s%s_%s%s",
+               "GenericBinaryOpStub_%s_%s%s_%s%s_%s",
                op_name,
                overwrite_name,
                (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
                args_in_registers_ ? "RegArgs" : "StackArgs",
-               args_reversed_ ? "_R" : "");
+               args_reversed_ ? "_R" : "",
+               NumberInfo::ToString(operands_type_));
   return name_;
 }
 
@@ -971,27 +1007,35 @@
     // Neither operand is known to be a string.
   }
 
-  bool left_is_smi = left.is_constant() && left.handle()->IsSmi();
-  bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi();
-  bool right_is_smi = right.is_constant() && right.handle()->IsSmi();
-  bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi();
+  bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi();
+  bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi();
+  bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi();
+  bool right_is_non_smi_constant =
+      right.is_constant() && !right.handle()->IsSmi();
 
-  if (left_is_smi && right_is_smi) {
+  if (left_is_smi_constant && right_is_smi_constant) {
     // Compute the constant result at compile time, and leave it on the frame.
     int left_int = Smi::cast(*left.handle())->value();
     int right_int = Smi::cast(*right.handle())->value();
     if (FoldConstantSmis(op, left_int, right_int)) return;
   }
 
+  // Get number type of left and right sub-expressions.
+  NumberInfo::Type operands_type =
+      NumberInfo::Combine(left.number_info(), right.number_info());
+
   Result answer;
-  if (left_is_non_smi || right_is_non_smi) {
+  if (left_is_non_smi_constant || right_is_non_smi_constant) {
     // Go straight to the slow case, with no smi code.
-    GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB);
+    GenericBinaryOpStub stub(op,
+                             overwrite_mode,
+                             NO_SMI_CODE_IN_STUB,
+                             operands_type);
     answer = stub.GenerateCall(masm_, frame_, &left, &right);
-  } else if (right_is_smi) {
+  } else if (right_is_smi_constant) {
     answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
                                         type, false, overwrite_mode);
-  } else if (left_is_smi) {
+  } else if (left_is_smi_constant) {
     answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
                                         type, true, overwrite_mode);
   } else {
@@ -1003,10 +1047,67 @@
     if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
       answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
     } else {
-      GenericBinaryOpStub stub(op, overwrite_mode, NO_GENERIC_BINARY_FLAGS);
+      GenericBinaryOpStub stub(op,
+                               overwrite_mode,
+                               NO_GENERIC_BINARY_FLAGS,
+                               operands_type);
       answer = stub.GenerateCall(masm_, frame_, &left, &right);
     }
   }
+
+  // Set NumberInfo of result according to the operation performed.
+  // Rely on the fact that smis have a 31 bit payload on ia32.
+  ASSERT(kSmiValueSize == 31);
+  NumberInfo::Type result_type = NumberInfo::kUnknown;
+  switch (op) {
+    case Token::COMMA:
+      result_type = right.number_info();
+      break;
+    case Token::OR:
+    case Token::AND:
+      // Result type can be either of the two input types.
+      result_type = operands_type;
+      break;
+    case Token::BIT_OR:
+    case Token::BIT_XOR:
+    case Token::BIT_AND:
+      // Result is always a number. Smi property of inputs is preserved.
+      result_type = (operands_type == NumberInfo::kSmi)
+          ? NumberInfo::kSmi
+          : NumberInfo::kNumber;
+      break;
+    case Token::SAR:
+      // Result is a smi if we shift by a constant >= 1, otherwise a number.
+      result_type = (right.is_constant() && right.handle()->IsSmi()
+                     && Smi::cast(*right.handle())->value() >= 1)
+          ? NumberInfo::kSmi
+          : NumberInfo::kNumber;
+      break;
+    case Token::SHR:
+      // Result is a smi if we shift by a constant >= 2, otherwise a number.
+      result_type = (right.is_constant() && right.handle()->IsSmi()
+                     && Smi::cast(*right.handle())->value() >= 2)
+          ? NumberInfo::kSmi
+          : NumberInfo::kNumber;
+      break;
+    case Token::ADD:
+      // Result could be a string or a number. Check types of inputs.
+      result_type = NumberInfo::IsNumber(operands_type)
+          ? NumberInfo::kNumber
+          : NumberInfo::kUnknown;
+      break;
+    case Token::SHL:
+    case Token::SUB:
+    case Token::MUL:
+    case Token::DIV:
+    case Token::MOD:
+      // Result is always a number.
+      result_type = NumberInfo::kNumber;
+      break;
+    default:
+      UNREACHABLE();
+  }
+  answer.set_number_info(result_type);
   frame_->Push(&answer);
 }
 
@@ -1848,6 +1949,39 @@
       break;
     }
 
+    case Token::DIV:
+      if (!reversed && int_value == 2) {
+        operand->ToRegister();
+        frame_->Spill(operand->reg());
+
+        DeferredInlineSmiOperation* deferred =
+            new DeferredInlineSmiOperation(op,
+                                           operand->reg(),
+                                           operand->reg(),
+                                           smi_value,
+                                           overwrite_mode);
+        // Check that lowest log2(value) bits of operand are zero, and test
+        // smi tag at the same time.
+        ASSERT_EQ(0, kSmiTag);
+        ASSERT_EQ(1, kSmiTagSize);
+        __ test(operand->reg(), Immediate(3));
+        deferred->Branch(not_zero);  // Branch if non-smi or odd smi.
+        __ sar(operand->reg(), 1);
+        deferred->BindExit();
+        answer = *operand;
+      } else {
+        // Cannot fall through MOD to default case, so we duplicate the
+        // default case here.
+        Result constant_operand(value);
+        if (reversed) {
+          answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
+                                            overwrite_mode);
+        } else {
+          answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
+                                            overwrite_mode);
+        }
+      }
+      break;
     // Generate inline code for mod of powers of 2 and negative powers of 2.
     case Token::MOD:
       if (!reversed &&
@@ -2327,6 +2461,7 @@
   // Load applicand.apply onto the stack. This will usually
   // give us a megamorphic load site. Not super, but it works.
   Load(applicand);
+  frame()->Dup();
   Handle<String> name = Factory::LookupAsciiSymbol("apply");
   frame()->Push(name);
   Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET);
@@ -2336,7 +2471,9 @@
   // Load the receiver and the existing arguments object onto the
   // expression stack. Avoid allocating the arguments object here.
   Load(receiver);
-  LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
+  Result existing_args =
+      LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
+  frame()->Push(&existing_args);
 
   // Emit the source position information after having loaded the
   // receiver and the arguments.
@@ -3906,35 +4043,32 @@
   // Spill everything, even constants, to the frame.
   frame_->SpillAll();
 
-  DebuggerStatementStub ces;
-  frame_->CallStub(&ces, 0);
+  frame_->DebugBreak();
   // Ignore the return value.
 #endif
 }
 
 
-void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
+Result CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
   ASSERT(boilerplate->IsBoilerplate());
 
   // The inevitable call will sync frame elements to memory anyway, so
   // we do it eagerly to allow us to push the arguments directly into
   // place.
-  frame_->SyncRange(0, frame_->element_count() - 1);
+  frame()->SyncRange(0, frame()->element_count() - 1);
 
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
   if (scope()->is_function_scope() && boilerplate->NumberOfLiterals() == 0) {
     FastNewClosureStub stub;
-    frame_->EmitPush(Immediate(boilerplate));
-    Result answer = frame_->CallStub(&stub, 1);
-    frame_->Push(&answer);
+    frame()->EmitPush(Immediate(boilerplate));
+    return frame()->CallStub(&stub, 1);
   } else {
     // Call the runtime to instantiate the function boilerplate
     // object.
-    frame_->EmitPush(esi);
-    frame_->EmitPush(Immediate(boilerplate));
-    Result result = frame_->CallRuntime(Runtime::kNewClosure, 2);
-    frame_->Push(&result);
+    frame()->EmitPush(esi);
+    frame()->EmitPush(Immediate(boilerplate));
+    return frame()->CallRuntime(Runtime::kNewClosure, 2);
   }
 }
 
@@ -3947,14 +4081,16 @@
       Compiler::BuildBoilerplate(node, script(), this);
   // Check for stack-overflow exception.
   if (HasStackOverflow()) return;
-  InstantiateBoilerplate(boilerplate);
+  Result result = InstantiateBoilerplate(boilerplate);
+  frame()->Push(&result);
 }
 
 
 void CodeGenerator::VisitFunctionBoilerplateLiteral(
     FunctionBoilerplateLiteral* node) {
   Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
-  InstantiateBoilerplate(node->boilerplate());
+  Result result = InstantiateBoilerplate(node->boilerplate());
+  frame()->Push(&result);
 }
 
 
@@ -3990,13 +4126,12 @@
 }
 
 
-void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
+Result CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
+  Result result;
   if (slot->type() == Slot::LOOKUP) {
     ASSERT(slot->var()->is_dynamic());
-
     JumpTarget slow;
     JumpTarget done;
-    Result value;
 
     // Generate fast-case code for variables that might be shadowed by
     // eval-introduced variables.  Eval is used a lot without
@@ -4004,14 +4139,10 @@
     // perform a runtime call for all variables in the scope
     // containing the eval.
     if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
-      value = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
+      result = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
       // If there was no control flow to slow, we can exit early.
-      if (!slow.is_linked()) {
-        frame_->Push(&value);
-        return;
-      }
-
-      done.Jump(&value);
+      if (!slow.is_linked()) return result;
+      done.Jump(&result);
 
     } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
       Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
@@ -4021,21 +4152,21 @@
         // Allocate a fresh register to use as a temp in
         // ContextSlotOperandCheckExtensions and to hold the result
         // value.
-        value = allocator_->Allocate();
-        ASSERT(value.is_valid());
-        __ mov(value.reg(),
+        result = allocator()->Allocate();
+        ASSERT(result.is_valid());
+        __ mov(result.reg(),
                ContextSlotOperandCheckExtensions(potential_slot,
-                                                 value,
+                                                 result,
                                                  &slow));
         if (potential_slot->var()->mode() == Variable::CONST) {
-          __ cmp(value.reg(), Factory::the_hole_value());
-          done.Branch(not_equal, &value);
-          __ mov(value.reg(), Factory::undefined_value());
+          __ cmp(result.reg(), Factory::the_hole_value());
+          done.Branch(not_equal, &result);
+          __ mov(result.reg(), Factory::undefined_value());
         }
         // There is always control flow to slow from
         // ContextSlotOperandCheckExtensions so we have to jump around
         // it.
-        done.Jump(&value);
+        done.Jump(&result);
       }
     }
 
@@ -4043,18 +4174,18 @@
     // A runtime call is inevitable.  We eagerly sync frame elements
     // to memory so that we can push the arguments directly into place
     // on top of the frame.
-    frame_->SyncRange(0, frame_->element_count() - 1);
-    frame_->EmitPush(esi);
-    frame_->EmitPush(Immediate(slot->var()->name()));
+    frame()->SyncRange(0, frame()->element_count() - 1);
+    frame()->EmitPush(esi);
+    frame()->EmitPush(Immediate(slot->var()->name()));
     if (typeof_state == INSIDE_TYPEOF) {
-      value =
-          frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
+      result =
+          frame()->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
     } else {
-      value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
+      result = frame()->CallRuntime(Runtime::kLoadContextSlot, 2);
     }
 
-    done.Bind(&value);
-    frame_->Push(&value);
+    done.Bind(&result);
+    return result;
 
   } else if (slot->var()->mode() == Variable::CONST) {
     // Const slots may contain 'the hole' value (the constant hasn't been
@@ -4065,19 +4196,21 @@
     // potentially unsafe direct-frame access of SlotOperand.
     VirtualFrame::SpilledScope spilled_scope;
     Comment cmnt(masm_, "[ Load const");
-    JumpTarget exit;
+    Label exit;
     __ mov(ecx, SlotOperand(slot, ecx));
     __ cmp(ecx, Factory::the_hole_value());
-    exit.Branch(not_equal);
+    __ j(not_equal, &exit);
     __ mov(ecx, Factory::undefined_value());
-    exit.Bind();
-    frame_->EmitPush(ecx);
+    __ bind(&exit);
+    return Result(ecx);
 
   } else if (slot->type() == Slot::PARAMETER) {
-    frame_->PushParameterAt(slot->index());
+    frame()->PushParameterAt(slot->index());
+    return frame()->Pop();
 
   } else if (slot->type() == Slot::LOCAL) {
-    frame_->PushLocalAt(slot->index());
+    frame()->PushLocalAt(slot->index());
+    return frame()->Pop();
 
   } else {
     // The other remaining slot types (LOOKUP and GLOBAL) cannot reach
@@ -4086,49 +4219,46 @@
     // The use of SlotOperand below is safe for an unspilled frame
     // because it will always be a context slot.
     ASSERT(slot->type() == Slot::CONTEXT);
-    Result temp = allocator_->Allocate();
-    ASSERT(temp.is_valid());
-    __ mov(temp.reg(), SlotOperand(slot, temp.reg()));
-    frame_->Push(&temp);
+    result = allocator()->Allocate();
+    ASSERT(result.is_valid());
+    __ mov(result.reg(), SlotOperand(slot, result.reg()));
+    return result;
   }
 }
 
 
-void CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot,
-                                                  TypeofState state) {
-  LoadFromSlot(slot, state);
+Result CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot,
+                                                    TypeofState state) {
+  Result result = LoadFromSlot(slot, state);
 
   // Bail out quickly if we're not using lazy arguments allocation.
-  if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return;
+  if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return result;
 
   // ... or if the slot isn't a non-parameter arguments slot.
-  if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return;
-
-  // Pop the loaded value from the stack.
-  Result value = frame_->Pop();
+  if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return result;
 
   // If the loaded value is a constant, we know if the arguments
   // object has been lazily loaded yet.
-  if (value.is_constant()) {
-    if (value.handle()->IsTheHole()) {
-      Result arguments = StoreArgumentsObject(false);
-      frame_->Push(&arguments);
+  if (result.is_constant()) {
+    if (result.handle()->IsTheHole()) {
+      result.Unuse();
+      return StoreArgumentsObject(false);
     } else {
-      frame_->Push(&value);
+      return result;
     }
-    return;
   }
 
   // The loaded value is in a register. If it is the sentinel that
   // indicates that we haven't loaded the arguments object yet, we
   // need to do it now.
   JumpTarget exit;
-  __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value()));
-  frame_->Push(&value);
-  exit.Branch(not_equal);
-  Result arguments = StoreArgumentsObject(false);
-  frame_->SetElementAt(0, &arguments);
-  exit.Bind();
+  __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value()));
+  exit.Branch(not_equal, &result);
+
+  result.Unuse();
+  result = StoreArgumentsObject(false);
+  exit.Bind(&result);
+  return result;
 }
 
 
@@ -4188,6 +4318,10 @@
 
   // All extension objects were empty and it is safe to use a global
   // load IC call.
+  // The register allocator prefers eax if it is free, so the code generator
+  // will load the global object directly into eax, which is where the LoadIC
+  // expects it.
+  frame_->Spill(eax);
   LoadGlobal();
   frame_->Push(slot->var()->name());
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
@@ -4198,8 +4332,6 @@
   // property case was inlined.  Ensure that there is not a test eax
   // instruction here.
   __ nop();
-  // Discard the global object. The result is in answer.
-  frame_->Drop();
   return answer;
 }
 
@@ -4304,7 +4436,8 @@
 
 void CodeGenerator::VisitSlot(Slot* node) {
   Comment cmnt(masm_, "[ Slot");
-  LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
+  Result result = LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
+  frame()->Push(&result);
 }
 
 
@@ -4474,8 +4607,8 @@
           // Duplicate the object as the IC receiver.
           frame_->Dup();
           Load(property->value());
-          frame_->Push(key);
-          Result ignored = frame_->CallStoreIC();
+          Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
+          dummy.Unuse();
           break;
         }
         // Fall through
@@ -4599,106 +4732,241 @@
 }
 
 
+void CodeGenerator::EmitSlotAssignment(Assignment* node) {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Comment cmnt(masm(), "[ Variable Assignment");
+  Variable* var = node->target()->AsVariableProxy()->AsVariable();
+  ASSERT(var != NULL);
+  Slot* slot = var->slot();
+  ASSERT(slot != NULL);
+
+  // Evaluate the right-hand side.
+  if (node->is_compound()) {
+    Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
+    frame()->Push(&result);
+    Load(node->value());
+
+    bool overwrite_value =
+        (node->value()->AsBinaryOperation() != NULL &&
+         node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+    GenericBinaryOperation(node->binary_op(),
+                           node->type(),
+                           overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+  } else {
+    Load(node->value());
+  }
+
+  // Perform the assignment.
+  if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
+    CodeForSourcePosition(node->position());
+    StoreToSlot(slot,
+                node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
+  }
+  ASSERT(frame()->height() == original_height + 1);
+}
+
+
+void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Comment cmnt(masm(), "[ Named Property Assignment");
+  Variable* var = node->target()->AsVariableProxy()->AsVariable();
+  Property* prop = node->target()->AsProperty();
+  ASSERT(var == NULL || (prop == NULL && var->is_global()));
+
+  // Initialize name and evaluate the receiver subexpression if necessary.
+  Handle<String> name;
+  bool is_trivial_receiver = false;
+  if (var != NULL) {
+    name = var->name();
+  } else {
+    Literal* lit = prop->key()->AsLiteral();
+    ASSERT_NOT_NULL(lit);
+    name = Handle<String>::cast(lit->handle());
+    // Do not materialize the receiver on the frame if it is trivial.
+    is_trivial_receiver = prop->obj()->IsTrivial();
+    if (!is_trivial_receiver) Load(prop->obj());
+  }
+
+  if (node->starts_initialization_block()) {
+    ASSERT_EQ(NULL, var);
+    // Change to slow case in the beginning of an initialization block to
+    // avoid the quadratic behavior of repeatedly adding fast properties.
+    if (is_trivial_receiver) {
+      frame()->Push(prop->obj());
+    } else {
+      frame()->Dup();
+    }
+    Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1);
+  }
+
+  if (node->ends_initialization_block() && !is_trivial_receiver) {
+    // Add an extra copy of the receiver to the frame, so that it can be
+    // converted back to fast case after the assignment.
+    frame()->Dup();
+  }
+
+  // Evaluate the right-hand side.
+  if (node->is_compound()) {
+    if (is_trivial_receiver) {
+      frame()->Push(prop->obj());
+    } else if (var != NULL) {
+      // The LoadIC stub expects the object in eax.
+      // Freeing eax causes the code generator to load the global into it.
+      frame_->Spill(eax);
+      LoadGlobal();
+    } else {
+      frame()->Dup();
+    }
+    Result value = EmitNamedLoad(name, var != NULL);
+    frame()->Push(&value);
+    Load(node->value());
+
+    bool overwrite_value =
+        (node->value()->AsBinaryOperation() != NULL &&
+         node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+    GenericBinaryOperation(node->binary_op(),
+                           node->type(),
+                           overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+  } else {
+    Load(node->value());
+  }
+
+  // Perform the assignment.  It is safe to ignore constants here.
+  ASSERT(var == NULL || var->mode() != Variable::CONST);
+  ASSERT_NE(Token::INIT_CONST, node->op());
+  if (is_trivial_receiver) {
+    Result value = frame()->Pop();
+    frame()->Push(prop->obj());
+    frame()->Push(&value);
+  }
+  CodeForSourcePosition(node->position());
+  bool is_contextual = (var != NULL);
+  Result answer = EmitNamedStore(name, is_contextual);
+  frame()->Push(&answer);
+
+  if (node->ends_initialization_block()) {
+    ASSERT_EQ(NULL, var);
+    // The argument to the runtime call is the receiver.
+    if (is_trivial_receiver) {
+      frame()->Push(prop->obj());
+    } else {
+      // A copy of the receiver is below the value of the assignment.  Swap
+      // the receiver and the value of the assignment expression.
+      Result result = frame()->Pop();
+      Result receiver = frame()->Pop();
+      frame()->Push(&result);
+      frame()->Push(&receiver);
+    }
+    Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
+  }
+
+  ASSERT_EQ(frame()->height(), original_height + 1);
+}
+
+
+void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Comment cmnt(masm_, "[ Named Property Assignment");
+  Property* prop = node->target()->AsProperty();
+  ASSERT_NOT_NULL(prop);
+
+  // Evaluate the receiver subexpression.
+  Load(prop->obj());
+
+  if (node->starts_initialization_block()) {
+    // Change to slow case in the beginning of an initialization block to
+    // avoid the quadratic behavior of repeatedly adding fast properties.
+    frame_->Dup();
+    Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
+  }
+
+  if (node->ends_initialization_block()) {
+    // Add an extra copy of the receiver to the frame, so that it can be
+    // converted back to fast case after the assignment.
+    frame_->Dup();
+  }
+
+  // Evaluate the key subexpression.
+  Load(prop->key());
+
+  // Evaluate the right-hand side.
+  if (node->is_compound()) {
+    // Duplicate receiver and key.
+    frame()->PushElementAt(1);
+    frame()->PushElementAt(1);
+    Result value = EmitKeyedLoad();
+    frame()->Push(&value);
+    Load(node->value());
+
+    bool overwrite_value =
+        (node->value()->AsBinaryOperation() != NULL &&
+         node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+    GenericBinaryOperation(node->binary_op(),
+                           node->type(),
+                           overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+  } else {
+    Load(node->value());
+  }
+
+  // Perform the assignment.  It is safe to ignore constants here.
+  ASSERT(node->op() != Token::INIT_CONST);
+  CodeForSourcePosition(node->position());
+  Result answer = EmitKeyedStore(prop->key()->type());
+  frame()->Push(&answer);
+
+  if (node->ends_initialization_block()) {
+    // The argument to the runtime call is the extra copy of the receiver,
+    // which is below the value of the assignment.  Swap the receiver and
+    // the value of the assignment expression.
+    Result result = frame()->Pop();
+    Result receiver = frame()->Pop();
+    frame()->Push(&result);
+    frame()->Push(&receiver);
+    Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
+  }
+
+  ASSERT(frame()->height() == original_height + 1);
+}
+
+
 void CodeGenerator::VisitAssignment(Assignment* node) {
 #ifdef DEBUG
-  int original_height = frame_->height();
+  int original_height = frame()->height();
 #endif
-  Comment cmnt(masm_, "[ Assignment");
+  Variable* var = node->target()->AsVariableProxy()->AsVariable();
+  Property* prop = node->target()->AsProperty();
 
-  { Reference target(this, node->target(), node->is_compound());
-    if (target.is_illegal()) {
-      // Fool the virtual frame into thinking that we left the assignment's
-      // value on the frame.
-      frame_->Push(Smi::FromInt(0));
-      return;
-    }
-    Variable* var = node->target()->AsVariableProxy()->AsVariable();
+  if (var != NULL && !var->is_global()) {
+    EmitSlotAssignment(node);
 
-    if (node->starts_initialization_block()) {
-      ASSERT(target.type() == Reference::NAMED ||
-             target.type() == Reference::KEYED);
-      // Change to slow case in the beginning of an initialization
-      // block to avoid the quadratic behavior of repeatedly adding
-      // fast properties.
+  } else if ((prop != NULL && prop->key()->IsPropertyName()) ||
+             (var != NULL && var->is_global())) {
+    // Properties whose keys are property names and global variables are
+    // treated as named property references.  We do not need to consider
+    // global 'this' because it is not a valid left-hand side.
+    EmitNamedPropertyAssignment(node);
 
-      // The receiver is the argument to the runtime call.  It is the
-      // first value pushed when the reference was loaded to the
-      // frame.
-      frame_->PushElementAt(target.size() - 1);
-      Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
-    }
-    if (node->ends_initialization_block()) {
-      // Add an extra copy of the receiver to the frame, so that it can be
-      // converted back to fast case after the assignment.
-      ASSERT(target.type() == Reference::NAMED ||
-             target.type() == Reference::KEYED);
-      if (target.type() == Reference::NAMED) {
-        frame_->Dup();
-        // Dup target receiver on stack.
-      } else {
-        ASSERT(target.type() == Reference::KEYED);
-        Result temp = frame_->Pop();
-        frame_->Dup();
-        frame_->Push(&temp);
-      }
-    }
-    if (node->op() == Token::ASSIGN ||
-        node->op() == Token::INIT_VAR ||
-        node->op() == Token::INIT_CONST) {
-      Load(node->value());
+  } else if (prop != NULL) {
+    // Other properties (including rewritten parameters for a function that
+    // uses arguments) are keyed property assignments.
+    EmitKeyedPropertyAssignment(node);
 
-    } else {  // Assignment is a compound assignment.
-      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,
-      // or the right hand side is a different variable.  TakeValue invalidates
-      // the target, with an implicit promise that it will be written to again
-      // before it is read.
-      if (literal != NULL || (right_var != NULL && right_var != var)) {
-        target.TakeValue();
-      } else {
-        target.GetValue();
-      }
-      Load(node->value());
-      GenericBinaryOperation(node->binary_op(),
-                             node->type(),
-                             overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
-    }
-
-    if (var != NULL &&
-        var->mode() == Variable::CONST &&
-        node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
-      // Assignment ignored - leave the value on the stack.
-      UnloadReference(&target);
-    } else {
-      CodeForSourcePosition(node->position());
-      if (node->op() == Token::INIT_CONST) {
-        // Dynamic constant initializations must use the function context
-        // and initialize the actual constant declared. Dynamic variable
-        // initializations are simply assignments and use SetValue.
-        target.SetValue(CONST_INIT);
-      } else {
-        target.SetValue(NOT_CONST_INIT);
-      }
-      if (node->ends_initialization_block()) {
-        ASSERT(target.type() == Reference::UNLOADED);
-        // End of initialization block. Revert to fast case.  The
-        // argument to the runtime call is the extra copy of the receiver,
-        // which is below the value of the assignment.
-        // Swap the receiver and the value of the assignment expression.
-        Result lhs = frame_->Pop();
-        Result receiver = frame_->Pop();
-        frame_->Push(&lhs);
-        frame_->Push(&receiver);
-        Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
-      }
-    }
+  } else {
+    // Invalid left-hand side.
+    Load(node->target());
+    Result result = frame()->CallRuntime(Runtime::kThrowReferenceError, 1);
+    // The runtime call doesn't actually return but the code generator will
+    // still generate code and expects a certain frame height.
+    frame()->Push(&result);
   }
-  ASSERT(frame_->height() == original_height + 1);
+
+  ASSERT(frame()->height() == original_height + 1);
 }
 
 
@@ -4903,9 +5171,9 @@
         LoadGlobalReceiver();
       } else {
         Load(property->obj());
+        frame()->Dup();
         Load(property->key());
-        Result function = EmitKeyedLoad(false);
-        frame_->Drop();  // Key.
+        Result function = EmitKeyedLoad();
         Result receiver = frame_->Pop();
         frame_->Push(&function);
         frame_->Push(&receiver);
@@ -5173,6 +5441,25 @@
 }
 
 
+void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+  Load(args->at(0));
+  Result value = frame_->Pop();
+  value.ToRegister();
+  ASSERT(value.is_valid());
+  __ test(value.reg(), Immediate(kSmiTagMask));
+  destination()->false_target()->Branch(equal);
+  // It is a heap object - get map.
+  Result temp = allocator()->Allocate();
+  ASSERT(temp.is_valid());
+  // Check if the object is a regexp.
+  __ CmpObjectType(value.reg(), JS_REGEXP_TYPE, temp.reg());
+  value.Unuse();
+  temp.Unuse();
+  destination()->Split(equal);
+}
+
+
 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
   // This generates a fast version of:
   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
@@ -5527,6 +5814,35 @@
 }
 
 
+void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+
+  // Load the argument on the stack and call the stub.
+  Load(args->at(0));
+  NumberToStringStub stub;
+  Result result = frame_->CallStub(&stub, 1);
+  frame_->Push(&result);
+}
+
+
+void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  Load(args->at(0));
+  TranscendentalCacheStub stub(TranscendentalCache::SIN);
+  Result result = frame_->CallStub(&stub, 1);
+  frame_->Push(&result);
+}
+
+
+void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  Load(args->at(0));
+  TranscendentalCacheStub stub(TranscendentalCache::COS);
+  Result result = frame_->CallStub(&stub, 1);
+  frame_->Push(&result);
+}
+
+
 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
   if (CheckForInlineRuntimeCall(node)) {
     return;
@@ -5661,7 +5977,6 @@
     switch (op) {
       case Token::SUB: {
         GenericUnaryOpStub stub(Token::SUB, overwrite);
-        // TODO(1222589): remove dependency of TOS being cached inside stub
         Result operand = frame_->Pop();
         Result answer = frame_->CallStub(&stub, &operand);
         frame_->Push(&answer);
@@ -6111,13 +6426,10 @@
       __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kBitFieldOffset));
       __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
       destination()->false_target()->Branch(not_zero);
-      __ mov(temp.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
-      __ movzx_b(temp.reg(),
-                 FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
-      __ cmp(temp.reg(), FIRST_NONSTRING_TYPE);
+      __ CmpObjectType(answer.reg(), FIRST_NONSTRING_TYPE, temp.reg());
       temp.Unuse();
       answer.Unuse();
-      destination()->Split(less);
+      destination()->Split(below);
 
     } else if (check->Equals(Heap::boolean_symbol())) {
       __ cmp(answer.reg(), Factory::true_value());
@@ -6277,7 +6589,7 @@
 
 
 // Emit a LoadIC call to get the value from receiver and leave it in
-// dst.  The receiver register is restored after the call.
+// dst.
 class DeferredReferenceGetNamedValue: public DeferredCode {
  public:
   DeferredReferenceGetNamedValue(Register dst,
@@ -6300,7 +6612,9 @@
 
 
 void DeferredReferenceGetNamedValue::Generate() {
-  __ push(receiver_);
+  if (!receiver_.is(eax)) {
+    __ mov(eax, receiver_);
+  }
   __ Set(ecx, Immediate(name_));
   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
@@ -6317,7 +6631,6 @@
   __ IncrementCounter(&Counters::named_load_inline_miss, 1);
 
   if (!dst_.is(eax)) __ mov(dst_, eax);
-  __ pop(receiver_);
 }
 
 
@@ -6325,9 +6638,8 @@
  public:
   explicit DeferredReferenceGetKeyedValue(Register dst,
                                           Register receiver,
-                                          Register key,
-                                          bool is_global)
-      : dst_(dst), receiver_(receiver), key_(key), is_global_(is_global) {
+                                          Register key)
+      : dst_(dst), receiver_(receiver), key_(key) {
     set_comment("[ DeferredReferenceGetKeyedValue");
   }
 
@@ -6340,14 +6652,29 @@
   Register dst_;
   Register receiver_;
   Register key_;
-  bool is_global_;
 };
 
 
 void DeferredReferenceGetKeyedValue::Generate() {
-  __ push(receiver_);  // First IC argument.
-  __ push(key_);       // Second IC argument.
-
+  if (!receiver_.is(eax)) {
+    // Register eax is available for key.
+    if (!key_.is(eax)) {
+      __ mov(eax, key_);
+    }
+    if (!receiver_.is(edx)) {
+      __ mov(edx, receiver_);
+    }
+  } else if (!key_.is(edx)) {
+    // Register edx is available for receiver.
+    if (!receiver_.is(edx)) {
+      __ mov(edx, receiver_);
+    }
+    if (!key_.is(eax)) {
+      __ mov(eax, key_);
+    }
+  } else {
+    __ xchg(edx, eax);
+  }
   // Calculate the delta from the IC call instruction to the map check
   // cmp instruction in the inlined version.  This delta is stored in
   // a test(eax, delta) instruction after the call so that we can find
@@ -6355,10 +6682,7 @@
   // This means that we cannot allow test instructions after calls to
   // KeyedLoadIC stubs in other places.
   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
-  RelocInfo::Mode mode = is_global_
-                         ? RelocInfo::CODE_TARGET_CONTEXT
-                         : RelocInfo::CODE_TARGET;
-  __ call(ic, mode);
+  __ call(ic, RelocInfo::CODE_TARGET);
   // The delta from the start of the map-compare instruction to the
   // test instruction.  We use masm_-> directly here instead of the __
   // macro because the macro sometimes uses macro expansion to turn
@@ -6371,8 +6695,6 @@
   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
 
   if (!dst_.is(eax)) __ mov(dst_, eax);
-  __ pop(key_);
-  __ pop(receiver_);
 }
 
 
@@ -6424,12 +6746,90 @@
 }
 
 
-Result CodeGenerator::EmitKeyedLoad(bool is_global) {
-  Comment cmnt(masm_, "[ Load from keyed Property");
-  // Inline array load code if inside of a loop.  We do not know
-  // the receiver map yet, so we initially generate the code with
-  // a check against an invalid map.  In the inline cache code, we
-  // patch the map check if appropriate.
+Result CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Result result;
+  // Do not inline the inobject property case for loads from the global
+  // object.  Also do not inline for unoptimized code.  This saves time in
+  // the code generator.  Unoptimized code is toplevel code or code that is
+  // not in a loop.
+  if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
+    Comment cmnt(masm(), "[ Load from named Property");
+    frame()->Push(name);
+
+    RelocInfo::Mode mode = is_contextual
+        ? RelocInfo::CODE_TARGET_CONTEXT
+        : RelocInfo::CODE_TARGET;
+    result = frame()->CallLoadIC(mode);
+    // A test eax instruction following the call signals that the inobject
+    // property case was inlined.  Ensure that there is not a test eax
+    // instruction here.
+    __ nop();
+  } else {
+    // Inline the inobject property case.
+    Comment cmnt(masm(), "[ Inlined named property load");
+    Result receiver = frame()->Pop();
+    receiver.ToRegister();
+
+    result = allocator()->Allocate();
+    ASSERT(result.is_valid());
+    DeferredReferenceGetNamedValue* deferred =
+        new DeferredReferenceGetNamedValue(result.reg(), receiver.reg(), name);
+
+    // Check that the receiver is a heap object.
+    __ test(receiver.reg(), Immediate(kSmiTagMask));
+    deferred->Branch(zero);
+
+    __ bind(deferred->patch_site());
+    // This is the map check instruction that will be patched (so we can't
+    // use the double underscore macro that may insert instructions).
+    // Initially use an invalid map to force a failure.
+    masm()->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
+                Immediate(Factory::null_value()));
+    // This branch is always a forwards branch so it's always a fixed size
+    // which allows the assert below to succeed and patching to work.
+    deferred->Branch(not_equal);
+
+    // The delta from the patch label to the load offset must be statically
+    // known.
+    ASSERT(masm()->SizeOfCodeGeneratedSince(deferred->patch_site()) ==
+           LoadIC::kOffsetToLoadInstruction);
+    // The initial (invalid) offset has to be large enough to force a 32-bit
+    // instruction encoding to allow patching with an arbitrary offset.  Use
+    // kMaxInt (minus kHeapObjectTag).
+    int offset = kMaxInt;
+    masm()->mov(result.reg(), FieldOperand(receiver.reg(), offset));
+
+    __ IncrementCounter(&Counters::named_load_inline, 1);
+    deferred->BindExit();
+  }
+  ASSERT(frame()->height() == original_height - 1);
+  return result;
+}
+
+
+Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
+#ifdef DEBUG
+  int expected_height = frame()->height() - (is_contextual ? 1 : 2);
+#endif
+  Result result = frame()->CallStoreIC(name, is_contextual);
+
+  ASSERT_EQ(expected_height, frame()->height());
+  return result;
+}
+
+
+Result CodeGenerator::EmitKeyedLoad() {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Result result;
+  // Inline array load code if inside of a loop.  We do not know the
+  // receiver map yet, so we initially generate the code with a check
+  // against an invalid map.  In the inline cache code, we patch the map
+  // check if appropriate.
   if (loop_nesting() > 0) {
     Comment cmnt(masm_, "[ Inlined load from keyed Property");
 
@@ -6445,22 +6845,16 @@
 
     // Use a fresh temporary for the index and later the loaded
     // value.
-    Result index = allocator()->Allocate();
-    ASSERT(index.is_valid());
+    result = allocator()->Allocate();
+    ASSERT(result.is_valid());
 
     DeferredReferenceGetKeyedValue* deferred =
-        new DeferredReferenceGetKeyedValue(index.reg(),
+        new DeferredReferenceGetKeyedValue(result.reg(),
                                            receiver.reg(),
-                                           key.reg(),
-                                           is_global);
+                                           key.reg());
 
-    // Check that the receiver is not a smi (only needed if this
-    // is not a load from the global context) and that it has the
-    // expected map.
-    if (!is_global) {
-      __ test(receiver.reg(), Immediate(kSmiTagMask));
-      deferred->Branch(zero);
-    }
+    __ test(receiver.reg(), Immediate(kSmiTagMask));
+    deferred->Branch(zero);
 
     // Initially, use an invalid map. The map is patched in the IC
     // initialization code.
@@ -6485,50 +6879,132 @@
 
     // Shift the key to get the actual index value and check that
     // it is within bounds.
-    __ mov(index.reg(), key.reg());
-    __ SmiUntag(index.reg());
-    __ cmp(index.reg(),
+    __ mov(result.reg(), key.reg());
+    __ SmiUntag(result.reg());
+    __ cmp(result.reg(),
            FieldOperand(elements.reg(), FixedArray::kLengthOffset));
     deferred->Branch(above_equal);
 
-    // Load and check that the result is not the hole.  We could
-    // reuse the index or elements register for the value.
-    //
-    // TODO(206): Consider whether it makes sense to try some
-    // heuristic about which register to reuse.  For example, if
-    // one is eax, the we can reuse that one because the value
-    // coming from the deferred code will be in eax.
-    Result value = index;
-    __ mov(value.reg(), Operand(elements.reg(),
-                                index.reg(),
-                                times_4,
-                                FixedArray::kHeaderSize - kHeapObjectTag));
+    // Load and check that the result is not the hole.
+    __ mov(result.reg(), Operand(elements.reg(),
+                                 result.reg(),
+                                 times_4,
+                                 FixedArray::kHeaderSize - kHeapObjectTag));
     elements.Unuse();
-    index.Unuse();
-    __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value()));
+    __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value()));
     deferred->Branch(equal);
     __ IncrementCounter(&Counters::keyed_load_inline, 1);
 
     deferred->BindExit();
-    // Restore the receiver and key to the frame and push the
-    // result on top of it.
-    frame_->Push(&receiver);
-    frame_->Push(&key);
-    return value;
   } else {
     Comment cmnt(masm_, "[ Load from keyed Property");
-    RelocInfo::Mode mode = is_global
-        ? RelocInfo::CODE_TARGET_CONTEXT
-        : RelocInfo::CODE_TARGET;
-    Result answer = frame_->CallKeyedLoadIC(mode);
+    result = frame_->CallKeyedLoadIC(RelocInfo::CODE_TARGET);
     // Make sure that we do not have a test instruction after the
     // call.  A test instruction after the call is used to
     // indicate that we have generated an inline version of the
     // keyed load.  The explicit nop instruction is here because
     // the push that follows might be peep-hole optimized away.
     __ nop();
-    return answer;
   }
+  ASSERT(frame()->height() == original_height - 2);
+  return result;
+}
+
+
+Result CodeGenerator::EmitKeyedStore(StaticType* key_type) {
+#ifdef DEBUG
+  int original_height = frame()->height();
+#endif
+  Result result;
+  // Generate inlined version of the keyed store if the code is in a loop
+  // and the key is likely to be a smi.
+  if (loop_nesting() > 0 && key_type->IsLikelySmi()) {
+    Comment cmnt(masm(), "[ Inlined store to keyed Property");
+
+    // Get the receiver, key and value into registers.
+    result = frame()->Pop();
+    Result key = frame()->Pop();
+    Result receiver = frame()->Pop();
+
+    Result tmp = allocator_->Allocate();
+    ASSERT(tmp.is_valid());
+
+    // Determine whether the value is a constant before putting it in a
+    // register.
+    bool value_is_constant = result.is_constant();
+
+    // Make sure that value, key and receiver are in registers.
+    result.ToRegister();
+    key.ToRegister();
+    receiver.ToRegister();
+
+    DeferredReferenceSetKeyedValue* deferred =
+        new DeferredReferenceSetKeyedValue(result.reg(),
+                                           key.reg(),
+                                           receiver.reg());
+
+    // Check that the value is a smi if it is not a constant.  We can skip
+    // the write barrier for smis and constants.
+    if (!value_is_constant) {
+      __ test(result.reg(), Immediate(kSmiTagMask));
+      deferred->Branch(not_zero);
+    }
+
+    // Check that the key is a non-negative smi.
+    __ test(key.reg(), Immediate(kSmiTagMask | 0x80000000));
+    deferred->Branch(not_zero);
+
+    // Check that the receiver is not a smi.
+    __ test(receiver.reg(), Immediate(kSmiTagMask));
+    deferred->Branch(zero);
+
+    // Check that the receiver is a JSArray.
+    __ mov(tmp.reg(),
+           FieldOperand(receiver.reg(), HeapObject::kMapOffset));
+    __ movzx_b(tmp.reg(),
+               FieldOperand(tmp.reg(), Map::kInstanceTypeOffset));
+    __ cmp(tmp.reg(), JS_ARRAY_TYPE);
+    deferred->Branch(not_equal);
+
+    // Check that the key is within bounds.  Both the key and the length of
+    // the JSArray are smis.
+    __ cmp(key.reg(),
+           FieldOperand(receiver.reg(), JSArray::kLengthOffset));
+    deferred->Branch(greater_equal);
+
+    // Get the elements array from the receiver and check that it is not a
+    // dictionary.
+    __ mov(tmp.reg(),
+           FieldOperand(receiver.reg(), JSObject::kElementsOffset));
+    // Bind the deferred code patch site to be able to locate the fixed
+    // array map comparison.  When debugging, we patch this comparison to
+    // always fail so that we will hit the IC call in the deferred code
+    // which will allow the debugger to break for fast case stores.
+    __ bind(deferred->patch_site());
+    __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
+           Immediate(Factory::fixed_array_map()));
+    deferred->Branch(not_equal);
+
+    // Store the value.
+    __ mov(Operand(tmp.reg(),
+                   key.reg(),
+                   times_2,
+                   FixedArray::kHeaderSize - kHeapObjectTag),
+           result.reg());
+    __ IncrementCounter(&Counters::keyed_store_inline, 1);
+
+    deferred->BindExit();
+  } else {
+    result = frame()->CallKeyedStoreIC();
+    // Make sure that we do not have a test instruction after the
+    // call.  A test instruction after the call is used to
+    // indicate that we have generated an inline version of the
+    // keyed store.
+    __ nop();
+    frame()->Drop(2);
+  }
+  ASSERT(frame()->height() == original_height - 3);
+  return result;
 }
 
 
@@ -6548,7 +7024,7 @@
   } else {
     Literal* raw_name = property->key()->AsLiteral();
     ASSERT(raw_name != NULL);
-    return Handle<String>(String::cast(*raw_name->handle()));
+    return Handle<String>::cast(raw_name->handle());
   }
 }
 
@@ -6570,7 +7046,10 @@
       Comment cmnt(masm, "[ Load from Slot");
       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
       ASSERT(slot != NULL);
-      cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
+      Result result =
+          cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
+      if (!persist_after_get_) set_unloaded();
+      cgen_->frame()->Push(&result);
       break;
     }
 
@@ -6578,87 +7057,27 @@
       Variable* var = expression_->AsVariableProxy()->AsVariable();
       bool is_global = var != NULL;
       ASSERT(!is_global || var->is_global());
-
-      // Do not inline the inobject property case for loads from the global
-      // object.  Also do not inline for unoptimized code.  This saves time
-      // in the code generator.  Unoptimized code is toplevel code or code
-      // that is not in a loop.
-      if (is_global ||
-          cgen_->scope()->is_global_scope() ||
-          cgen_->loop_nesting() == 0) {
-        Comment cmnt(masm, "[ Load from named Property");
-        cgen_->frame()->Push(GetName());
-
-        RelocInfo::Mode mode = is_global
-                               ? RelocInfo::CODE_TARGET_CONTEXT
-                               : RelocInfo::CODE_TARGET;
-        Result answer = cgen_->frame()->CallLoadIC(mode);
-        // A test eax instruction following the call signals that the
-        // inobject property case was inlined.  Ensure that there is not
-        // a test eax instruction here.
-        __ nop();
-        cgen_->frame()->Push(&answer);
-      } else {
-        // Inline the inobject property case.
-        Comment cmnt(masm, "[ Inlined named property load");
-        Result receiver = cgen_->frame()->Pop();
-        receiver.ToRegister();
-
-        Result value = cgen_->allocator()->Allocate();
-        ASSERT(value.is_valid());
-        DeferredReferenceGetNamedValue* deferred =
-            new DeferredReferenceGetNamedValue(value.reg(),
-                                               receiver.reg(),
-                                               GetName());
-
-        // Check that the receiver is a heap object.
-        __ test(receiver.reg(), Immediate(kSmiTagMask));
-        deferred->Branch(zero);
-
-        __ bind(deferred->patch_site());
-        // This is the map check instruction that will be patched (so we can't
-        // use the double underscore macro that may insert instructions).
-        // Initially use an invalid map to force a failure.
-        masm->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
-                  Immediate(Factory::null_value()));
-        // This branch is always a forwards branch so it's always a fixed
-        // size which allows the assert below to succeed and patching to work.
-        deferred->Branch(not_equal);
-
-        // The delta from the patch label to the load offset must be
-        // statically known.
-        ASSERT(masm->SizeOfCodeGeneratedSince(deferred->patch_site()) ==
-               LoadIC::kOffsetToLoadInstruction);
-        // The initial (invalid) offset has to be large enough to force
-        // a 32-bit instruction encoding to allow patching with an
-        // arbitrary offset.  Use kMaxInt (minus kHeapObjectTag).
-        int offset = kMaxInt;
-        masm->mov(value.reg(), FieldOperand(receiver.reg(), offset));
-
-        __ IncrementCounter(&Counters::named_load_inline, 1);
-        deferred->BindExit();
-        cgen_->frame()->Push(&receiver);
-        cgen_->frame()->Push(&value);
-      }
+      if (persist_after_get_) cgen_->frame()->Dup();
+      Result result = cgen_->EmitNamedLoad(GetName(), is_global);
+      if (!persist_after_get_) set_unloaded();
+      cgen_->frame()->Push(&result);
       break;
     }
 
     case KEYED: {
-      Variable* var = expression_->AsVariableProxy()->AsVariable();
-      bool is_global = var != NULL;
-      ASSERT(!is_global || var->is_global());
-      Result value = cgen_->EmitKeyedLoad(is_global);
+      if (persist_after_get_) {
+        cgen_->frame()->PushElementAt(1);
+        cgen_->frame()->PushElementAt(1);
+      }
+      Result value = cgen_->EmitKeyedLoad();
       cgen_->frame()->Push(&value);
+      if (!persist_after_get_) set_unloaded();
       break;
     }
 
     default:
       UNREACHABLE();
   }
-
-  if (!persist_after_get_) {
-    cgen_->UnloadReference(this);
-  }
 }
 
 
@@ -6708,14 +7127,13 @@
       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
       ASSERT(slot != NULL);
       cgen_->StoreToSlot(slot, init_state);
-      cgen_->UnloadReference(this);
+      set_unloaded();
       break;
     }
 
     case NAMED: {
       Comment cmnt(masm, "[ Store to named Property");
-      cgen_->frame()->Push(GetName());
-      Result answer = cgen_->frame()->CallStoreIC();
+      Result answer = cgen_->EmitNamedStore(GetName(), false);
       cgen_->frame()->Push(&answer);
       set_unloaded();
       break;
@@ -6723,108 +7141,16 @@
 
     case KEYED: {
       Comment cmnt(masm, "[ Store to keyed Property");
-
-      // Generate inlined version of the keyed store if the code is in
-      // a loop and the key is likely to be a smi.
       Property* property = expression()->AsProperty();
       ASSERT(property != NULL);
-      StaticType* key_smi_analysis = property->key()->type();
-
-      if (cgen_->loop_nesting() > 0 && key_smi_analysis->IsLikelySmi()) {
-        Comment cmnt(masm, "[ Inlined store to keyed Property");
-
-        // Get the receiver, key and value into registers.
-        Result value = cgen_->frame()->Pop();
-        Result key = cgen_->frame()->Pop();
-        Result receiver = cgen_->frame()->Pop();
-
-        Result tmp = cgen_->allocator_->Allocate();
-        ASSERT(tmp.is_valid());
-
-        // Determine whether the value is a constant before putting it
-        // in a register.
-        bool value_is_constant = value.is_constant();
-
-        // Make sure that value, key and receiver are in registers.
-        value.ToRegister();
-        key.ToRegister();
-        receiver.ToRegister();
-
-        DeferredReferenceSetKeyedValue* deferred =
-            new DeferredReferenceSetKeyedValue(value.reg(),
-                                               key.reg(),
-                                               receiver.reg());
-
-        // Check that the value is a smi if it is not a constant.  We
-        // can skip the write barrier for smis and constants.
-        if (!value_is_constant) {
-          __ test(value.reg(), Immediate(kSmiTagMask));
-          deferred->Branch(not_zero);
-        }
-
-        // Check that the key is a non-negative smi.
-        __ test(key.reg(), Immediate(kSmiTagMask | 0x80000000));
-        deferred->Branch(not_zero);
-
-        // Check that the receiver is not a smi.
-        __ test(receiver.reg(), Immediate(kSmiTagMask));
-        deferred->Branch(zero);
-
-        // Check that the receiver is a JSArray.
-        __ mov(tmp.reg(),
-               FieldOperand(receiver.reg(), HeapObject::kMapOffset));
-        __ movzx_b(tmp.reg(),
-                   FieldOperand(tmp.reg(), Map::kInstanceTypeOffset));
-        __ cmp(tmp.reg(), JS_ARRAY_TYPE);
-        deferred->Branch(not_equal);
-
-        // Check that the key is within bounds.  Both the key and the
-        // length of the JSArray are smis.
-        __ cmp(key.reg(),
-               FieldOperand(receiver.reg(), JSArray::kLengthOffset));
-        deferred->Branch(greater_equal);
-
-        // Get the elements array from the receiver and check that it
-        // is not a dictionary.
-        __ mov(tmp.reg(),
-               FieldOperand(receiver.reg(), JSObject::kElementsOffset));
-        // Bind the deferred code patch site to be able to locate the
-        // fixed array map comparison.  When debugging, we patch this
-        // comparison to always fail so that we will hit the IC call
-        // in the deferred code which will allow the debugger to
-        // break for fast case stores.
-        __ bind(deferred->patch_site());
-        __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
-               Immediate(Factory::fixed_array_map()));
-        deferred->Branch(not_equal);
-
-        // Store the value.
-        __ mov(Operand(tmp.reg(),
-                       key.reg(),
-                       times_2,
-                       FixedArray::kHeaderSize - kHeapObjectTag),
-               value.reg());
-        __ IncrementCounter(&Counters::keyed_store_inline, 1);
-
-        deferred->BindExit();
-
-        cgen_->frame()->Push(&receiver);
-        cgen_->frame()->Push(&key);
-        cgen_->frame()->Push(&value);
-      } else {
-        Result answer = cgen_->frame()->CallKeyedStoreIC();
-        // Make sure that we do not have a test instruction after the
-        // call.  A test instruction after the call is used to
-        // indicate that we have generated an inline version of the
-        // keyed store.
-        __ nop();
-        cgen_->frame()->Push(&answer);
-      }
-      cgen_->UnloadReference(this);
+      Result answer = cgen_->EmitKeyedStore(property->key()->type());
+      cgen_->frame()->Push(&answer);
+      set_unloaded();
       break;
     }
 
-    default:
+    case UNLOADED:
+    case ILLEGAL:
       UNREACHABLE();
   }
 }
@@ -6918,6 +7244,13 @@
 
 
 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
+  // Stack layout on entry:
+  //
+  // [esp + kPointerSize]: constant elements.
+  // [esp + (2 * kPointerSize)]: literal index.
+  // [esp + (3 * kPointerSize)]: literals array.
+
+  // All sizes here are multiples of kPointerSize.
   int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
   int size = JSArray::kSize + elements_size;
 
@@ -7037,6 +7370,8 @@
         }
       } else if (left.is(left_arg)) {
         __ mov(right_arg, right);
+      } else if (right.is(right_arg)) {
+        __ mov(left_arg, left);
       } else if (left.is(right_arg)) {
         if (IsOperationCommutative()) {
           __ mov(left_arg, right);
@@ -7055,8 +7390,6 @@
           __ mov(right_arg, right);
           __ mov(left_arg, left);
         }
-      } else if (right.is(right_arg)) {
-        __ mov(left_arg, left);
       } else {
         // Order of moves is not important.
         __ mov(left_arg, left);
@@ -7092,6 +7425,10 @@
       __ mov(left_arg, Immediate(right));
       SetArgsReversed();
     } else {
+      // For non-commutative operations, left and right_arg might be
+      // the same register.  Therefore, the order of the moves is
+      // important here in order to not overwrite left before moving
+      // it to left_arg.
       __ mov(left_arg, left);
       __ mov(right_arg, Immediate(right));
     }
@@ -7124,8 +7461,12 @@
       __ mov(right_arg, Immediate(left));
       SetArgsReversed();
     } else {
-      __ mov(left_arg, Immediate(left));
+      // For non-commutative operations, right and left_arg might be
+      // the same register.  Therefore, the order of the moves is
+      // important here in order to not overwrite right before moving
+      // it to right_arg.
       __ mov(right_arg, right);
+      __ mov(left_arg, Immediate(left));
     }
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
@@ -7493,7 +7834,18 @@
     case Token::DIV: {
       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatures::Scope use_sse2(SSE2);
-        FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime);
+        if (NumberInfo::IsNumber(operands_type_)) {
+          if (FLAG_debug_code) {
+            // Assert at runtime that inputs are only numbers.
+            __ AbortIfNotNumber(edx,
+                                "GenericBinaryOpStub operand not a number.");
+            __ AbortIfNotNumber(eax,
+                                "GenericBinaryOpStub operand not a number.");
+          }
+          FloatingPointHelper::LoadSSE2Operands(masm);
+        } else {
+          FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime);
+        }
 
         switch (op_) {
           case Token::ADD: __ addsd(xmm0, xmm1); break;
@@ -7506,7 +7858,17 @@
         __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
         GenerateReturn(masm);
       } else {  // SSE2 not available, use FPU.
-        FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx);
+        if (NumberInfo::IsNumber(operands_type_)) {
+          if (FLAG_debug_code) {
+            // Assert at runtime that inputs are only numbers.
+            __ AbortIfNotNumber(edx,
+                                "GenericBinaryOpStub operand not a number.");
+            __ AbortIfNotNumber(eax,
+                                "GenericBinaryOpStub operand not a number.");
+          }
+        } else {
+          FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx);
+        }
         FloatingPointHelper::LoadFloatOperands(
             masm,
             ecx,
@@ -7618,7 +7980,7 @@
   switch (op_) {
     case Token::ADD: {
       // Test for string arguments before calling runtime.
-      Label not_strings, not_string1, string1;
+      Label not_strings, not_string1, string1, string1_smi2;
       Result answer;
       __ test(edx, Immediate(kSmiTagMask));
       __ j(zero, &not_string1);
@@ -7627,15 +7989,28 @@
 
       // First argument is a string, test second.
       __ test(eax, Immediate(kSmiTagMask));
-      __ j(zero, &string1);
+      __ j(zero, &string1_smi2);
       __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
       __ j(above_equal, &string1);
 
       // First and second argument are strings. Jump to the string add stub.
-      StringAddStub stub(NO_STRING_CHECK_IN_STUB);
-      __ TailCallStub(&stub);
+      StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
+      __ TailCallStub(&string_add_stub);
 
-      // Only first argument is a string.
+      __ bind(&string1_smi2);
+      // First argument is a string, second is a smi. Try to lookup the number
+      // string for the smi in the number string cache.
+      NumberToStringStub::GenerateLookupNumberStringCache(
+          masm, eax, edi, ebx, ecx, true, &string1);
+
+      // Call the string add stub to make the result.
+      __ EnterInternalFrame();
+      __ push(edx);  // Original first argument.
+      __ push(edi);  // Number to string result for second argument.
+      __ CallStub(&string_add_stub);
+      __ LeaveInternalFrame();
+      __ ret(2 * kPointerSize);
+
       __ bind(&string1);
       __ InvokeBuiltin(
           HasArgsReversed() ?
@@ -7766,6 +8141,212 @@
 }
 
 
+void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
+  // Input on stack:
+  // esp[4]: argument (should be number).
+  // esp[0]: return address.
+  // Test that eax is a number.
+  Label runtime_call;
+  Label runtime_call_clear_stack;
+  Label input_not_smi;
+  Label loaded;
+  __ mov(eax, Operand(esp, kPointerSize));
+  __ test(eax, Immediate(kSmiTagMask));
+  __ j(not_zero, &input_not_smi);
+  // Input is a smi. Untag and load it onto the FPU stack.
+  // Then load the low and high words of the double into ebx, edx.
+  ASSERT_EQ(1, kSmiTagSize);
+  __ sar(eax, 1);
+  __ sub(Operand(esp), Immediate(2 * kPointerSize));
+  __ mov(Operand(esp, 0), eax);
+  __ fild_s(Operand(esp, 0));
+  __ fst_d(Operand(esp, 0));
+  __ pop(edx);
+  __ pop(ebx);
+  __ jmp(&loaded);
+  __ bind(&input_not_smi);
+  // Check if input is a HeapNumber.
+  __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+  __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
+  __ j(not_equal, &runtime_call);
+  // Input is a HeapNumber. Push it on the FPU stack and load its
+  // low and high words into ebx, edx.
+  __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
+  __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
+  __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
+
+  __ bind(&loaded);
+  // ST[0] == double value
+  // ebx = low 32 bits of double value
+  // edx = high 32 bits of double value
+  // Compute hash:
+  //   h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
+  __ mov(ecx, ebx);
+  __ xor_(ecx, Operand(edx));
+  __ mov(eax, ecx);
+  __ sar(eax, 16);
+  __ xor_(ecx, Operand(eax));
+  __ mov(eax, ecx);
+  __ sar(eax, 8);
+  __ xor_(ecx, Operand(eax));
+  ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
+  __ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));
+  // ST[0] == double value.
+  // ebx = low 32 bits of double value.
+  // edx = high 32 bits of double value.
+  // ecx = TranscendentalCache::hash(double value).
+  __ mov(eax,
+         Immediate(ExternalReference::transcendental_cache_array_address()));
+  // Eax points to cache array.
+  __ mov(eax, Operand(eax, type_ * sizeof(TranscendentalCache::caches_[0])));
+  // Eax points to the cache for the type type_.
+  // If NULL, the cache hasn't been initialized yet, so go through runtime.
+  __ test(eax, Operand(eax));
+  __ j(zero, &runtime_call_clear_stack);
+#ifdef DEBUG
+  // Check that the layout of cache elements match expectations.
+  {  // NOLINT - doesn't like a single brace on a line.
+    TranscendentalCache::Element test_elem[2];
+    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
+    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
+    char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
+    char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
+    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
+    CHECK_EQ(12, elem2_start - elem_start);  // Two uint_32's and a pointer.
+    CHECK_EQ(0, elem_in0 - elem_start);
+    CHECK_EQ(kIntSize, elem_in1 - elem_start);
+    CHECK_EQ(2 * kIntSize, elem_out - elem_start);
+  }
+#endif
+  // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
+  __ lea(ecx, Operand(ecx, ecx, times_2, 0));
+  __ lea(ecx, Operand(eax, ecx, times_4, 0));
+  // Check if cache matches: Double value is stored in uint32_t[2] array.
+  Label cache_miss;
+  __ cmp(ebx, Operand(ecx, 0));
+  __ j(not_equal, &cache_miss);
+  __ cmp(edx, Operand(ecx, kIntSize));
+  __ j(not_equal, &cache_miss);
+  // Cache hit!
+  __ mov(eax, Operand(ecx, 2 * kIntSize));
+  __ fstp(0);
+  __ ret(kPointerSize);
+
+  __ bind(&cache_miss);
+  // Update cache with new value.
+  // We are short on registers, so use no_reg as scratch.
+  // This gives slightly larger code.
+  __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
+  GenerateOperation(masm);
+  __ mov(Operand(ecx, 0), ebx);
+  __ mov(Operand(ecx, kIntSize), edx);
+  __ mov(Operand(ecx, 2 * kIntSize), eax);
+  __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
+  __ ret(kPointerSize);
+
+  __ bind(&runtime_call_clear_stack);
+  __ fstp(0);
+  __ bind(&runtime_call);
+  __ TailCallRuntime(ExternalReference(RuntimeFunction()), 1, 1);
+}
+
+
+Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
+  switch (type_) {
+    // Add more cases when necessary.
+    case TranscendentalCache::SIN: return Runtime::kMath_sin;
+    case TranscendentalCache::COS: return Runtime::kMath_cos;
+    default:
+      UNIMPLEMENTED();
+      return Runtime::kAbort;
+  }
+}
+
+
+void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
+  // Only free register is edi.
+  Label done;
+  ASSERT(type_ == TranscendentalCache::SIN ||
+         type_ == TranscendentalCache::COS);
+  // More transcendental types can be added later.
+
+  // Both fsin and fcos require arguments in the range +/-2^63 and
+  // return NaN for infinities and NaN. They can share all code except
+  // the actual fsin/fcos operation.
+  Label in_range;
+  // If argument is outside the range -2^63..2^63, fsin/cos doesn't
+  // work. We must reduce it to the appropriate range.
+  __ mov(edi, edx);
+  __ and_(Operand(edi), Immediate(0x7ff00000));  // Exponent only.
+  int supported_exponent_limit =
+      (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift;
+  __ cmp(Operand(edi), Immediate(supported_exponent_limit));
+  __ j(below, &in_range, taken);
+  // Check for infinity and NaN. Both return NaN for sin.
+  __ cmp(Operand(edi), Immediate(0x7ff00000));
+  Label non_nan_result;
+  __ j(not_equal, &non_nan_result, taken);
+  // Input is +/-Infinity or NaN. Result is NaN.
+  __ fstp(0);
+  // NaN is represented by 0x7ff8000000000000.
+  __ push(Immediate(0x7ff80000));
+  __ push(Immediate(0));
+  __ fld_d(Operand(esp, 0));
+  __ add(Operand(esp), Immediate(2 * kPointerSize));
+  __ jmp(&done);
+
+  __ bind(&non_nan_result);
+
+  // Use fpmod to restrict argument to the range +/-2*PI.
+  __ mov(edi, eax);  // Save eax before using fnstsw_ax.
+  __ fldpi();
+  __ fadd(0);
+  __ fld(1);
+  // FPU Stack: input, 2*pi, input.
+  {
+    Label no_exceptions;
+    __ fwait();
+    __ fnstsw_ax();
+    // Clear if Illegal Operand or Zero Division exceptions are set.
+    __ test(Operand(eax), Immediate(5));
+    __ j(zero, &no_exceptions);
+    __ fnclex();
+    __ bind(&no_exceptions);
+  }
+
+  // Compute st(0) % st(1)
+  {
+    Label partial_remainder_loop;
+    __ bind(&partial_remainder_loop);
+    __ fprem1();
+    __ fwait();
+    __ fnstsw_ax();
+    __ test(Operand(eax), Immediate(0x400 /* C2 */));
+    // If C2 is set, computation only has partial result. Loop to
+    // continue computation.
+    __ j(not_zero, &partial_remainder_loop);
+  }
+  // FPU Stack: input, 2*pi, input % 2*pi
+  __ fstp(2);
+  __ fstp(0);
+  __ mov(eax, edi);  // Restore eax (allocated HeapNumber pointer).
+
+  // FPU Stack: input % 2*pi
+  __ bind(&in_range);
+  switch (type_) {
+    case TranscendentalCache::SIN:
+      __ fsin();
+      break;
+    case TranscendentalCache::COS:
+      __ fcos();
+      break;
+    default:
+      UNREACHABLE();
+  }
+  __ bind(&done);
+}
+
+
 // Get the integer part of a heap number.  Surprisingly, all this bit twiddling
 // is faster than using the built-in instructions on floating point registers.
 // Trashes edi and ebx.  Dest is ecx.  Source cannot be ecx or one of the
@@ -7977,6 +8558,35 @@
 }
 
 
+void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm) {
+  Label load_smi_edx, load_eax, load_smi_eax, done;
+  // Load operand in edx into xmm0.
+  __ test(edx, Immediate(kSmiTagMask));
+  __ j(zero, &load_smi_edx, not_taken);  // Argument in edx is a smi.
+  __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
+
+  __ bind(&load_eax);
+  // Load operand in eax into xmm1.
+  __ test(eax, Immediate(kSmiTagMask));
+  __ j(zero, &load_smi_eax, not_taken);  // Argument in eax is a smi.
+  __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+  __ jmp(&done);
+
+  __ bind(&load_smi_edx);
+  __ SmiUntag(edx);  // Untag smi before converting to float.
+  __ cvtsi2sd(xmm0, Operand(edx));
+  __ SmiTag(edx);  // Retag smi for heap number overwriting test.
+  __ jmp(&load_eax);
+
+  __ bind(&load_smi_eax);
+  __ SmiUntag(eax);  // Untag smi before converting to float.
+  __ cvtsi2sd(xmm1, Operand(eax));
+  __ SmiTag(eax);  // Retag smi for heap number overwriting test.
+
+  __ bind(&done);
+}
+
+
 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
                                            Label* not_numbers) {
   Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
@@ -8306,6 +8916,11 @@
 
 
 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+  // esp[0] : return address
+  // esp[4] : number of parameters
+  // esp[8] : receiver displacement
+  // esp[16] : function
+
   // The displacement is used for skipping the return address and the
   // frame pointer on the stack. It is the offset of the last
   // parameter (if any) relative to the frame pointer.
@@ -8389,7 +9004,6 @@
   __ add(Operand(edi), Immediate(kPointerSize));
   __ sub(Operand(edx), Immediate(kPointerSize));
   __ dec(ecx);
-  __ test(ecx, Operand(ecx));
   __ j(not_zero, &loop);
 
   // Return and remove the on-stack parameters.
@@ -8737,6 +9351,74 @@
 }
 
 
+void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
+                                                         Register object,
+                                                         Register result,
+                                                         Register scratch1,
+                                                         Register scratch2,
+                                                         bool object_is_smi,
+                                                         Label* not_found) {
+  // Currently only lookup for smis. Check for smi if object is not known to be
+  // a smi.
+  if (!object_is_smi) {
+    ASSERT(kSmiTag == 0);
+    __ test(object, Immediate(kSmiTagMask));
+    __ j(not_zero, not_found);
+  }
+
+  // Use of registers. Register result is used as a temporary.
+  Register number_string_cache = result;
+  Register mask = scratch1;
+  Register scratch = scratch2;
+
+  // Load the number string cache.
+  ExternalReference roots_address = ExternalReference::roots_address();
+  __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
+  __ mov(number_string_cache,
+         Operand::StaticArray(scratch, times_pointer_size, roots_address));
+  // Make the hash mask from the length of the number string cache. It
+  // contains two elements (number and string) for each cache entry.
+  __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
+  __ shr(mask, 1);  // Divide length by two (length is not a smi).
+  __ sub(Operand(mask), Immediate(1));  // Make mask.
+  // Calculate the entry in the number string cache. The hash value in the
+  // number string cache for smis is just the smi value.
+  __ mov(scratch, object);
+  __ SmiUntag(scratch);
+  __ and_(scratch, Operand(mask));
+  // Check if the entry is the smi we are looking for.
+  __ cmp(object,
+         FieldOperand(number_string_cache,
+                      scratch,
+                      times_twice_pointer_size,
+                      FixedArray::kHeaderSize));
+  __ j(not_equal, not_found);
+
+  // Get the result from the cache.
+  __ mov(result,
+         FieldOperand(number_string_cache,
+                      scratch,
+                      times_twice_pointer_size,
+                      FixedArray::kHeaderSize + kPointerSize));
+  __ IncrementCounter(&Counters::number_to_string_native, 1);
+}
+
+
+void NumberToStringStub::Generate(MacroAssembler* masm) {
+  Label runtime;
+
+  __ mov(ebx, Operand(esp, kPointerSize));
+
+  // Generate code to lookup number in the number string cache.
+  GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime);
+  __ ret(1 * kPointerSize);
+
+  __ bind(&runtime);
+  // Handle number to string in the runtime system if not found in the cache.
+  __ TailCallRuntime(ExternalReference(Runtime::kNumberToString), 1, 1);
+}
+
+
 void CompareStub::Generate(MacroAssembler* masm) {
   Label call_builtin, done;
 
@@ -9069,6 +9751,9 @@
 
   // Slow-case: Non-function called.
   __ bind(&slow);
+  // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+  // of the original receiver from the call site).
+  __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
   __ Set(eax, Immediate(argc_));
   __ Set(ebx, Immediate(0));
   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
@@ -9642,13 +10327,34 @@
   // ecx: length of second string
   // edx: second string
   // Look at the length of the result of adding the two strings.
-  Label string_add_flat_result;
+  Label string_add_flat_result, longer_than_two;
   __ bind(&both_not_zero_length);
   __ add(ebx, Operand(ecx));
   // Use the runtime system when adding two one character strings, as it
   // contains optimizations for this specific case using the symbol table.
   __ cmp(ebx, 2);
-  __ j(equal, &string_add_runtime);
+  __ j(not_equal, &longer_than_two);
+
+  // Check that both strings are non-external ascii strings.
+  __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
+                                         &string_add_runtime);
+
+  // Get the two characters forming the sub string.
+  __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
+  __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
+
+  // Try to lookup two character string in symbol table. If it is not found
+  // just allocate a new one.
+  Label make_two_character_string, make_flat_ascii_string;
+  GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
+                                       &make_two_character_string);
+  __ ret(2 * kPointerSize);
+
+  __ bind(&make_two_character_string);
+  __ Set(ebx, Immediate(2));
+  __ jmp(&make_flat_ascii_string);
+
+  __ bind(&longer_than_two);
   // Check if resulting string will be flat.
   __ cmp(ebx, String::kMinNonFlatLength);
   __ j(below, &string_add_flat_result);
@@ -9715,7 +10421,10 @@
   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   __ test(ecx, Immediate(kAsciiStringTag));
   __ j(zero, &string_add_runtime);
+
+  __ bind(&make_flat_ascii_string);
   // Both strings are ascii strings. As they are short they are both flat.
+  // ebx: length of resulting flat string
   __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
   // eax: result string
   __ mov(ecx, eax);
@@ -9872,6 +10581,190 @@
 }
 
 
+void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
+                                                          Register c1,
+                                                          Register c2,
+                                                          Register scratch1,
+                                                          Register scratch2,
+                                                          Register scratch3,
+                                                          Label* not_found) {
+  // Register scratch3 is the general scratch register in this function.
+  Register scratch = scratch3;
+
+  // Make sure that both characters are not digits as such strings has a
+  // different hash algorithm. Don't try to look for these in the symbol table.
+  Label not_array_index;
+  __ mov(scratch, c1);
+  __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
+  __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
+  __ j(above, &not_array_index);
+  __ mov(scratch, c2);
+  __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
+  __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
+  __ j(below_equal, not_found);
+
+  __ bind(&not_array_index);
+  // Calculate the two character string hash.
+  Register hash = scratch1;
+  GenerateHashInit(masm, hash, c1, scratch);
+  GenerateHashAddCharacter(masm, hash, c2, scratch);
+  GenerateHashGetHash(masm, hash, scratch);
+
+  // Collect the two characters in a register.
+  Register chars = c1;
+  __ shl(c2, kBitsPerByte);
+  __ or_(chars, Operand(c2));
+
+  // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
+  // hash:  hash of two character string.
+
+  // Load the symbol table.
+  Register symbol_table = c2;
+  ExternalReference roots_address = ExternalReference::roots_address();
+  __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex));
+  __ mov(symbol_table,
+         Operand::StaticArray(scratch, times_pointer_size, roots_address));
+
+  // Calculate capacity mask from the symbol table capacity.
+  Register mask = scratch2;
+  static const int kCapacityOffset =
+      FixedArray::kHeaderSize +
+      SymbolTable::kCapacityIndex * kPointerSize;
+  __ mov(mask, FieldOperand(symbol_table, kCapacityOffset));
+  __ SmiUntag(mask);
+  __ sub(Operand(mask), Immediate(1));
+
+  // Registers
+  // chars:        two character string, char 1 in byte 0 and char 2 in byte 1.
+  // hash:         hash of two character string
+  // symbol_table: symbol table
+  // mask:         capacity mask
+  // scratch:      -
+
+  // Perform a number of probes in the symbol table.
+  static const int kProbes = 4;
+  Label found_in_symbol_table;
+  Label next_probe[kProbes], next_probe_pop_mask[kProbes];
+  for (int i = 0; i < kProbes; i++) {
+    // Calculate entry in symbol table.
+    __ mov(scratch, hash);
+    if (i > 0) {
+      __ add(Operand(scratch), Immediate(SymbolTable::GetProbeOffset(i)));
+    }
+    __ and_(scratch, Operand(mask));
+
+    // Load the entry from the symble table.
+    Register candidate = scratch;  // Scratch register contains candidate.
+    ASSERT_EQ(1, SymbolTableShape::kEntrySize);
+    static const int kFirstElementOffset =
+        FixedArray::kHeaderSize +
+        SymbolTable::kPrefixStartIndex * kPointerSize +
+        SymbolTableShape::kPrefixSize * kPointerSize;
+    __ mov(candidate,
+           FieldOperand(symbol_table,
+                        scratch,
+                        times_pointer_size,
+                        kFirstElementOffset));
+
+    // If entry is undefined no string with this hash can be found.
+    __ cmp(candidate, Factory::undefined_value());
+    __ j(equal, not_found);
+
+    // If length is not 2 the string is not a candidate.
+    __ cmp(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
+    __ j(not_equal, &next_probe[i]);
+
+    // As we are out of registers save the mask on the stack and use that
+    // register as a temporary.
+    __ push(mask);
+    Register temp = mask;
+
+    // Check that the candidate is a non-external ascii string.
+    __ mov(temp, FieldOperand(candidate, HeapObject::kMapOffset));
+    __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+    __ JumpIfInstanceTypeIsNotSequentialAscii(
+        temp, temp, &next_probe_pop_mask[i]);
+
+    // Check if the two characters match.
+    __ mov(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
+    __ and_(temp, 0x0000ffff);
+    __ cmp(chars, Operand(temp));
+    __ j(equal, &found_in_symbol_table);
+    __ bind(&next_probe_pop_mask[i]);
+    __ pop(mask);
+    __ bind(&next_probe[i]);
+  }
+
+  // No matching 2 character string found by probing.
+  __ jmp(not_found);
+
+  // Scratch register contains result when we fall through to here.
+  Register result = scratch;
+  __ bind(&found_in_symbol_table);
+  __ pop(mask);  // Pop temporally saved mask from the stack.
+  if (!result.is(eax)) {
+    __ mov(eax, result);
+  }
+}
+
+
+void StringStubBase::GenerateHashInit(MacroAssembler* masm,
+                                      Register hash,
+                                      Register character,
+                                      Register scratch) {
+  // hash = character + (character << 10);
+  __ mov(hash, character);
+  __ shl(hash, 10);
+  __ add(hash, Operand(character));
+  // hash ^= hash >> 6;
+  __ mov(scratch, hash);
+  __ sar(scratch, 6);
+  __ xor_(hash, Operand(scratch));
+}
+
+
+void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm,
+                                              Register hash,
+                                              Register character,
+                                              Register scratch) {
+  // hash += character;
+  __ add(hash, Operand(character));
+  // hash += hash << 10;
+  __ mov(scratch, hash);
+  __ shl(scratch, 10);
+  __ add(hash, Operand(scratch));
+  // hash ^= hash >> 6;
+  __ mov(scratch, hash);
+  __ sar(scratch, 6);
+  __ xor_(hash, Operand(scratch));
+}
+
+
+void StringStubBase::GenerateHashGetHash(MacroAssembler* masm,
+                                         Register hash,
+                                         Register scratch) {
+  // hash += hash << 3;
+  __ mov(scratch, hash);
+  __ shl(scratch, 3);
+  __ add(hash, Operand(scratch));
+  // hash ^= hash >> 11;
+  __ mov(scratch, hash);
+  __ sar(scratch, 11);
+  __ xor_(hash, Operand(scratch));
+  // hash += hash << 15;
+  __ mov(scratch, hash);
+  __ shl(scratch, 15);
+  __ add(hash, Operand(scratch));
+
+  // if (hash == 0) hash = 27;
+  Label hash_not_zero;
+  __ test(hash, Operand(hash));
+  __ j(not_zero, &hash_not_zero);
+  __ mov(hash, Immediate(27));
+  __ bind(&hash_not_zero);
+}
+
+
 void SubStringStub::Generate(MacroAssembler* masm) {
   Label runtime;
 
@@ -9892,26 +10785,55 @@
   // eax: string
   // ebx: instance type
   // Calculate length of sub string using the smi values.
-  __ mov(ecx, Operand(esp, 1 * kPointerSize));  // to
+  Label result_longer_than_two;
+  __ mov(ecx, Operand(esp, 1 * kPointerSize));  // To index.
   __ test(ecx, Immediate(kSmiTagMask));
   __ j(not_zero, &runtime);
-  __ mov(edx, Operand(esp, 2 * kPointerSize));  // from
+  __ mov(edx, Operand(esp, 2 * kPointerSize));  // From index.
   __ test(edx, Immediate(kSmiTagMask));
   __ j(not_zero, &runtime);
   __ sub(ecx, Operand(edx));
-  // Handle sub-strings of length 2 and less in the runtime system.
+  // Special handling of sub-strings of length 1 and 2. One character strings
+  // are handled in the runtime system (looked up in the single character
+  // cache). Two character strings are looked for in the symbol cache.
   __ SmiUntag(ecx);  // Result length is no longer smi.
   __ cmp(ecx, 2);
-  __ j(below_equal, &runtime);
+  __ j(greater, &result_longer_than_two);
+  __ j(less, &runtime);
 
+  // Sub string of length 2 requested.
+  // eax: string
+  // ebx: instance type
+  // ecx: sub string length (value is 2)
+  // edx: from index (smi)
+  __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &runtime);
+
+  // Get the two characters forming the sub string.
+  __ SmiUntag(edx);  // From index is no longer smi.
+  __ movzx_b(ebx, FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize));
+  __ movzx_b(ecx,
+             FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize + 1));
+
+  // Try to lookup two character string in symbol table.
+  Label make_two_character_string;
+  GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
+                                     &make_two_character_string);
+  __ ret(2 * kPointerSize);
+
+  __ bind(&make_two_character_string);
+  // Setup registers for allocating the two character string.
+  __ mov(eax, Operand(esp, 3 * kPointerSize));
+  __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+  __ Set(ecx, Immediate(2));
+
+  __ bind(&result_longer_than_two);
   // eax: string
   // ebx: instance type
   // ecx: result string length
   // Check for flat ascii string
   Label non_ascii_flat;
-  __ and_(ebx, kStringRepresentationMask | kStringEncodingMask);
-  __ cmp(ebx, kSeqStringTag | kAsciiStringTag);
-  __ j(not_equal, &non_ascii_flat);
+  __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &non_ascii_flat);
 
   // Allocate the result.
   __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime);
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 843bbf7..b84a6bb 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -294,15 +294,6 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Compilation mode.  Either the compiler is used as the primary
-  // compiler and needs to setup everything or the compiler is used as
-  // the secondary compiler for split compilation and has to handle
-  // bailouts.
-  enum Mode {
-    PRIMARY,
-    SECONDARY
-  };
-
   // Takes a function literal, generates code for it. This function should only
   // be called by compiler.cc.
   static Handle<Code> MakeCode(CompilationInfo* info);
@@ -384,7 +375,7 @@
   void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
 
   // Main code generation function
-  void Generate(CompilationInfo* info, Mode mode);
+  void Generate(CompilationInfo* info);
 
   // Generate the return sequence code.  Should be called no more than
   // once per compiled function, immediately after binding the return
@@ -429,8 +420,8 @@
   void LoadAndSpill(Expression* expression);
 
   // Read a value from a slot and leave it on top of the expression stack.
-  void LoadFromSlot(Slot* slot, TypeofState typeof_state);
-  void LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state);
+  Result LoadFromSlot(Slot* slot, TypeofState typeof_state);
+  Result LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state);
   Result LoadFromGlobalSlotCheckExtensions(Slot* slot,
                                            TypeofState typeof_state,
                                            JumpTarget* slow);
@@ -439,10 +430,23 @@
   // value in place.
   void StoreToSlot(Slot* slot, InitState init_state);
 
-  // Load a property of an object, returning it in a Result.
-  // The object and the property name are passed on the stack, and
-  // not changed.
-  Result EmitKeyedLoad(bool is_global);
+  // Support for compiling assignment expressions.
+  void EmitSlotAssignment(Assignment* node);
+  void EmitNamedPropertyAssignment(Assignment* node);
+  void EmitKeyedPropertyAssignment(Assignment* node);
+
+  // Receiver is passed on the frame and consumed.
+  Result EmitNamedLoad(Handle<String> name, bool is_contextual);
+
+  // If the store is contextual, value is passed on the frame and consumed.
+  // Otherwise, receiver and value are passed on the frame and consumed.
+  Result EmitNamedStore(Handle<String> name, bool is_contextual);
+
+  // Receiver and key are passed on the frame and consumed.
+  Result EmitKeyedLoad();
+
+  // Receiver, key, and value are passed on the frame and consumed.
+  Result EmitKeyedStore(StaticType* key_type);
 
   // Special code for typeof expressions: Unfortunately, we must
   // be careful when loading the expression in 'typeof'
@@ -533,12 +537,13 @@
   void DeclareGlobals(Handle<FixedArray> pairs);
 
   // Instantiate the function boilerplate.
-  void InstantiateBoilerplate(Handle<JSFunction> boilerplate);
+  Result InstantiateBoilerplate(Handle<JSFunction> boilerplate);
 
   // Support for type checks.
   void GenerateIsSmi(ZoneList<Expression*>* args);
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
+  void GenerateIsRegExp(ZoneList<Expression*>* args);
   void GenerateIsObject(ZoneList<Expression*>* args);
   void GenerateIsFunction(ZoneList<Expression*>* args);
   void GenerateIsUndetectableObject(ZoneList<Expression*>* args);
@@ -580,6 +585,13 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
+  // Fast support for number to string.
+  void GenerateNumberToString(ZoneList<Expression*>* args);
+
+  // Fast call to transcendental functions.
+  void GenerateMathSin(ZoneList<Expression*>* args);
+  void GenerateMathCos(ZoneList<Expression*>* args);
+
   // Simple condition analysis.
   enum ConditionAnalysis {
     ALWAYS_TRUE,
@@ -647,6 +659,22 @@
 };
 
 
+// Compute a transcendental math function natively, or call the
+// TranscendentalCache runtime function.
+class TranscendentalCacheStub: public CodeStub {
+ public:
+  explicit TranscendentalCacheStub(TranscendentalCache::Type type)
+      : type_(type) {}
+  void Generate(MacroAssembler* masm);
+ private:
+  TranscendentalCache::Type type_;
+  Major MajorKey() { return TranscendentalCache; }
+  int MinorKey() { return type_; }
+  Runtime::FunctionId RuntimeFunction();
+  void GenerateOperation(MacroAssembler* masm);
+};
+
+
 // Flag that indicates how to generate code for the stub GenericBinaryOpStub.
 enum GenericBinaryFlags {
   NO_GENERIC_BINARY_FLAGS = 0,
@@ -658,13 +686,15 @@
  public:
   GenericBinaryOpStub(Token::Value op,
                       OverwriteMode mode,
-                      GenericBinaryFlags flags)
+                      GenericBinaryFlags flags,
+                      NumberInfo::Type operands_type = NumberInfo::kUnknown)
       : op_(op),
         mode_(mode),
         flags_(flags),
         args_in_registers_(false),
         args_reversed_(false),
-        name_(NULL) {
+        name_(NULL),
+        operands_type_(operands_type) {
     use_sse3_ = CpuFeatures::IsSupported(SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -689,28 +719,32 @@
   bool args_reversed_;  // Left and right argument are swapped.
   bool use_sse3_;
   char* name_;
+  NumberInfo::Type operands_type_;  // Number type information of operands.
 
   const char* GetName();
 
 #ifdef DEBUG
   void Print() {
-    PrintF("GenericBinaryOpStub (op %s), "
-           "(mode %d, flags %d, registers %d, reversed %d)\n",
+    PrintF("GenericBinaryOpStub %d (op %s), "
+           "(mode %d, flags %d, registers %d, reversed %d, number_info %s)\n",
+           MinorKey(),
            Token::String(op_),
            static_cast<int>(mode_),
            static_cast<int>(flags_),
            static_cast<int>(args_in_registers_),
-           static_cast<int>(args_reversed_));
+           static_cast<int>(args_reversed_),
+           NumberInfo::ToString(operands_type_));
   }
 #endif
 
-  // Minor key encoding in 16 bits FRASOOOOOOOOOOMM.
+  // Minor key encoding in 16 bits NNNFRASOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
-  class OpBits: public BitField<Token::Value, 2, 10> {};
-  class SSE3Bits: public BitField<bool, 12, 1> {};
-  class ArgsInRegistersBits: public BitField<bool, 13, 1> {};
-  class ArgsReversedBits: public BitField<bool, 14, 1> {};
-  class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
+  class OpBits: public BitField<Token::Value, 2, 7> {};
+  class SSE3Bits: public BitField<bool, 9, 1> {};
+  class ArgsInRegistersBits: public BitField<bool, 10, 1> {};
+  class ArgsReversedBits: public BitField<bool, 11, 1> {};
+  class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
+  class NumberInfoBits: public BitField<NumberInfo::Type, 13, 3> {};
 
   Major MajorKey() { return GenericBinaryOp; }
   int MinorKey() {
@@ -720,7 +754,8 @@
            | FlagBits::encode(flags_)
            | SSE3Bits::encode(use_sse3_)
            | ArgsInRegistersBits::encode(args_in_registers_)
-           | ArgsReversedBits::encode(args_reversed_);
+           | ArgsReversedBits::encode(args_reversed_)
+           | NumberInfoBits::encode(operands_type_);
   }
 
   void Generate(MacroAssembler* masm);
@@ -767,6 +802,31 @@
                                  Register count,    // Must be ecx.
                                  Register scratch,  // Neither of the above.
                                  bool ascii);
+
+  // Probe the symbol table for a two character string. If the string is
+  // not found by probing a jump to the label not_found is performed. This jump
+  // does not guarantee that the string is not in the symbol table. If the
+  // string is found the code falls through with the string in register eax.
+  void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
+                                            Register c1,
+                                            Register c2,
+                                            Register scratch1,
+                                            Register scratch2,
+                                            Register scratch3,
+                                            Label* not_found);
+
+  // Generate string hash.
+  void GenerateHashInit(MacroAssembler* masm,
+                        Register hash,
+                        Register character,
+                        Register scratch);
+  void GenerateHashAddCharacter(MacroAssembler* masm,
+                                Register hash,
+                                Register character,
+                                Register scratch);
+  void GenerateHashGetHash(MacroAssembler* masm,
+                           Register hash,
+                           Register scratch);
 };
 
 
@@ -828,6 +888,39 @@
 };
 
 
+class NumberToStringStub: public CodeStub {
+ public:
+  NumberToStringStub() { }
+
+  // Generate code to do a lookup in the number string cache. If the number in
+  // the register object is found in the cache the generated code falls through
+  // with the result in the result register. The object and the result register
+  // can be the same. If the number is not found in the cache the code jumps to
+  // the label not_found with only the content of register object unchanged.
+  static void GenerateLookupNumberStringCache(MacroAssembler* masm,
+                                              Register object,
+                                              Register result,
+                                              Register scratch1,
+                                              Register scratch2,
+                                              bool object_is_smi,
+                                              Label* not_found);
+
+ private:
+  Major MajorKey() { return NumberToString; }
+  int MinorKey() { return 0; }
+
+  void Generate(MacroAssembler* masm);
+
+  const char* GetName() { return "NumberToStringStub"; }
+
+#ifdef DEBUG
+  void Print() {
+    PrintF("NumberToStringStub\n");
+  }
+#endif
+};
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_IA32_CODEGEN_IA32_H_
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index 1f34b30..a9e2626 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -125,9 +125,10 @@
 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
   // Register state for IC load call (from ic-ia32.cc).
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   // -----------------------------------
-  Generate_DebugBreakCallHelper(masm, ecx.bit(), false);
+  Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), false);
 }
 
 
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index cb500d5..a085900 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -679,6 +679,7 @@
 
     case 0xDD: switch (regop) {
         case 0: mnem = "fld_d"; break;
+        case 2: mnem = "fstp"; break;
         case 3: mnem = "fstp_d"; break;
         default: UnimplementedInstruction();
       }
@@ -720,6 +721,7 @@
             case 0xE1: mnem = "fabs"; break;
             case 0xE4: mnem = "ftst"; break;
             case 0xE8: mnem = "fld1"; break;
+            case 0xEB: mnem = "fldpi"; break;
             case 0xEE: mnem = "fldz"; break;
             case 0xF5: mnem = "fprem1"; break;
             case 0xF7: mnem = "fincstp"; break;
@@ -1014,7 +1016,6 @@
           int mod, regop, rm;
           get_modrm(*data, &mod, &regop, &rm);
           const char* mnem = NULL;
-          printf("%d\n", regop);
           switch (regop) {
             case 5:  mnem = "subb"; break;
             case 7:  mnem = "cmpb"; break;
diff --git a/src/ia32/fast-codegen-ia32.cc b/src/ia32/fast-codegen-ia32.cc
index 126f96b..f1c2507 100644
--- a/src/ia32/fast-codegen-ia32.cc
+++ b/src/ia32/fast-codegen-ia32.cc
@@ -29,56 +29,474 @@
 
 #include "codegen-inl.h"
 #include "fast-codegen.h"
+#include "data-flow.h"
+#include "scopes.h"
 
 namespace v8 {
 namespace internal {
 
+#define BAILOUT(reason)                         \
+  do {                                          \
+    if (FLAG_trace_bailout) {                   \
+      PrintF("%s\n", reason);                   \
+    }                                           \
+    has_supported_syntax_ = false;              \
+    return;                                     \
+  } while (false)
+
+
+#define CHECK_BAILOUT                           \
+  do {                                          \
+    if (!has_supported_syntax_) return;         \
+  } while (false)
+
+
+void FastCodeGenSyntaxChecker::Check(CompilationInfo* info) {
+  info_ = info;
+
+  // We do not specialize if we do not have a receiver or if it is not a
+  // JS object with fast mode properties.
+  if (!info->has_receiver()) BAILOUT("No receiver");
+  if (!info->receiver()->IsJSObject()) BAILOUT("Receiver is not an object");
+  Handle<JSObject> object = Handle<JSObject>::cast(info->receiver());
+  if (!object->HasFastProperties()) BAILOUT("Receiver is in dictionary mode");
+
+  // We do not support stack or heap slots (both of which require
+  // allocation).
+  Scope* scope = info->scope();
+  if (scope->num_stack_slots() > 0) {
+    BAILOUT("Function has stack-allocated locals");
+  }
+  if (scope->num_heap_slots() > 0) {
+    BAILOUT("Function has context-allocated locals");
+  }
+
+  VisitDeclarations(scope->declarations());
+  CHECK_BAILOUT;
+
+  // We do not support empty function bodies.
+  if (info->function()->body()->is_empty()) {
+    BAILOUT("Function has an empty body");
+  }
+  VisitStatements(info->function()->body());
+}
+
+
+void FastCodeGenSyntaxChecker::VisitDeclarations(
+    ZoneList<Declaration*>* decls) {
+  if (!decls->is_empty()) BAILOUT("Function has declarations");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
+  if (stmts->length() != 1) {
+    BAILOUT("Function body is not a singleton statement.");
+  }
+  Visit(stmts->at(0));
+}
+
+
+void FastCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
+  VisitStatements(stmt->statements());
+}
+
+
+void FastCodeGenSyntaxChecker::VisitExpressionStatement(
+    ExpressionStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void FastCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
+  // Supported.
+}
+
+
+void FastCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
+  BAILOUT("IfStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
+  BAILOUT("Continuestatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {
+  BAILOUT("BreakStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
+  BAILOUT("ReturnStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitWithEnterStatement(
+    WithEnterStatement* stmt) {
+  BAILOUT("WithEnterStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
+  BAILOUT("WithExitStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
+  BAILOUT("SwitchStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
+  BAILOUT("DoWhileStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
+  BAILOUT("WhileStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
+  BAILOUT("ForStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
+  BAILOUT("ForInStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
+  BAILOUT("TryCatchStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitTryFinallyStatement(
+    TryFinallyStatement* stmt) {
+  BAILOUT("TryFinallyStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitDebuggerStatement(
+    DebuggerStatement* stmt) {
+  BAILOUT("DebuggerStatement");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
+  BAILOUT("FunctionLiteral");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral(
+    FunctionBoilerplateLiteral* expr) {
+  BAILOUT("FunctionBoilerplateLiteral");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
+  BAILOUT("Conditional");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
+  // Only global variable references are supported.
+  Variable* var = expr->var();
+  if (!var->is_global() || var->is_this()) BAILOUT("Non-global variable");
+
+  // Check if the global variable is existing and non-deletable.
+  if (info()->has_global_object()) {
+    LookupResult lookup;
+    info()->global_object()->Lookup(*expr->name(), &lookup);
+    if (!lookup.IsProperty()) {
+      BAILOUT("Non-existing global variable");
+    }
+    // We do not handle global variables with accessors or interceptors.
+    if (lookup.type() != NORMAL) {
+      BAILOUT("Global variable with accessors or interceptors.");
+    }
+    // We do not handle deletable global variables.
+    if (!lookup.IsDontDelete()) {
+      BAILOUT("Deletable global variable");
+    }
+  }
+}
+
+
+void FastCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
+  BAILOUT("Literal");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
+  BAILOUT("RegExpLiteral");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
+  BAILOUT("ObjectLiteral");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
+  BAILOUT("ArrayLiteral");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCatchExtensionObject(
+    CatchExtensionObject* expr) {
+  BAILOUT("CatchExtensionObject");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
+  // Simple assignments to (named) this properties are supported.
+  if (expr->op() != Token::ASSIGN) BAILOUT("Non-simple assignment");
+
+  Property* prop = expr->target()->AsProperty();
+  if (prop == NULL) BAILOUT("Non-property assignment");
+  VariableProxy* proxy = prop->obj()->AsVariableProxy();
+  if (proxy == NULL || !proxy->var()->is_this()) {
+    BAILOUT("Non-this-property assignment");
+  }
+  if (!prop->key()->IsPropertyName()) {
+    BAILOUT("Non-named-property assignment");
+  }
+
+  // We will only specialize for fields on the object itself.
+  // Expression::IsPropertyName implies that the name is a literal
+  // symbol but we do not assume that.
+  Literal* key = prop->key()->AsLiteral();
+  if (key != NULL && key->handle()->IsString()) {
+    Handle<Object> receiver = info()->receiver();
+    Handle<String> name = Handle<String>::cast(key->handle());
+    LookupResult lookup;
+    receiver->Lookup(*name, &lookup);
+    if (!lookup.IsProperty()) {
+      BAILOUT("Assigned property not found at compile time");
+    }
+    if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
+    if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment");
+  } else {
+    UNREACHABLE();
+    BAILOUT("Unexpected non-string-literal property key");
+  }
+
+  Visit(expr->value());
+}
+
+
+void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
+  BAILOUT("Throw");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
+  // We support named this property references.
+  VariableProxy* proxy = expr->obj()->AsVariableProxy();
+  if (proxy == NULL || !proxy->var()->is_this()) {
+    BAILOUT("Non-this-property reference");
+  }
+  if (!expr->key()->IsPropertyName()) {
+    BAILOUT("Non-named-property reference");
+  }
+
+  // We will only specialize for fields on the object itself.
+  // Expression::IsPropertyName implies that the name is a literal
+  // symbol but we do not assume that.
+  Literal* key = expr->key()->AsLiteral();
+  if (key != NULL && key->handle()->IsString()) {
+    Handle<Object> receiver = info()->receiver();
+    Handle<String> name = Handle<String>::cast(key->handle());
+    LookupResult lookup;
+    receiver->Lookup(*name, &lookup);
+    if (!lookup.IsProperty()) {
+      BAILOUT("Referenced property not found at compile time");
+    }
+    if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
+    if (!lookup.type() == FIELD) BAILOUT("Non-field property reference");
+  } else {
+    UNREACHABLE();
+    BAILOUT("Unexpected non-string-literal property key");
+  }
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCall(Call* expr) {
+  BAILOUT("Call");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
+  BAILOUT("CallNew");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
+  BAILOUT("CallRuntime");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
+  BAILOUT("UnaryOperation");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
+  BAILOUT("CountOperation");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
+  // We support bitwise OR.
+  switch (expr->op()) {
+    case Token::COMMA:
+      BAILOUT("BinaryOperation COMMA");
+    case Token::OR:
+      BAILOUT("BinaryOperation OR");
+    case Token::AND:
+      BAILOUT("BinaryOperation AND");
+
+    case Token::BIT_OR:
+      // We support expressions nested on the left because they only require
+      // a pair of registers to keep all intermediate values in registers
+      // (i.e., the expression stack has height no more than two).
+      if (!expr->right()->IsLeaf()) BAILOUT("expression nested on right");
+
+      // We do not allow subexpressions with side effects because we
+      // (currently) bail out to the beginning of the full function.  The
+      // only expressions with side effects that we would otherwise handle
+      // are assignments.
+      if (expr->left()->AsAssignment() != NULL ||
+          expr->right()->AsAssignment() != NULL) {
+        BAILOUT("subexpression of binary operation has side effects");
+      }
+
+      Visit(expr->left());
+      CHECK_BAILOUT;
+      Visit(expr->right());
+      break;
+
+    case Token::BIT_XOR:
+      BAILOUT("BinaryOperation BIT_XOR");
+    case Token::BIT_AND:
+      BAILOUT("BinaryOperation BIT_AND");
+    case Token::SHL:
+      BAILOUT("BinaryOperation SHL");
+    case Token::SAR:
+      BAILOUT("BinaryOperation SAR");
+    case Token::SHR:
+      BAILOUT("BinaryOperation SHR");
+    case Token::ADD:
+      BAILOUT("BinaryOperation ADD");
+    case Token::SUB:
+      BAILOUT("BinaryOperation SUB");
+    case Token::MUL:
+      BAILOUT("BinaryOperation MUL");
+    case Token::DIV:
+      BAILOUT("BinaryOperation DIV");
+    case Token::MOD:
+      BAILOUT("BinaryOperation MOD");
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
+  BAILOUT("CompareOperation");
+}
+
+
+void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
+  BAILOUT("ThisFunction");
+}
+
+#undef BAILOUT
+#undef CHECK_BAILOUT
+
+
 #define __ ACCESS_MASM(masm())
 
-void FastCodeGenerator::EmitLoadReceiver(Register reg) {
+Handle<Code> FastCodeGenerator::MakeCode(CompilationInfo* info) {
+  // Label the AST before calling MakeCodePrologue, so AST node numbers are
+  // printed with the AST.
+  AstLabeler labeler;
+  labeler.Label(info);
+
+  LivenessAnalyzer analyzer;
+  analyzer.Analyze(info->function());
+
+  CodeGenerator::MakeCodePrologue(info);
+
+  const int kInitialBufferSize = 4 * KB;
+  MacroAssembler masm(NULL, kInitialBufferSize);
+
+  // Generate the fast-path code.
+  FastCodeGenerator fast_cgen(&masm);
+  fast_cgen.Generate(info);
+  if (fast_cgen.HasStackOverflow()) {
+    ASSERT(!Top::has_pending_exception());
+    return Handle<Code>::null();
+  }
+
+  // Generate the full code for the function in bailout mode, using the same
+  // macro assembler.
+  CodeGenerator cgen(&masm);
+  CodeGeneratorScope scope(&cgen);
+  info->set_mode(CompilationInfo::SECONDARY);
+  cgen.Generate(info);
+  if (cgen.HasStackOverflow()) {
+    ASSERT(!Top::has_pending_exception());
+    return Handle<Code>::null();
+  }
+
+  Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
+  return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
+}
+
+
+Register FastCodeGenerator::accumulator0() { return eax; }
+Register FastCodeGenerator::accumulator1() { return edx; }
+Register FastCodeGenerator::scratch0() { return ecx; }
+Register FastCodeGenerator::scratch1() { return edi; }
+Register FastCodeGenerator::receiver_reg() { return ebx; }
+Register FastCodeGenerator::context_reg() { return esi; }
+
+
+void FastCodeGenerator::EmitLoadReceiver() {
   // Offset 2 is due to return address and saved frame pointer.
   int index = 2 + function()->scope()->num_parameters();
-  __ mov(reg, Operand(ebp, index * kPointerSize));
-}
-
-
-void FastCodeGenerator::EmitReceiverMapCheck() {
-  Comment cmnt(masm(), ";; MapCheck(this)");
-  if (FLAG_print_ir) {
-    PrintF("MapCheck(this)\n");
-  }
-
-  ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
-  Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
-  Handle<Map> map(object->map());
-
-  EmitLoadReceiver(edx);
-  __ CheckMap(edx, map, bailout(), false);
-}
-
-
-void FastCodeGenerator::EmitGlobalMapCheck() {
-  Comment cmnt(masm(), ";; GlobalMapCheck");
-  if (FLAG_print_ir) {
-    PrintF(";; GlobalMapCheck()");
-  }
-
-  ASSERT(info()->has_global_object());
-  Handle<Map> map(info()->global_object()->map());
-
-  __ mov(ebx, CodeGenerator::GlobalObject());
-  __ CheckMap(ebx, map, bailout(), true);
+  __ mov(receiver_reg(), Operand(ebp, index * kPointerSize));
 }
 
 
 void FastCodeGenerator::EmitGlobalVariableLoad(Handle<Object> cell) {
+  ASSERT(!destination().is(no_reg));
   ASSERT(cell->IsJSGlobalPropertyCell());
-  __ mov(eax, Immediate(cell));
-  __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset));
+
+  __ mov(destination(), Immediate(cell));
+  __ mov(destination(),
+         FieldOperand(destination(), JSGlobalPropertyCell::kValueOffset));
   if (FLAG_debug_code) {
-    __ cmp(eax, Factory::the_hole_value());
+    __ cmp(destination(), Factory::the_hole_value());
     __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
 }
 
 
@@ -92,19 +510,111 @@
   int index = lookup.GetFieldIndex() - map->inobject_properties();
   int offset = index * kPointerSize;
 
-  // Negative offsets are inobject properties.
+  // We will emit the write barrier unless the stored value is statically
+  // known to be a smi.
+  bool needs_write_barrier = !is_smi(accumulator0());
+
+  // Perform the store.  Negative offsets are inobject properties.
   if (offset < 0) {
     offset += map->instance_size();
-    __ mov(ecx, edx);  // Copy receiver for write barrier.
+    __ mov(FieldOperand(receiver_reg(), offset), accumulator0());
+    if (needs_write_barrier) {
+      // Preserve receiver from write barrier.
+      __ mov(scratch0(), receiver_reg());
+    }
   } else {
     offset += FixedArray::kHeaderSize;
-    __ mov(ecx, FieldOperand(edx, JSObject::kPropertiesOffset));
+    __ mov(scratch0(),
+           FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ mov(FieldOperand(scratch0(), offset), accumulator0());
   }
-  // Perform the store.
-  __ mov(FieldOperand(ecx, offset), eax);
-  // Preserve value from write barrier in case it's needed.
-  __ mov(ebx, eax);
-  __ RecordWrite(ecx, offset, ebx, edi);
+
+  if (needs_write_barrier) {
+    if (destination().is(no_reg)) {
+      // After RecordWrite accumulator0 is only accidently a smi, but it is
+      // already marked as not known to be one.
+      __ RecordWrite(scratch0(), offset, accumulator0(), scratch1());
+    } else {
+      // Copy the value to the other accumulator to preserve a copy from the
+      // write barrier. One of the accumulators is available as a scratch
+      // register.  Neither is a smi.
+      __ mov(accumulator1(), accumulator0());
+      clear_as_smi(accumulator1());
+      Register value_scratch = other_accumulator(destination());
+      __ RecordWrite(scratch0(), offset, value_scratch, scratch1());
+    }
+  } else if (destination().is(accumulator1())) {
+    __ mov(accumulator1(), accumulator0());
+    // Is a smi because we do not need the write barrier.
+    set_as_smi(accumulator1());
+  }
+}
+
+
+void FastCodeGenerator::EmitThisPropertyLoad(Handle<String> name) {
+  ASSERT(!destination().is(no_reg));
+  LookupResult lookup;
+  info()->receiver()->Lookup(*name, &lookup);
+
+  ASSERT(lookup.holder() == *info()->receiver());
+  ASSERT(lookup.type() == FIELD);
+  Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map());
+  int index = lookup.GetFieldIndex() - map->inobject_properties();
+  int offset = index * kPointerSize;
+
+  // Perform the load.  Negative offsets are inobject properties.
+  if (offset < 0) {
+    offset += map->instance_size();
+    __ mov(destination(), FieldOperand(receiver_reg(), offset));
+  } else {
+    offset += FixedArray::kHeaderSize;
+    __ mov(scratch0(),
+           FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ mov(destination(), FieldOperand(scratch0(), offset));
+  }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
+}
+
+
+void FastCodeGenerator::EmitBitOr() {
+  if (is_smi(accumulator0()) && is_smi(accumulator1())) {
+    // If both operands are known to be a smi then there is no need to check
+    // the operands or result.  There is no need to perform the operation in
+    // an effect context.
+    if (!destination().is(no_reg)) {
+      // Leave the result in the destination register.  Bitwise or is
+      // commutative.
+      __ or_(destination(), Operand(other_accumulator(destination())));
+    }
+  } else {
+    // Left is in accumulator1, right in accumulator0.
+    Label* bailout = NULL;
+    if (destination().is(accumulator0())) {
+      __ mov(scratch0(), accumulator0());
+      __ or_(destination(), Operand(accumulator1()));  // Or is commutative.
+      __ test(destination(), Immediate(kSmiTagMask));
+      bailout = info()->AddBailout(accumulator1(), scratch0());  // Left, right.
+    } else if (destination().is(accumulator1())) {
+      __ mov(scratch0(), accumulator1());
+      __ or_(destination(), Operand(accumulator0()));
+      __ test(destination(), Immediate(kSmiTagMask));
+      bailout = info()->AddBailout(scratch0(), accumulator0());
+    } else {
+      ASSERT(destination().is(no_reg));
+      __ mov(scratch0(), accumulator1());
+      __ or_(scratch0(), Operand(accumulator0()));
+      __ test(scratch0(), Immediate(kSmiTagMask));
+      bailout = info()->AddBailout(accumulator1(), accumulator0());
+    }
+    __ j(not_zero, bailout, not_taken);
+  }
+
+  // If we didn't bailout, the result (in fact, both inputs too) is known to
+  // be a smi.
+  set_as_smi(accumulator0());
+  set_as_smi(accumulator1());
 }
 
 
@@ -121,27 +631,323 @@
   // Note that we keep a live register reference to esi (context) at this
   // point.
 
-  // Receiver (this) is allocated to edx if there are this properties.
-  if (info()->has_this_properties()) EmitReceiverMapCheck();
+  Label* bailout_to_beginning = info()->AddBailout();
+  // Receiver (this) is allocated to a fixed register.
+  if (info()->has_this_properties()) {
+    Comment cmnt(masm(), ";; MapCheck(this)");
+    if (FLAG_print_ir) {
+      PrintF("#: MapCheck(this)\n");
+    }
+    ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
+    Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
+    Handle<Map> map(object->map());
+    EmitLoadReceiver();
+    __ CheckMap(receiver_reg(), map, bailout_to_beginning, false);
+  }
 
-  // If there is a global variable access check if the global object
-  // is the same as at lazy-compilation time.
-  if (info()->has_globals()) EmitGlobalMapCheck();
+  // If there is a global variable access check if the global object is the
+  // same as at lazy-compilation time.
+  if (info()->has_globals()) {
+    Comment cmnt(masm(), ";; MapCheck(GLOBAL)");
+    if (FLAG_print_ir) {
+      PrintF("#: MapCheck(GLOBAL)\n");
+    }
+    ASSERT(info()->has_global_object());
+    Handle<Map> map(info()->global_object()->map());
+    __ mov(scratch0(), CodeGenerator::GlobalObject());
+    __ CheckMap(scratch0(), map, bailout_to_beginning, true);
+  }
 
   VisitStatements(function()->body());
 
   Comment return_cmnt(masm(), ";; Return(<undefined>)");
+  if (FLAG_print_ir) {
+    PrintF("#: Return(<undefined>)\n");
+  }
   __ mov(eax, Factory::undefined_value());
-
-  Comment epilogue_cmnt(masm(), ";; Epilogue");
   __ mov(esp, ebp);
   __ pop(ebp);
   __ ret((scope()->num_parameters() + 1) * kPointerSize);
-
-  __ bind(&bailout_);
 }
 
 
+void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitBlock(Block* stmt) {
+  VisitStatements(stmt->statements());
+}
+
+
+void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
+  // Nothing to do.
+}
+
+
+void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
+    FunctionBoilerplateLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitConditional(Conditional* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitSlot(Slot* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
+  ASSERT(expr->var()->is_global() && !expr->var()->is_this());
+  // Check if we can compile a global variable load directly from the cell.
+  ASSERT(info()->has_global_object());
+  LookupResult lookup;
+  info()->global_object()->Lookup(*expr->name(), &lookup);
+  // We only support normal (non-accessor/interceptor) DontDelete properties
+  // for now.
+  ASSERT(lookup.IsProperty());
+  ASSERT_EQ(NORMAL, lookup.type());
+  ASSERT(lookup.IsDontDelete());
+  Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
+
+  // Global variable lookups do not have side effects, so we do not need to
+  // emit code if we are in an effect context.
+  if (!destination().is(no_reg)) {
+    Comment cmnt(masm(), ";; Global");
+    if (FLAG_print_ir) {
+      SmartPointer<char> name = expr->name()->ToCString();
+      PrintF("%d: t%d = Global(%s)  // last_use = %d\n", expr->num(),
+             expr->num(), *name, expr->var_def()->last_use()->num());
+    }
+    EmitGlobalVariableLoad(cell);
+  }
+}
+
+
+void FastCodeGenerator::VisitLiteral(Literal* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitAssignment(Assignment* expr) {
+  // Known to be a simple this property assignment.  Effectively a unary
+  // operation.
+  { Register my_destination = destination();
+    set_destination(accumulator0());
+    Visit(expr->value());
+    set_destination(my_destination);
+  }
+
+  Property* prop = expr->target()->AsProperty();
+  ASSERT_NOT_NULL(prop);
+  ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
+  ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
+  ASSERT(prop->key()->IsPropertyName());
+  Handle<String> name =
+      Handle<String>::cast(prop->key()->AsLiteral()->handle());
+
+  Comment cmnt(masm(), ";; Store to this");
+  if (FLAG_print_ir) {
+    SmartPointer<char> name_string = name->ToCString();
+    PrintF("%d: ", expr->num());
+    if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+    PrintF("Store(this, \"%s\", t%d)  // last_use(this) = %d\n", *name_string,
+           expr->value()->num(),
+           expr->var_def()->last_use()->num());
+  }
+
+  EmitThisPropertyStore(name);
+}
+
+
+void FastCodeGenerator::VisitThrow(Throw* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitProperty(Property* expr) {
+  ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
+  ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
+  ASSERT(expr->key()->IsPropertyName());
+  if (!destination().is(no_reg)) {
+    Handle<String> name =
+        Handle<String>::cast(expr->key()->AsLiteral()->handle());
+
+    Comment cmnt(masm(), ";; Load from this");
+    if (FLAG_print_ir) {
+      SmartPointer<char> name_string = name->ToCString();
+      PrintF("%d: t%d = Load(this, \"%s\")  // last_use(this) = %d\n",
+             expr->num(), expr->num(), *name_string,
+             expr->var_def()->last_use()->num());
+    }
+    EmitThisPropertyLoad(name);
+  }
+}
+
+
+void FastCodeGenerator::VisitCall(Call* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitCallNew(CallNew* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
+  // We support limited binary operations: bitwise OR only allowed to be
+  // nested on the left.
+  ASSERT(expr->op() == Token::BIT_OR);
+  ASSERT(expr->right()->IsLeaf());
+
+  { Register my_destination = destination();
+    set_destination(accumulator1());
+    Visit(expr->left());
+    set_destination(accumulator0());
+    Visit(expr->right());
+    set_destination(my_destination);
+  }
+
+  Comment cmnt(masm(), ";; BIT_OR");
+  if (FLAG_print_ir) {
+    PrintF("%d: ", expr->num());
+    if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+    PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
+  }
+  EmitBitOr();
+}
+
+
+void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
+  UNREACHABLE();
+}
+
+
+void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
+  UNREACHABLE();
+}
+
 #undef __
 
 
diff --git a/src/ia32/fast-codegen-ia32.h b/src/ia32/fast-codegen-ia32.h
new file mode 100644
index 0000000..e0851af
--- /dev/null
+++ b/src/ia32/fast-codegen-ia32.h
@@ -0,0 +1,155 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_FAST_CODEGEN_IA32_H_
+#define V8_FAST_CODEGEN_IA32_H_
+
+#include "v8.h"
+
+#include "ast.h"
+#include "compiler.h"
+#include "list.h"
+
+namespace v8 {
+namespace internal {
+
+class FastCodeGenSyntaxChecker: public AstVisitor {
+ public:
+  explicit FastCodeGenSyntaxChecker()
+      : info_(NULL), has_supported_syntax_(true) {
+  }
+
+  void Check(CompilationInfo* info);
+
+  CompilationInfo* info() { return info_; }
+  bool has_supported_syntax() { return has_supported_syntax_; }
+
+ private:
+  void VisitDeclarations(ZoneList<Declaration*>* decls);
+  void VisitStatements(ZoneList<Statement*>* stmts);
+
+  // AST node visit functions.
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+  AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+  CompilationInfo* info_;
+  bool has_supported_syntax_;
+
+  DISALLOW_COPY_AND_ASSIGN(FastCodeGenSyntaxChecker);
+};
+
+
+class FastCodeGenerator: public AstVisitor {
+ public:
+  explicit FastCodeGenerator(MacroAssembler* masm)
+      : masm_(masm), info_(NULL), destination_(no_reg), smi_bits_(0) {
+  }
+
+  static Handle<Code> MakeCode(CompilationInfo* info);
+
+  void Generate(CompilationInfo* compilation_info);
+
+ private:
+  MacroAssembler* masm() { return masm_; }
+  CompilationInfo* info() { return info_; }
+
+  Register destination() { return destination_; }
+  void set_destination(Register reg) { destination_ = reg; }
+
+  FunctionLiteral* function() { return info_->function(); }
+  Scope* scope() { return info_->scope(); }
+
+  // Platform-specific fixed registers, all guaranteed distinct.
+  Register accumulator0();
+  Register accumulator1();
+  Register scratch0();
+  Register scratch1();
+  Register receiver_reg();
+  Register context_reg();
+
+  Register other_accumulator(Register reg) {
+    ASSERT(reg.is(accumulator0()) || reg.is(accumulator1()));
+    return (reg.is(accumulator0())) ? accumulator1() : accumulator0();
+  }
+
+  // Flags are true if the respective register is statically known to hold a
+  // smi.  We do not track every register, only the accumulator registers.
+  bool is_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    return (smi_bits_ & reg.bit()) != 0;
+  }
+  void set_as_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    smi_bits_ = smi_bits_ | reg.bit();
+  }
+  void clear_as_smi(Register reg) {
+    ASSERT(!reg.is(no_reg));
+    smi_bits_ = smi_bits_ & ~reg.bit();
+  }
+
+  // AST node visit functions.
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+  AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+  // Emit code to load the receiver from the stack into receiver_reg.
+  void EmitLoadReceiver();
+
+  // Emit code to load a global variable directly from a global property
+  // cell into the destination register.
+  void EmitGlobalVariableLoad(Handle<Object> cell);
+
+  // Emit a store to an own property of this.  The stored value is expected
+  // in accumulator0 and the receiver in receiver_reg.  The receiver
+  // register is preserved and the result (the stored value) is left in the
+  // destination register.
+  void EmitThisPropertyStore(Handle<String> name);
+
+  // Emit a load from an own property of this.  The receiver is expected in
+  // receiver_reg.  The receiver register is preserved and the result is
+  // left in the destination register.
+  void EmitThisPropertyLoad(Handle<String> name);
+
+  // Emit a bitwise or operation.  The left operand is in accumulator1 and
+  // the right is in accumulator0.  The result should be left in the
+  // destination register.
+  void EmitBitOr();
+
+  MacroAssembler* masm_;
+  CompilationInfo* info_;
+
+  Register destination_;
+  uint32_t smi_bits_;
+
+  DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator);
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_FAST_CODEGEN_IA32_H_
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 3163b19..2394bed 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -808,7 +808,7 @@
     Comment cmnt(masm_, "Global variable");
     // Use inline caching. Variable name is passed in ecx and the global
     // object on the stack.
-    __ push(CodeGenerator::GlobalObject());
+    __ mov(eax, CodeGenerator::GlobalObject());
     __ mov(ecx, var->name());
     Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
     __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
@@ -817,7 +817,7 @@
     // Remember that the assembler may choose to do peephole optimization
     // (eg, push/pop elimination).
     __ nop();
-    DropAndApply(1, context, eax);
+    Apply(context, eax);
 
   } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
     Comment cmnt(masm_, "Lookup slot");
@@ -845,7 +845,7 @@
 
     // Load the object.
     MemOperand object_loc = EmitSlotSearch(object_slot, eax);
-    __ push(object_loc);
+    __ mov(edx, object_loc);
 
     // Assert that the key is a smi.
     Literal* key_literal = property->key()->AsLiteral();
@@ -853,7 +853,7 @@
     ASSERT(key_literal->handle()->IsSmi());
 
     // Load the key.
-    __ push(Immediate(key_literal->handle()));
+    __ mov(eax, Immediate(key_literal->handle()));
 
     // Do a keyed property load.
     Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
@@ -862,7 +862,7 @@
     // call. It is treated specially by the LoadIC code.
     __ nop();
     // Drop key and object left on the stack by IC.
-    DropAndApply(2, context, eax);
+    Apply(context, eax);
   }
 }
 
@@ -1013,6 +1013,99 @@
 }
 
 
+void FullCodeGenerator::VisitAssignment(Assignment* expr) {
+  Comment cmnt(masm_, "[ Assignment");
+  ASSERT(expr->op() != Token::INIT_CONST);
+  // Left-hand side can only be a property, a global or a (parameter or local)
+  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
+  LhsKind assign_type = VARIABLE;
+  Property* prop = expr->target()->AsProperty();
+  if (prop != NULL) {
+    assign_type =
+        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
+  }
+
+  // Evaluate LHS expression.
+  switch (assign_type) {
+    case VARIABLE:
+      // Nothing to do here.
+      break;
+    case NAMED_PROPERTY:
+      if (expr->is_compound()) {
+        // We need the receiver both on the stack and in the accumulator.
+        VisitForValue(prop->obj(), kAccumulator);
+        __ push(result_register());
+      } else {
+        VisitForValue(prop->obj(), kStack);
+      }
+      break;
+    case KEYED_PROPERTY:
+      if (expr->is_compound()) {
+        VisitForValue(prop->obj(), kStack);
+        VisitForValue(prop->key(), kAccumulator);
+        __ mov(edx, Operand(esp, 0));
+        __ push(eax);
+      } else {
+        VisitForValue(prop->obj(), kStack);
+        VisitForValue(prop->key(), kStack);
+      }
+      break;
+  }
+
+  // If we have a compound assignment: Get value of LHS expression and
+  // store in on top of the stack.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kStack;
+    switch (assign_type) {
+      case VARIABLE:
+        EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
+                         Expression::kValue);
+        break;
+      case NAMED_PROPERTY:
+        EmitNamedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+      case KEYED_PROPERTY:
+        EmitKeyedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+    }
+    location_ = saved_location;
+  }
+
+  // Evaluate RHS expression.
+  Expression* rhs = expr->value();
+  VisitForValue(rhs, kAccumulator);
+
+  // If we have a compound assignment: Apply operator.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kAccumulator;
+    EmitBinaryOp(expr->binary_op(), Expression::kValue);
+    location_ = saved_location;
+  }
+
+  // Record source position before possible IC call.
+  SetSourcePosition(expr->position());
+
+  // Store the value.
+  switch (assign_type) {
+    case VARIABLE:
+      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
+                             context_);
+      break;
+    case NAMED_PROPERTY:
+      EmitNamedPropertyAssignment(expr);
+      break;
+    case KEYED_PROPERTY:
+      EmitKeyedPropertyAssignment(expr);
+      break;
+  }
+}
+
+
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
@@ -1183,18 +1276,16 @@
   Comment cmnt(masm_, "[ Property");
   Expression* key = expr->key();
 
-  // Evaluate the receiver.
-  VisitForValue(expr->obj(), kStack);
-
   if (key->IsPropertyName()) {
+    VisitForValue(expr->obj(), kAccumulator);
     EmitNamedPropertyLoad(expr);
-    // Drop receiver left on the stack by IC.
-    DropAndApply(1, context_, eax);
+    Apply(context_, eax);
   } else {
-    VisitForValue(expr->key(), kStack);
+    VisitForValue(expr->obj(), kStack);
+    VisitForValue(expr->key(), kAccumulator);
+    __ pop(edx);
     EmitKeyedPropertyLoad(expr);
-    // Drop key and receiver left on the stack by IC.
-    DropAndApply(2, context_, eax);
+    Apply(context_, eax);
   }
 }
 
@@ -1265,25 +1356,31 @@
       // Call to a keyed property, use keyed load IC followed by function
       // call.
       VisitForValue(prop->obj(), kStack);
-      VisitForValue(prop->key(), kStack);
+      VisitForValue(prop->key(), kAccumulator);
       // Record source code position for IC call.
       SetSourcePosition(prop->position());
+      if (prop->is_synthetic()) {
+        __ pop(edx);  // We do not need to keep the receiver.
+      } else {
+        __ mov(edx, Operand(esp, 0));  // Keep receiver, to call function on.
+      }
+
       Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
       __ call(ic, RelocInfo::CODE_TARGET);
       // By emitting a nop we make sure that we do not have a "test eax,..."
       // instruction after the call it is treated specially by the LoadIC code.
       __ nop();
-      // Drop key left on the stack by IC.
-      __ Drop(1);
-      // Pop receiver.
-      __ pop(ebx);
-      // Push result (function).
-      __ push(eax);
-      // Push receiver object on stack.
       if (prop->is_synthetic()) {
+        // Push result (function).
+        __ push(eax);
+        // Push Global receiver.
         __ mov(ecx, CodeGenerator::GlobalObject());
         __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
       } else {
+        // Pop receiver.
+        __ pop(ebx);
+        // Push result (function).
+        __ push(eax);
         __ push(ebx);
       }
       EmitCallWithStub(expr);
@@ -1455,13 +1552,13 @@
           !proxy->var()->is_this() &&
           proxy->var()->is_global()) {
         Comment cmnt(masm_, "Global variable");
-        __ push(CodeGenerator::GlobalObject());
+        __ mov(eax, CodeGenerator::GlobalObject());
         __ mov(ecx, Immediate(proxy->name()));
         Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
         // Use a regular load, not a contextual load, to avoid a reference
         // error.
         __ call(ic, RelocInfo::CODE_TARGET);
-        __ mov(Operand(esp, 0), eax);
+        __ push(eax);
       } else if (proxy != NULL &&
                  proxy->var()->slot() != NULL &&
                  proxy->var()->slot()->type() == Slot::LOOKUP) {
@@ -1565,11 +1662,16 @@
     if (expr->is_postfix() && context_ != Expression::kEffect) {
       __ push(Immediate(Smi::FromInt(0)));
     }
-    VisitForValue(prop->obj(), kStack);
     if (assign_type == NAMED_PROPERTY) {
+      // Put the object both on the stack and in the accumulator.
+      VisitForValue(prop->obj(), kAccumulator);
+      __ push(eax);
       EmitNamedPropertyLoad(prop);
     } else {
-      VisitForValue(prop->key(), kStack);
+      VisitForValue(prop->obj(), kStack);
+      VisitForValue(prop->key(), kAccumulator);
+      __ mov(edx, Operand(esp, 0));
+      __ push(eax);
       EmitKeyedPropertyLoad(prop);
     }
   }
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index d1ae28b..0d79c54 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -50,28 +50,29 @@
 // or if name is not a symbol, and will jump to the miss_label in that case.
 static void GenerateDictionaryLoad(MacroAssembler* masm,
                                    Label* miss_label,
+                                   Register receiver,
+                                   Register name,
                                    Register r0,
                                    Register r1,
                                    Register r2,
-                                   Register name,
                                    DictionaryCheck check_dictionary) {
   // Register use:
   //
+  // name - holds the name of the property and is unchanged.
+  // receiver - holds the receiver and is unchanged.
+  // Scratch registers:
   // r0   - used to hold the property dictionary.
   //
-  // r1   - initially the receiver
-  //      - used for the index into the property dictionary
+  // r1   - used for the index into the property dictionary
   //      - holds the result on exit.
   //
   // r2   - used to hold the capacity of the property dictionary.
-  //
-  // name - holds the name of the property and is unchanged.
 
   Label done;
 
   // Check for the absence of an interceptor.
   // Load the map into r0.
-  __ mov(r0, FieldOperand(r1, JSObject::kMapOffset));
+  __ mov(r0, FieldOperand(receiver, JSObject::kMapOffset));
   // Test the has_named_interceptor bit in the map.
   __ test(FieldOperand(r0, Map::kInstanceAttributesOffset),
           Immediate(1 << (Map::kHasNamedInterceptor + (3 * 8))));
@@ -91,7 +92,7 @@
   __ j(equal, miss_label, not_taken);
 
   // Load properties array.
-  __ mov(r0, FieldOperand(r1, JSObject::kPropertiesOffset));
+  __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
 
   // Check that the properties array is a dictionary.
   if (check_dictionary == CHECK_DICTIONARY) {
@@ -159,14 +160,12 @@
 
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-
   StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss);
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
@@ -175,15 +174,13 @@
 
 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-
-  StubCompiler::GenerateLoadStringLength(masm, eax, edx, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss);
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
 }
@@ -191,14 +188,12 @@
 
 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-
   StubCompiler::GenerateLoadFunctionPrototype(masm, eax, edx, ebx, &miss);
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
@@ -207,26 +202,22 @@
 
 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label slow, check_string, index_int, index_string;
   Label check_pixel_array, probe_dictionary;
 
-  // Load name and receiver.
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
+  __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &slow, not_taken);
 
   // Get the map of the receiver.
-  __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset));
+  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
 
   // Check bit field.
-  __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
+  __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
   __ test(ebx, Immediate(kSlowCaseBitFieldMask));
   __ j(not_zero, &slow, not_taken);
   // Check that the object is some kind of JS object EXCEPT JS Value type.
@@ -234,56 +225,58 @@
   // we enter the runtime system to make sure that indexing
   // into string objects work as intended.
   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
-  __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
-  __ cmp(edx, JS_OBJECT_TYPE);
-  __ j(less, &slow, not_taken);
+  __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
+  __ j(below, &slow, not_taken);
   // Check that the key is a smi.
   __ test(eax, Immediate(kSmiTagMask));
   __ j(not_zero, &check_string, not_taken);
-  __ sar(eax, kSmiTagSize);
+  __ mov(ebx, eax);
+  __ SmiUntag(ebx);
   // Get the elements array of the object.
   __ bind(&index_int);
-  __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
+  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
   // Check that the object is in fast mode (not dictionary).
-  __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
-         Immediate(Factory::fixed_array_map()));
-  __ j(not_equal, &check_pixel_array);
+  __ CheckMap(ecx, Factory::fixed_array_map(), &check_pixel_array, true);
   // Check that the key (index) is within bounds.
-  __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
+  __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
   __ j(above_equal, &slow);
   // Fast case: Do the load.
-  __ mov(eax,
-         Operand(ecx, eax, times_4, FixedArray::kHeaderSize - kHeapObjectTag));
-  __ cmp(Operand(eax), Immediate(Factory::the_hole_value()));
+  __ mov(ecx, FieldOperand(ecx, ebx, times_4, FixedArray::kHeaderSize));
+  __ cmp(Operand(ecx), Immediate(Factory::the_hole_value()));
   // In case the loaded value is the_hole we have to consult GetProperty
   // to ensure the prototype chain is searched.
   __ j(equal, &slow);
+  __ mov(eax, ecx);
   __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
   __ ret(0);
 
-  // Check whether the elements is a pixel array.
-  // eax: untagged index
-  // ecx: elements array
   __ bind(&check_pixel_array);
-  __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
-         Immediate(Factory::pixel_array_map()));
-  __ j(not_equal, &slow);
-  __ cmp(eax, FieldOperand(ecx, PixelArray::kLengthOffset));
+  // Check whether the elements is a pixel array.
+  // edx: receiver
+  // ebx: untagged index
+  // eax: key
+  // ecx: elements
+  __ CheckMap(ecx, Factory::pixel_array_map(), &slow, true);
+  __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset));
   __ j(above_equal, &slow);
-  __ mov(ecx, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
-  __ movzx_b(eax, Operand(ecx, eax, times_1, 0));
-  __ shl(eax, kSmiTagSize);
+  __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
+  __ movzx_b(eax, Operand(eax, ebx, times_1, 0));
+  __ SmiTag(eax);
   __ ret(0);
 
-  // Slow case: Load name and receiver from stack and jump to runtime.
   __ bind(&slow);
+  // Slow case: jump to runtime.
+  // edx: receiver
+  // eax: key
   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
-  Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
+  GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_string);
   // The key is not a smi.
   // Is it a string?
-  __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
+  // edx: receiver
+  // eax: key
+  __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
   __ j(above_equal, &slow);
   // Is the string an array index, with cached numeric value?
   __ mov(ebx, FieldOperand(eax, String::kHashFieldOffset));
@@ -291,55 +284,58 @@
   __ j(not_zero, &index_string, not_taken);
 
   // Is the string a symbol?
-  __ movzx_b(ebx, FieldOperand(edx, Map::kInstanceTypeOffset));
+  __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   ASSERT(kSymbolTag != 0);
   __ test(ebx, Immediate(kIsSymbolMask));
   __ j(zero, &slow, not_taken);
 
   // If the receiver is a fast-case object, check the keyed lookup
-  // cache. Otherwise probe the dictionary leaving result in ecx.
-  __ mov(ebx, FieldOperand(ecx, JSObject::kPropertiesOffset));
+  // cache. Otherwise probe the dictionary.
+  __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
   __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
          Immediate(Factory::hash_table_map()));
   __ j(equal, &probe_dictionary);
 
   // Load the map of the receiver, compute the keyed lookup cache hash
   // based on 32 bits of the map pointer and the string hash.
-  __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
-  __ mov(edx, ebx);
-  __ shr(edx, KeyedLookupCache::kMapHashShift);
-  __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
-  __ shr(eax, String::kHashShift);
-  __ xor_(edx, Operand(eax));
-  __ and_(edx, KeyedLookupCache::kCapacityMask);
+  __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
+  __ mov(ecx, ebx);
+  __ shr(ecx, KeyedLookupCache::kMapHashShift);
+  __ mov(edi, FieldOperand(eax, String::kHashFieldOffset));
+  __ shr(edi, String::kHashShift);
+  __ xor_(ecx, Operand(edi));
+  __ and_(ecx, KeyedLookupCache::kCapacityMask);
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
   ExternalReference cache_keys
       = ExternalReference::keyed_lookup_cache_keys();
-  __ mov(edi, edx);
+  __ mov(edi, ecx);
   __ shl(edi, kPointerSizeLog2 + 1);
   __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
   __ j(not_equal, &slow);
   __ add(Operand(edi), Immediate(kPointerSize));
-  __ mov(edi, Operand::StaticArray(edi, times_1, cache_keys));
-  __ cmp(edi, Operand(esp, kPointerSize));
+  __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys));
   __ j(not_equal, &slow);
 
   // Get field offset and check that it is an in-object property.
+  // edx     : receiver
+  // ebx     : receiver's map
+  // eax     : key
+  // ecx     : lookup cache index
   ExternalReference cache_field_offsets
       = ExternalReference::keyed_lookup_cache_field_offsets();
-  __ mov(eax,
-         Operand::StaticArray(edx, times_pointer_size, cache_field_offsets));
-  __ movzx_b(edx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
-  __ cmp(eax, Operand(edx));
+  __ mov(edi,
+         Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
+  __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
+  __ cmp(edi, Operand(ecx));
   __ j(above_equal, &slow);
 
   // Load in-object property.
-  __ sub(eax, Operand(edx));
-  __ movzx_b(edx, FieldOperand(ebx, Map::kInstanceSizeOffset));
-  __ add(eax, Operand(edx));
-  __ mov(eax, FieldOperand(ecx, eax, times_pointer_size, 0));
+  __ sub(edi, Operand(ecx));
+  __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
+  __ add(ecx, Operand(edi));
+  __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
   __ ret(0);
 
   // Do a quick inline probe of the receiver's dictionary, if it
@@ -347,10 +343,11 @@
   __ bind(&probe_dictionary);
   GenerateDictionaryLoad(masm,
                          &slow,
-                         ebx,
-                         ecx,
                          edx,
                          eax,
+                         ebx,
+                         ecx,
+                         edi,
                          DICTIONARY_CHECK_DONE);
   __ mov(eax, Operand(ecx));
   __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
@@ -363,51 +360,47 @@
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));
   __ bind(&index_string);
-  __ mov(eax, Operand(ebx));
-  __ and_(eax, String::kArrayIndexHashMask);
-  __ shr(eax, String::kHashShift);
+  __ and_(ebx, String::kArrayIndexHashMask);
+  __ shr(ebx, String::kHashShift);
   __ jmp(&index_int);
 }
 
 
 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : key
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss, index_ok;
 
   // Pop return address.
   // Performing the load early is better in the common case.
-  __ pop(eax);
+  __ pop(ebx);
 
-  __ mov(ebx, Operand(esp, 1 * kPointerSize));
-  __ test(ebx, Immediate(kSmiTagMask));
+  __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &miss);
-  __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
+  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   __ test(ecx, Immediate(kIsNotStringMask));
   __ j(not_zero, &miss);
 
   // Check if key is a smi or a heap number.
-  __ mov(edx, Operand(esp, 0));
-  __ test(edx, Immediate(kSmiTagMask));
+  __ test(eax, Immediate(kSmiTagMask));
   __ j(zero, &index_ok);
-  __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
+  __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
   __ cmp(ecx, Factory::heap_number_map());
   __ j(not_equal, &miss);
 
   __ bind(&index_ok);
-  // Duplicate receiver and key since they are expected on the stack after
-  // the KeyedLoadIC call.
-  __ push(ebx);  // receiver
-  __ push(edx);  // key
-  __ push(eax);  // return address
+  // Push receiver and key on the stack, and make a tail call.
+  __ push(edx);  // receiver
+  __ push(eax);  // key
+  __ push(ebx);  // return address
   __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_FUNCTION);
 
   __ bind(&miss);
-  __ push(eax);
+  __ push(ebx);
   GenerateMiss(masm);
 }
 
@@ -415,18 +408,14 @@
 void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
                                         ExternalArrayType array_type) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : key
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label slow, failed_allocation;
 
-  // Load name and receiver.
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
+  __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &slow, not_taken);
 
   // Check that the key is a smi.
@@ -434,59 +423,56 @@
   __ j(not_zero, &slow, not_taken);
 
   // Get the map of the receiver.
-  __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset));
+  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   // Check that the receiver does not require access checks.  We need
   // to check this explicitly since this generic stub does not perform
   // map checks.
-  __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
+  __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
   __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
   __ j(not_zero, &slow, not_taken);
 
-  // Get the instance type from the map of the receiver.
-  __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
-  // Check that the object is a JS object.
-  __ cmp(edx, JS_OBJECT_TYPE);
+  __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
   __ j(not_equal, &slow, not_taken);
 
   // Check that the elements array is the appropriate type of
   // ExternalArray.
-  // eax: index (as a smi)
-  // ecx: JSObject
-  __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
+  __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
   Handle<Map> map(Heap::MapForExternalArrayType(array_type));
-  __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
+  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
          Immediate(map));
   __ j(not_equal, &slow, not_taken);
 
+  // eax: key, known to be a smi.
+  // edx: receiver, known to be a JSObject.
+  // ebx: elements object, known to be an external array.
   // Check that the index is in range.
-  __ sar(eax, kSmiTagSize);  // Untag the index.
-  __ cmp(eax, FieldOperand(ecx, ExternalArray::kLengthOffset));
+  __ mov(ecx, eax);
+  __ SmiUntag(ecx);  // Untag the index.
+  __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
   // Unsigned comparison catches both negative and too-large values.
   __ j(above_equal, &slow);
 
-  // eax: untagged index
-  // ecx: elements array
-  __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset));
-  // ecx: base pointer of external storage
+  __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
+  // ebx: base pointer of external storage
   switch (array_type) {
     case kExternalByteArray:
-      __ movsx_b(eax, Operand(ecx, eax, times_1, 0));
+      __ movsx_b(ecx, Operand(ebx, ecx, times_1, 0));
       break;
     case kExternalUnsignedByteArray:
-      __ movzx_b(eax, Operand(ecx, eax, times_1, 0));
+      __ movzx_b(ecx, Operand(ebx, ecx, times_1, 0));
       break;
     case kExternalShortArray:
-      __ movsx_w(eax, Operand(ecx, eax, times_2, 0));
+      __ movsx_w(ecx, Operand(ebx, ecx, times_2, 0));
       break;
     case kExternalUnsignedShortArray:
-      __ movzx_w(eax, Operand(ecx, eax, times_2, 0));
+      __ movzx_w(ecx, Operand(ebx, ecx, times_2, 0));
       break;
     case kExternalIntArray:
     case kExternalUnsignedIntArray:
-      __ mov(eax, Operand(ecx, eax, times_4, 0));
+      __ mov(ecx, Operand(ebx, ecx, times_4, 0));
       break;
     case kExternalFloatArray:
-      __ fld_s(Operand(ecx, eax, times_4, 0));
+      __ fld_s(Operand(ebx, ecx, times_4, 0));
       break;
     default:
       UNREACHABLE();
@@ -494,7 +480,7 @@
   }
 
   // For integer array types:
-  // eax: value
+  // ecx: value
   // For floating-point array type:
   // FP(0): value
 
@@ -505,21 +491,19 @@
     // it to a HeapNumber.
     Label box_int;
     if (array_type == kExternalIntArray) {
-      // See Smi::IsValid for why this works.
-      __ mov(ebx, eax);
-      __ add(Operand(ebx), Immediate(0x40000000));
-      __ cmp(ebx, 0x80000000);
-      __ j(above_equal, &box_int);
+      __ cmp(ecx, 0xC0000000);
+      __ j(sign, &box_int);
     } else {
       ASSERT_EQ(array_type, kExternalUnsignedIntArray);
       // The test is different for unsigned int values. Since we need
-      // the Smi-encoded result to be treated as unsigned, we can't
+      // the value to be in the range of a positive smi, we can't
       // handle either of the top two bits being set in the value.
-      __ test(eax, Immediate(0xC0000000));
+      __ test(ecx, Immediate(0xC0000000));
       __ j(not_zero, &box_int);
     }
 
-    __ shl(eax, kSmiTagSize);
+    __ mov(eax, ecx);
+    __ SmiTag(eax);
     __ ret(0);
 
     __ bind(&box_int);
@@ -527,34 +511,37 @@
     // Allocate a HeapNumber for the int and perform int-to-double
     // conversion.
     if (array_type == kExternalIntArray) {
-      __ push(eax);
+      __ push(ecx);
       __ fild_s(Operand(esp, 0));
-      __ pop(eax);
+      __ pop(ecx);
     } else {
       ASSERT(array_type == kExternalUnsignedIntArray);
       // Need to zero-extend the value.
       // There's no fild variant for unsigned values, so zero-extend
       // to a 64-bit int manually.
       __ push(Immediate(0));
-      __ push(eax);
+      __ push(ecx);
       __ fild_d(Operand(esp, 0));
-      __ pop(eax);
-      __ pop(eax);
+      __ pop(ecx);
+      __ pop(ecx);
     }
     // FP(0): value
-    __ AllocateHeapNumber(eax, ebx, ecx, &failed_allocation);
+    __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
     // Set the value.
+    __ mov(eax, ecx);
     __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
     __ ret(0);
   } else if (array_type == kExternalFloatArray) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
-    __ AllocateHeapNumber(eax, ebx, ecx, &failed_allocation);
+    __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
     // Set the value.
+    __ mov(eax, ecx);
     __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
     __ ret(0);
   } else {
-    __ shl(eax, kSmiTagSize);
+    __ mov(eax, ecx);
+    __ SmiTag(eax);
     __ ret(0);
   }
 
@@ -565,10 +552,51 @@
   __ fincstp();
   // Fall through to slow case.
 
-  // Slow case: Load name and receiver from stack and jump to runtime.
+  // Slow case: Load key and receiver from stack and jump to runtime.
   __ bind(&slow);
   __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
-  Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
+  GenerateRuntimeGetProperty(masm);
+}
+
+
+void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label slow;
+
+  // Check that the receiver isn't a smi.
+  __ test(edx, Immediate(kSmiTagMask));
+  __ j(zero, &slow, not_taken);
+
+  // Check that the key is a smi.
+  __ test(eax, Immediate(kSmiTagMask));
+  __ j(not_zero, &slow, not_taken);
+
+  // Get the map of the receiver.
+  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
+
+  // Check that it has indexed interceptor and access checks
+  // are not enabled for this object.
+  __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset));
+  __ and_(Operand(ecx), Immediate(kSlowCaseBitFieldMask));
+  __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor));
+  __ j(not_zero, &slow, not_taken);
+
+  // Everything is fine, call runtime.
+  __ pop(ecx);
+  __ push(edx);  // receiver
+  __ push(eax);  // key
+  __ push(ecx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(ExternalReference(
+        IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
+
+  __ bind(&slow);
+  GenerateMiss(masm);
 }
 
 
@@ -627,7 +655,7 @@
 
   // Slow case: call runtime.
   __ bind(&slow);
-  Generate(masm, ExternalReference(Runtime::kSetProperty));
+  GenerateRuntimeSetProperty(masm);
 
   // Check whether the elements is a pixel array.
   // eax: value
@@ -900,7 +928,7 @@
 
   // Slow case: call runtime.
   __ bind(&slow);
-  Generate(masm, ExternalReference(Runtime::kSetProperty));
+  GenerateRuntimeSetProperty(masm);
 }
 
 
@@ -983,7 +1011,7 @@
 
   // Search dictionary - put result in register edi.
   __ mov(edi, edx);
-  GenerateDictionaryLoad(masm, miss, eax, edi, ebx, ecx, CHECK_DICTIONARY);
+  GenerateDictionaryLoad(masm, miss, edx, ecx, eax, edi, ebx, CHECK_DICTIONARY);
 
   // Check that the result is not a smi.
   __ test(edi, Immediate(kSmiTagMask));
@@ -1127,13 +1155,11 @@
 
 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
 
-  __ mov(eax, Operand(esp, kPointerSize));
-
   // Probe the stub cache.
   Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
                                          NOT_IN_LOOP,
@@ -1141,20 +1167,18 @@
   StubCache::GenerateProbe(masm, flags, eax, ecx, ebx, edx);
 
   // Cache miss: Jump to runtime.
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
+  GenerateMiss(masm);
 }
 
 
 void LoadIC::GenerateNormal(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss, probe, global;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-
   // Check that the receiver isn't a smi.
   __ test(eax, Immediate(kSmiTagMask));
   __ j(zero, &miss, not_taken);
@@ -1179,7 +1203,15 @@
 
   // Search the dictionary placing the result in eax.
   __ bind(&probe);
-  GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx, CHECK_DICTIONARY);
+  GenerateDictionaryLoad(masm,
+                         &miss,
+                         eax,
+                         ecx,
+                         edx,
+                         edi,
+                         ebx,
+                         CHECK_DICTIONARY);
+  __ mov(eax, edi);
   __ ret(0);
 
   // Global object access: Check access rights.
@@ -1189,37 +1221,24 @@
 
   // Cache miss: Restore receiver from stack and jump to runtime.
   __ bind(&miss);
-  __ mov(eax, Operand(esp, 1 * kPointerSize));
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
+  GenerateMiss(masm);
 }
 
 
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
 
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
-}
-
-
-void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : name
-  //  -- esp[0] : return address
-  //  -- esp[4] : receiver
-  // -----------------------------------
-
-  __ mov(eax, Operand(esp, kPointerSize));
   __ pop(ebx);
   __ push(eax);  // receiver
   __ push(ecx);  // name
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
 }
 
 
@@ -1323,31 +1342,35 @@
 
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
 
-  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
-}
-
-
-void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
-  // ----------- S t a t e -------------
-  //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
-  // -----------------------------------
-
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ pop(ebx);
-  __ push(ecx);  // receiver
+  __ push(edx);  // receiver
   __ push(eax);  // name
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+
+  __ pop(ebx);
+  __ push(edx);  // receiver
+  __ push(eax);  // name
+  __ push(ebx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1);
 }
 
 
@@ -1369,26 +1392,6 @@
 }
 
 
-void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : transition map
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-
-  __ pop(ebx);
-  __ push(edx);  // receiver
-  __ push(ecx);  // transition map
-  __ push(eax);  // value
-  __ push(ebx);  // return address
-
-  // Perform tail call to the entry.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
-}
-
-
 void StoreIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : value
@@ -1411,7 +1414,7 @@
 // Defined in ic.cc.
 Object* KeyedStoreIC_Miss(Arguments args);
 
-void KeyedStoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
+void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- esp[0] : return address
@@ -1426,28 +1429,26 @@
   __ push(ecx);
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(f, 3, 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 }
 
 
-void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : value
-  //  -- ecx    : transition map
   //  -- esp[0] : return address
   //  -- esp[4] : key
   //  -- esp[8] : receiver
   // -----------------------------------
 
-  __ pop(ebx);
+  __ pop(ecx);
   __ push(Operand(esp, 1 * kPointerSize));
-  __ push(ecx);
+  __ push(Operand(esp, 1 * kPointerSize));
   __ push(eax);
-  __ push(ebx);
+  __ push(ecx);
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
 }
 
 #undef __
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 4dd6a9b..1f08e87 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -41,7 +41,6 @@
 
 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -165,7 +164,10 @@
   if (Serializer::enabled()) {
     // Can't do arithmetic on external references if it might get serialized.
     mov(value, Operand(object));
-    and_(value, Heap::NewSpaceMask());
+    // The mask isn't really an address.  We load it as an external reference in
+    // case the size of the new space is different between the snapshot maker
+    // and the running system.
+    and_(Operand(value), Immediate(ExternalReference::new_space_mask()));
     cmp(Operand(value), Immediate(ExternalReference::new_space_start()));
     j(equal, &done);
   } else {
@@ -308,6 +310,13 @@
     }
   }
 }
+
+void MacroAssembler::DebugBreak() {
+  Set(eax, Immediate(0));
+  mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak)));
+  CEntryStub ces(1);
+  call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
 #endif
 
 void MacroAssembler::Set(Register dst, const Immediate& x) {
@@ -377,6 +386,17 @@
 }
 
 
+void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
+  Label ok;
+  test(object, Immediate(kSmiTagMask));
+  j(zero, &ok);
+  cmp(FieldOperand(object, HeapObject::kMapOffset),
+      Factory::heap_number_map());
+  Assert(equal, msg);
+  bind(&ok);
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   push(ebp);
   mov(ebp, Operand(esp));
@@ -409,12 +429,8 @@
 
   // Reserve room for entry stack pointer and push the debug marker.
   ASSERT(ExitFrameConstants::kSPOffset  == -1 * kPointerSize);
-  push(Immediate(0));  // saved entry sp, patched before call
-  if (mode == ExitFrame::MODE_DEBUG) {
-    push(Immediate(0));
-  } else {
-    push(Immediate(CodeObject()));
-  }
+  push(Immediate(0));  // Saved entry sp, patched before call.
+  push(Immediate(CodeObject()));  // Accessed from ExitFrame::code_slot.
 
   // Save the frame pointer and the context in top.
   ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
@@ -551,6 +567,7 @@
 Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg,
                                    JSObject* holder, Register holder_reg,
                                    Register scratch,
+                                   int save_at_depth,
                                    Label* miss) {
   // Make sure there's no overlap between scratch and the other
   // registers.
@@ -558,7 +575,11 @@
 
   // Keep track of the current object in register reg.
   Register reg = object_reg;
-  int depth = 1;
+  int depth = 0;
+
+  if (save_at_depth == depth) {
+    mov(Operand(esp, kPointerSize), object_reg);
+  }
 
   // Check the maps in the prototype chain.
   // Traverse the prototype chain from the object and do map checks.
@@ -590,7 +611,6 @@
       // to it in the code. Load it from the map.
       reg = holder_reg;  // from now the object is in holder_reg
       mov(reg, FieldOperand(scratch, Map::kPrototypeOffset));
-
     } else {
       // Check the map of the current object.
       cmp(FieldOperand(reg, HeapObject::kMapOffset),
@@ -608,6 +628,10 @@
       mov(reg, Handle<JSObject>(prototype));
     }
 
+    if (save_at_depth == depth) {
+      mov(Operand(esp, kPointerSize), reg);
+    }
+
     // Go to the next object in the prototype chain.
     object = prototype;
   }
@@ -618,7 +642,7 @@
   j(not_equal, miss, not_taken);
 
   // Log the check depth.
-  LOG(IntEvent("check-maps-depth", depth));
+  LOG(IntEvent("check-maps-depth", depth + 1));
 
   // Perform security check for access to the global object and return
   // the holder register.
@@ -1135,6 +1159,16 @@
 }
 
 
+void MacroAssembler::CallExternalReference(ExternalReference ref,
+                                           int num_arguments) {
+  mov(eax, Immediate(num_arguments));
+  mov(ebx, Immediate(ref));
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
                                        int num_arguments) {
   if (f->nargs >= 0 && f->nargs != num_arguments) {
@@ -1355,10 +1389,22 @@
 }
 
 
-void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+  // Get the function and setup the context.
+  mov(edi, Immediate(Handle<JSFunction>(function)));
+  mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
+
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
   // Calls are not allowed in some stubs.
   ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
 
@@ -1366,55 +1412,22 @@
   // arguments match the expected number of arguments. Fake a
   // parameter count to avoid emitting code to do the check.
   ParameterCount expected(0);
-  InvokeCode(Handle<Code>(code), expected, expected,
-             RelocInfo::CODE_TARGET, flag);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
-    unresolved_.Add(entry);
-  }
+  GetBuiltinEntry(edx, id);
+  InvokeCode(Operand(edx), expected, expected, flag);
 }
 
 
 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  mov(Operand(target), Immediate(code));
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
-    unresolved_.Add(entry);
-  }
-  add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag));
-}
-
-
-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Move the builtin function into the temporary function slot by
-  // reading it from the builtins object. NOTE: We should be able to
-  // reduce this to two instructions by putting the function table in
-  // the global object instead of the "builtins" object and by using a
-  // real register for the function.
-  mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  mov(edx, FieldOperand(edx, GlobalObject::kBuiltinsOffset));
+  // Load the JavaScript builtin function from the builtins object.
+  mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  mov(edi, FieldOperand(edi, GlobalObject::kBuiltinsOffset));
   int builtins_offset =
       JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
-  mov(edi, FieldOperand(edx, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
+  mov(edi, FieldOperand(edi, builtins_offset));
+  // Load the code entry point from the function into the target register.
+  mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+  mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
+  add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag));
 }
 
 
@@ -1559,6 +1572,20 @@
 }
 
 
+void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
+    Register instance_type,
+    Register scratch,
+    Label *failure) {
+  if (!scratch.is(instance_type)) {
+    mov(scratch, instance_type);
+  }
+  and_(scratch,
+       kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
+  cmp(scratch, kStringTag | kSeqStringTag | kAsciiStringTag);
+  j(not_equal, failure);
+}
+
+
 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1,
                                                          Register object2,
                                                          Register scratch1,
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 0ddbd5d..69dc54c 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -69,6 +69,7 @@
   void CopyRegistersFromStackToMemory(Register base,
                                       Register scratch,
                                       RegList regs);
+  void DebugBreak();
 #endif
 
   // ---------------------------------------------------------------------------
@@ -123,6 +124,10 @@
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
   void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
@@ -171,6 +176,9 @@
     sar(reg, kSmiTagSize);
   }
 
+  // Abort execution if argument is not a number. Used in debug code.
+  void AbortIfNotNumber(Register object, const char* msg);
+
   // ---------------------------------------------------------------------------
   // Exception handling
 
@@ -193,9 +201,14 @@
   // clobbered if it the same as the holder register. The function
   // returns a register containing the holder - either object_reg or
   // holder_reg.
+  // The function can optionally (when save_at_depth !=
+  // kInvalidProtoDepth) save the object at the given depth by moving
+  // it to [esp + kPointerSize].
   Register CheckMaps(JSObject* object, Register object_reg,
                      JSObject* holder, Register holder_reg,
-                     Register scratch, Label* miss);
+                     Register scratch,
+                     int save_at_depth,
+                     Label* miss);
 
   // Generate code for checking access rights - used for security checks
   // on access to global objects across environments. The holder register
@@ -347,6 +360,9 @@
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId id, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(ExternalReference ref, int num_arguments);
+
   // Convenience function: Same as above, but takes the fid instead.
   Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
 
@@ -384,13 +400,6 @@
 
   void Move(Register target, Handle<Object> value);
 
-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }
 
 
@@ -426,6 +435,13 @@
   // ---------------------------------------------------------------------------
   // String utilities.
 
+  // Check whether the instance type represents a flat ascii string. Jump to the
+  // label if not. If the instance type can be scratched specify same register
+  // for both instance type and scratch.
+  void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
+                                              Register scratch,
+                                              Label *on_not_flat_ascii_string);
+
   // Checks if both objects are sequential ASCII strings, and jumps to label
   // if either is not.
   void JumpIfNotBothSequentialAsciiStrings(Register object1,
@@ -435,7 +451,6 @@
                                            Label *on_not_flat_ascii_strings);
 
  private:
-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
@@ -449,18 +464,6 @@
                       Label* done,
                       InvokeFlag flag);
 
-  // Prepares for a call or jump to a builtin by doing two things:
-  // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
-  //    compile time, so that later code can emit instructions to jump or call
-  //    the builtin directly.  If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
-  //    output parameter "resolved" to false.  Code that uses the return value
-  //    should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 7acf81c..5729d9d 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -152,22 +152,6 @@
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
-                                     JSObject* holder_obj) {
-  __ push(receiver);
-  __ push(holder);
-  __ push(name);
-  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
-  ASSERT(!Heap::InNewSpace(interceptor));
-  __ mov(receiver, Immediate(Handle<Object>(interceptor)));
-  __ push(receiver);
-  __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
-}
-
-
 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
                                                        int index,
                                                        Register prototype) {
@@ -226,30 +210,32 @@
 
 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
                                             Register receiver,
-                                            Register scratch,
+                                            Register scratch1,
+                                            Register scratch2,
                                             Label* miss) {
-  Label load_length, check_wrapper;
+  Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch register.
-  GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
 
   // Load length from the string and convert to a smi.
-  __ bind(&load_length);
   __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
   __ SmiTag(eax);
   __ ret(0);
 
   // Check if the object is a JSValue wrapper.
   __ bind(&check_wrapper);
-  __ cmp(scratch, JS_VALUE_TYPE);
+  __ cmp(scratch1, JS_VALUE_TYPE);
   __ j(not_equal, miss, not_taken);
 
   // Check if the wrapped value is a string and load the length
   // directly if it is.
-  __ mov(receiver, FieldOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, receiver, scratch, miss, miss);
-  __ jmp(&load_length);
+  __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
+  GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
+  __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
+  __ SmiTag(eax);
+  __ ret(0);
 }
 
 
@@ -285,20 +271,31 @@
 }
 
 
+static void PushInterceptorArguments(MacroAssembler* masm,
+                                     Register receiver,
+                                     Register holder,
+                                     Register name,
+                                     JSObject* holder_obj) {
+  __ push(receiver);
+  __ push(holder);
+  __ push(name);
+  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
+  ASSERT(!Heap::InNewSpace(interceptor));
+  __ mov(receiver, Immediate(Handle<Object>(interceptor)));
+  __ push(receiver);
+  __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
+}
+
+
 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
                                                    Register receiver,
                                                    Register holder,
                                                    Register name,
                                                    JSObject* holder_obj) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  ExternalReference ref =
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
-  __ mov(eax, Immediate(5));
-  __ mov(ebx, Immediate(ref));
-
-  CEntryStub stub(1);
-  __ CallStub(&stub);
+  __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)),
+        5);
 }
 
 
@@ -326,7 +323,7 @@
       stub_compiler->CheckPrototypes(object, receiver, holder,
                                      scratch1, scratch2, name, miss);
 
-  if (lookup->IsValid() && lookup->IsCacheable()) {
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
     compiler->CompileCacheable(masm,
                                stub_compiler,
                                receiver,
@@ -362,7 +359,7 @@
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -479,39 +476,362 @@
 };
 
 
+// Holds information about possible function call optimizations.
+class CallOptimization BASE_EMBEDDED {
+ public:
+  explicit CallOptimization(LookupResult* lookup)
+    : constant_function_(NULL),
+      is_simple_api_call_(false),
+      expected_receiver_type_(NULL),
+      api_call_info_(NULL) {
+    if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
+
+    // We only optimize constant function calls.
+    if (lookup->type() != CONSTANT_FUNCTION) return;
+
+    Initialize(lookup->GetConstantFunction());
+  }
+
+  explicit CallOptimization(JSFunction* function) {
+    Initialize(function);
+  }
+
+  bool is_constant_call() const {
+    return constant_function_ != NULL;
+  }
+
+  JSFunction* constant_function() const {
+    ASSERT(constant_function_ != NULL);
+    return constant_function_;
+  }
+
+  bool is_simple_api_call() const {
+    return is_simple_api_call_;
+  }
+
+  FunctionTemplateInfo* expected_receiver_type() const {
+    ASSERT(is_simple_api_call_);
+    return expected_receiver_type_;
+  }
+
+  CallHandlerInfo* api_call_info() const {
+    ASSERT(is_simple_api_call_);
+    return api_call_info_;
+  }
+
+  // Returns the depth of the object having the expected type in the
+  // prototype chain between the two arguments.
+  int GetPrototypeDepthOfExpectedType(JSObject* object,
+                                      JSObject* holder) const {
+    ASSERT(is_simple_api_call_);
+    if (expected_receiver_type_ == NULL) return 0;
+    int depth = 0;
+    while (object != holder) {
+      if (object->IsInstanceOf(expected_receiver_type_)) return depth;
+      object = JSObject::cast(object->GetPrototype());
+      ++depth;
+    }
+    if (holder->IsInstanceOf(expected_receiver_type_)) return depth;
+    return kInvalidProtoDepth;
+  }
+
+ private:
+  void Initialize(JSFunction* function) {
+    if (!function->is_compiled()) return;
+
+    constant_function_ = function;
+    is_simple_api_call_ = false;
+
+    AnalyzePossibleApiFunction(function);
+  }
+
+  // Determines whether the given function can be called using the
+  // fast api call builtin.
+  void AnalyzePossibleApiFunction(JSFunction* function) {
+    SharedFunctionInfo* sfi = function->shared();
+    if (sfi->function_data()->IsUndefined()) return;
+    FunctionTemplateInfo* info =
+        FunctionTemplateInfo::cast(sfi->function_data());
+
+    // Require a C++ callback.
+    if (info->call_code()->IsUndefined()) return;
+    api_call_info_ = CallHandlerInfo::cast(info->call_code());
+
+    // Accept signatures that either have no restrictions at all or
+    // only have restrictions on the receiver.
+    if (!info->signature()->IsUndefined()) {
+      SignatureInfo* signature = SignatureInfo::cast(info->signature());
+      if (!signature->args()->IsUndefined()) return;
+      if (!signature->receiver()->IsUndefined()) {
+        expected_receiver_type_ =
+            FunctionTemplateInfo::cast(signature->receiver());
+      }
+    }
+
+    is_simple_api_call_ = true;
+  }
+
+  JSFunction* constant_function_;
+  bool is_simple_api_call_;
+  FunctionTemplateInfo* expected_receiver_type_;
+  CallHandlerInfo* api_call_info_;
+};
+
+
+// Reserves space for the extra arguments to FastHandleApiCall in the
+// caller's frame.
+//
+// These arguments are set by CheckPrototypes and GenerateFastApiCall.
+static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
+  // ----------- S t a t e -------------
+  //  -- esp[0] : return address
+  //  -- esp[4] : last argument in the internal frame of the caller
+  // -----------------------------------
+  __ pop(scratch);
+  __ push(Immediate(Smi::FromInt(0)));
+  __ push(Immediate(Smi::FromInt(0)));
+  __ push(Immediate(Smi::FromInt(0)));
+  __ push(Immediate(Smi::FromInt(0)));
+  __ push(scratch);
+}
+
+
+// Undoes the effects of ReserveSpaceForFastApiCall.
+static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
+  // ----------- S t a t e -------------
+  //  -- esp[0]  : return address
+  //  -- esp[4]  : last fast api call extra argument
+  //  -- ...
+  //  -- esp[16] : first fast api call extra argument
+  //  -- esp[20] : last argument in the internal frame
+  // -----------------------------------
+  __ pop(scratch);
+  __ add(Operand(esp), Immediate(kPointerSize * 4));
+  __ push(scratch);
+}
+
+
+// Generates call to FastHandleApiCall builtin.
+static void GenerateFastApiCall(MacroAssembler* masm,
+                                const CallOptimization& optimization,
+                                int argc) {
+  // ----------- S t a t e -------------
+  //  -- esp[0]              : return address
+  //  -- esp[4]              : object passing the type check
+  //                           (last fast api call extra argument,
+  //                            set by CheckPrototypes)
+  //  -- esp[8]              : api call data
+  //  -- esp[12]             : api callback
+  //  -- esp[16]             : api function
+  //                           (first fast api call extra argument)
+  //  -- esp[20]             : last argument
+  //  -- ...
+  //  -- esp[(argc + 5) * 4] : first argument
+  //  -- esp[(argc + 6) * 4] : receiver
+  // -----------------------------------
+
+  // Get the function and setup the context.
+  JSFunction* function = optimization.constant_function();
+  __ mov(edi, Immediate(Handle<JSFunction>(function)));
+  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+
+  // Pass the additional arguments FastHandleApiCall expects.
+  __ mov(Operand(esp, 4 * kPointerSize), edi);
+  bool info_loaded = false;
+  Object* callback = optimization.api_call_info()->callback();
+  if (Heap::InNewSpace(callback)) {
+    info_loaded = true;
+    __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info()));
+    __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kCallbackOffset));
+    __ mov(Operand(esp, 3 * kPointerSize), ebx);
+  } else {
+    __ mov(Operand(esp, 3 * kPointerSize), Immediate(Handle<Object>(callback)));
+  }
+  Object* call_data = optimization.api_call_info()->data();
+  if (Heap::InNewSpace(call_data)) {
+    if (!info_loaded) {
+      __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info()));
+    }
+    __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
+    __ mov(Operand(esp, 2 * kPointerSize), ebx);
+  } else {
+    __ mov(Operand(esp, 2 * kPointerSize),
+           Immediate(Handle<Object>(call_data)));
+  }
+
+  // Set the number of arguments.
+  __ mov(eax, Immediate(argc + 4));
+
+  // Jump to the fast api call builtin (tail call).
+  Handle<Code> code = Handle<Code>(
+      Builtins::builtin(Builtins::FastHandleApiCall));
+  ParameterCount expected(0);
+  __ InvokeCode(code, expected, expected,
+                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+}
+
+
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
-  CallInterceptorCompiler(const ParameterCount& arguments, Register name)
-      : arguments_(arguments), argc_(arguments.immediate()), name_(name) {}
+  CallInterceptorCompiler(StubCompiler* stub_compiler,
+                          const ParameterCount& arguments,
+                          Register name)
+      : stub_compiler_(stub_compiler),
+        arguments_(arguments),
+        name_(name) {}
 
+  void Compile(MacroAssembler* masm,
+               JSObject* object,
+               JSObject* holder,
+               String* name,
+               LookupResult* lookup,
+               Register receiver,
+               Register scratch1,
+               Register scratch2,
+               Label* miss) {
+    ASSERT(holder->HasNamedInterceptor());
+    ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
+
+    // Check that the receiver isn't a smi.
+    __ test(receiver, Immediate(kSmiTagMask));
+    __ j(zero, miss, not_taken);
+
+    CallOptimization optimization(lookup);
+
+    if (optimization.is_constant_call() &&
+        !Top::CanHaveSpecialFunctions(holder)) {
+      CompileCacheable(masm,
+                       object,
+                       receiver,
+                       scratch1,
+                       scratch2,
+                       holder,
+                       lookup,
+                       name,
+                       optimization,
+                       miss);
+    } else {
+      CompileRegular(masm,
+                     object,
+                     receiver,
+                     scratch1,
+                     scratch2,
+                     name,
+                     holder,
+                     miss);
+    }
+  }
+
+ private:
   void CompileCacheable(MacroAssembler* masm,
-                        StubCompiler* stub_compiler,
+                        JSObject* object,
                         Register receiver,
-                        Register holder,
                         Register scratch1,
                         Register scratch2,
                         JSObject* holder_obj,
                         LookupResult* lookup,
                         String* name,
+                        const CallOptimization& optimization,
                         Label* miss_label) {
-    JSFunction* function = 0;
-    bool optimize = false;
-    // So far the most popular case for failed interceptor is
-    // CONSTANT_FUNCTION sitting below.
-    if (lookup->type() == CONSTANT_FUNCTION) {
-      function = lookup->GetConstantFunction();
-      // JSArray holder is a special case for call constant function
-      // (see the corresponding code).
-      if (function->is_compiled() && !holder_obj->IsJSArray()) {
-        optimize = true;
+    ASSERT(optimization.is_constant_call());
+    ASSERT(!lookup->holder()->IsGlobalObject());
+
+    int depth1 = kInvalidProtoDepth;
+    int depth2 = kInvalidProtoDepth;
+    bool can_do_fast_api_call = false;
+    if (optimization.is_simple_api_call() &&
+        !lookup->holder()->IsGlobalObject()) {
+      depth1 = optimization.GetPrototypeDepthOfExpectedType(object, holder_obj);
+      if (depth1 == kInvalidProtoDepth) {
+        depth2 = optimization.GetPrototypeDepthOfExpectedType(holder_obj,
+                                                              lookup->holder());
       }
+      can_do_fast_api_call = (depth1 != kInvalidProtoDepth) ||
+                             (depth2 != kInvalidProtoDepth);
     }
 
-    if (!optimize) {
-      CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
-      return;
+    __ IncrementCounter(&Counters::call_const_interceptor, 1);
+
+    if (can_do_fast_api_call) {
+      __ IncrementCounter(&Counters::call_const_interceptor_fast_api, 1);
+      ReserveSpaceForFastApiCall(masm, scratch1);
     }
 
+    Label miss_cleanup;
+    Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
+    Register holder =
+        stub_compiler_->CheckPrototypes(object, receiver, holder_obj,
+                                        scratch1, scratch2, name,
+                                        depth1, miss);
+
+    Label regular_invoke;
+    LoadWithInterceptor(masm, receiver, holder, holder_obj, &regular_invoke);
+
+    // Generate code for the failed interceptor case.
+
+    // Check the lookup is still valid.
+    stub_compiler_->CheckPrototypes(holder_obj, receiver,
+                                    lookup->holder(),
+                                    scratch1, scratch2, name,
+                                    depth2, miss);
+
+    if (can_do_fast_api_call) {
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
+    } else {
+      __ InvokeFunction(optimization.constant_function(), arguments_,
+                        JUMP_FUNCTION);
+    }
+
+    if (can_do_fast_api_call) {
+      __ bind(&miss_cleanup);
+      FreeSpaceForFastApiCall(masm, scratch1);
+      __ jmp(miss_label);
+    }
+
+    __ bind(&regular_invoke);
+    if (can_do_fast_api_call) {
+      FreeSpaceForFastApiCall(masm, scratch1);
+    }
+  }
+
+  void CompileRegular(MacroAssembler* masm,
+                      JSObject* object,
+                      Register receiver,
+                      Register scratch1,
+                      Register scratch2,
+                      String* name,
+                      JSObject* holder_obj,
+                      Label* miss_label) {
+    Register holder =
+        stub_compiler_->CheckPrototypes(object, receiver, holder_obj,
+                                        scratch1, scratch2, name,
+                                        miss_label);
+
+    __ EnterInternalFrame();
+    // Save the name_ register across the call.
+    __ push(name_);
+
+    PushInterceptorArguments(masm,
+                             receiver,
+                             holder,
+                             name_,
+                             holder_obj);
+
+    __ CallExternalReference(
+          ExternalReference(
+              IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+          5);
+
+    // Restore the name_ register.
+    __ pop(name_);
+    __ LeaveInternalFrame();
+  }
+
+  void LoadWithInterceptor(MacroAssembler* masm,
+                           Register receiver,
+                           Register holder,
+                           JSObject* holder_obj,
+                           Label* interceptor_succeeded) {
     __ EnterInternalFrame();
     __ push(holder);  // Save the holder.
     __ push(name_);  // Save the name.
@@ -527,66 +847,11 @@
     __ LeaveInternalFrame();
 
     __ cmp(eax, Factory::no_interceptor_result_sentinel());
-    Label invoke;
-    __ j(not_equal, &invoke);
-
-    stub_compiler->CheckPrototypes(holder_obj, receiver,
-                                   lookup->holder(), scratch1,
-                                   scratch2,
-                                   name,
-                                   miss_label);
-    if (lookup->holder()->IsGlobalObject()) {
-      __ mov(edx, Operand(esp, (argc_ + 1) * kPointerSize));
-      __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
-      __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edx);
-    }
-
-    ASSERT(function->is_compiled());
-    // Get the function and setup the context.
-    __ mov(edi, Immediate(Handle<JSFunction>(function)));
-    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-    // Jump to the cached code (tail call).
-    Handle<Code> code(function->code());
-    ParameterCount expected(function->shared()->formal_parameter_count());
-    __ InvokeCode(code, expected, arguments_,
-                  RelocInfo::CODE_TARGET, JUMP_FUNCTION);
-
-    __ bind(&invoke);
+    __ j(not_equal, interceptor_succeeded);
   }
 
-  void CompileRegular(MacroAssembler* masm,
-                      Register receiver,
-                      Register holder,
-                      Register scratch,
-                      JSObject* holder_obj,
-                      Label* miss_label) {
-    __ EnterInternalFrame();
-    // Save the name_ register across the call.
-    __ push(name_);
-
-    PushInterceptorArguments(masm,
-                             receiver,
-                             holder,
-                             name_,
-                             holder_obj);
-
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ mov(eax, Immediate(5));
-    __ mov(ebx, Immediate(ref));
-
-    CEntryStub stub(1);
-    __ CallStub(&stub);
-
-    // Restore the name_ register.
-    __ pop(name_);
-    __ LeaveInternalFrame();
-  }
-
- private:
+  StubCompiler* stub_compiler_;
   const ParameterCount& arguments_;
-  int argc_;
   Register name_;
 };
 
@@ -605,8 +870,9 @@
 }
 
 
+// Both name_reg and receiver_reg are preserved on jumps to miss_label,
+// but may be destroyed if store is successful.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
-                                      Builtins::Name storage_extend,
                                       JSObject* object,
                                       int index,
                                       Map* transition,
@@ -636,9 +902,13 @@
   if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
     // The properties must be extended before we can store the value.
     // We jump to a runtime call that extends the properties array.
-    __ mov(ecx, Immediate(Handle<Map>(transition)));
-    Handle<Code> ic(Builtins::builtin(storage_extend));
-    __ jmp(ic, RelocInfo::CODE_TARGET);
+    __ pop(scratch);  // Return address.
+    __ push(receiver_reg);
+    __ push(Immediate(Handle<Map>(transition)));
+    __ push(eax);
+    __ push(scratch);
+    __ TailCallRuntime(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
     return;
   }
 
@@ -691,10 +961,12 @@
                                        Register holder_reg,
                                        Register scratch,
                                        String* name,
+                                       int push_at_depth,
                                        Label* miss) {
   // Check that the maps haven't changed.
   Register result =
-      masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss);
+      masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch,
+                        push_at_depth, miss);
 
   // If we've skipped any global objects, it's not enough to verify
   // that their maps haven't changed.
@@ -716,7 +988,7 @@
     object = JSObject::cast(object->GetPrototype());
   }
 
-  // Return the register containin the holder.
+  // Return the register containing the holder.
   return result;
 }
 
@@ -887,7 +1159,7 @@
 }
 
 
-Object* CallStubCompiler::CompileCallField(Object* object,
+Object* CallStubCompiler::CompileCallField(JSObject* object,
                                            JSObject* holder,
                                            int index,
                                            String* name) {
@@ -909,9 +1181,7 @@
   __ j(zero, &miss, not_taken);
 
   // Do the right check and compute the holder register.
-  Register reg =
-      CheckPrototypes(JSObject::cast(object), edx, holder,
-                      ebx, eax, name, &miss);
+  Register reg = CheckPrototypes(object, edx, holder, ebx, eax, name, &miss);
 
   GenerateFastPropertyLoad(masm(), edi, reg, holder, index);
 
@@ -969,15 +1239,31 @@
   // unless we're doing a receiver map check.
   ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
 
+  CallOptimization optimization(function);
+  int depth = kInvalidProtoDepth;
+
   switch (check) {
     case RECEIVER_MAP_CHECK:
+      __ IncrementCounter(&Counters::call_const, 1);
+
+      if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
+        depth = optimization.GetPrototypeDepthOfExpectedType(
+            JSObject::cast(object), holder);
+      }
+
+      if (depth != kInvalidProtoDepth) {
+        __ IncrementCounter(&Counters::call_const_fast_api, 1);
+        ReserveSpaceForFastApiCall(masm(), eax);
+      }
+
       // Check that the maps haven't changed.
       CheckPrototypes(JSObject::cast(object), edx, holder,
-                      ebx, eax, name, &miss);
+                      ebx, eax, name, depth, &miss);
 
       // Patch the receiver on the stack with the global proxy if
       // necessary.
       if (object->IsGlobalObject()) {
+        ASSERT(depth == kInvalidProtoDepth);
         __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
         __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
       }
@@ -1062,19 +1348,17 @@
       UNREACHABLE();
   }
 
-  // Get the function and setup the context.
-  __ mov(edi, Immediate(Handle<JSFunction>(function)));
-  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-  // Jump to the cached code (tail call).
-  ASSERT(function->is_compiled());
-  Handle<Code> code(function->code());
-  ParameterCount expected(function->shared()->formal_parameter_count());
-  __ InvokeCode(code, expected, arguments(),
-                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+  if (depth != kInvalidProtoDepth) {
+    GenerateFastApiCall(masm(), optimization, argc);
+  } else {
+    __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  }
 
   // Handle call cache miss.
   __ bind(&miss);
+  if (depth != kInvalidProtoDepth) {
+    FreeSpaceForFastApiCall(masm(), eax);
+  }
   Handle<Code> ic = ComputeCallMiss(arguments().immediate());
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
@@ -1087,7 +1371,7 @@
 }
 
 
-Object* CallStubCompiler::CompileCallInterceptor(Object* object,
+Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
@@ -1108,18 +1392,16 @@
   // Get the receiver from the stack.
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
-  CallInterceptorCompiler compiler(arguments(), ecx);
-  CompileLoadInterceptor(&compiler,
-                         this,
-                         masm(),
-                         JSObject::cast(object),
-                         holder,
-                         name,
-                         &lookup,
-                         edx,
-                         ebx,
-                         edi,
-                         &miss);
+  CallInterceptorCompiler compiler(this, arguments(), ecx);
+  compiler.Compile(masm(),
+                   object,
+                   holder,
+                   name,
+                   &lookup,
+                   edx,
+                   ebx,
+                   edi,
+                   &miss);
 
   // Restore receiver.
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
@@ -1249,7 +1531,6 @@
 
   // Generate store field code.  Trashes the name register.
   GenerateStoreField(masm(),
-                     Builtins::StoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
@@ -1423,15 +1704,14 @@
   __ j(not_equal, &miss, not_taken);
 
   // Get the object from the stack.
-  __ mov(ebx, Operand(esp, 2 * kPointerSize));
+  __ mov(edx, Operand(esp, 2 * kPointerSize));
 
   // Generate store field code.  Trashes the name register.
   GenerateStoreField(masm(),
-                     Builtins::KeyedStoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
-                     ebx, ecx, edx,
+                     edx, ecx, ebx,
                      &miss);
 
   // Handle store cache miss.
@@ -1451,13 +1731,12 @@
                                            int index,
                                            String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
   GenerateLoadField(object, holder, eax, ebx, edx, index, name, &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
@@ -1472,13 +1751,12 @@
                                               JSObject* holder,
                                               AccessorInfo* callback) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
   Failure* failure = Failure::InternalError();
   bool success = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx,
                                       callback, name, &miss, &failure);
@@ -1497,13 +1775,12 @@
                                               Object* value,
                                               String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
   GenerateLoadConstant(object, holder, eax, ebx, edx, value, name, &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
@@ -1517,16 +1794,15 @@
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
   LookupResult lookup;
   LookupPostInterceptor(holder, name, &lookup);
 
-  __ mov(eax, Operand(esp, kPointerSize));
   // TODO(368): Compile in the whole chain: all the interceptors in
   // prototypes and ultimate answer.
   GenerateLoadInterceptor(receiver,
@@ -1553,15 +1829,12 @@
                                             String* name,
                                             bool is_dont_delete) {
   // ----------- S t a t e -------------
+  //  -- eax    : receiver
   //  -- ecx    : name
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;
 
-  // Get the receiver from the stack.
-  __ mov(eax, Operand(esp, kPointerSize));
-
   // If the object is the holder then we know that it's a global
   // object which can only happen for contextual loads. In this case,
   // the receiver cannot be a smi.
@@ -1574,19 +1847,20 @@
   CheckPrototypes(object, eax, holder, ebx, edx, name, &miss);
 
   // Get the value from the cell.
-  __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell)));
-  __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset));
+  __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
+  __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (!is_dont_delete) {
-    __ cmp(eax, Factory::the_hole_value());
+    __ cmp(ebx, Factory::the_hole_value());
     __ j(equal, &miss, not_taken);
   } else if (FLAG_debug_code) {
-    __ cmp(eax, Factory::the_hole_value());
+    __ cmp(ebx, Factory::the_hole_value());
     __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
 
   __ IncrementCounter(&Counters::named_load_global_inline, 1);
+  __ mov(eax, ebx);
   __ ret(0);
 
   __ bind(&miss);
@@ -1603,21 +1877,19 @@
                                                 JSObject* holder,
                                                 int index) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_field, 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
   __ j(not_equal, &miss, not_taken);
 
-  GenerateLoadField(receiver, holder, ecx, ebx, edx, index, name, &miss);
+  GenerateLoadField(receiver, holder, edx, ebx, ecx, index, name, &miss);
 
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_field, 1);
@@ -1633,14 +1905,12 @@
                                                    JSObject* holder,
                                                    AccessorInfo* callback) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_callback, 1);
 
   // Check that the name has not changed.
@@ -1648,7 +1918,7 @@
   __ j(not_equal, &miss, not_taken);
 
   Failure* failure = Failure::InternalError();
-  bool success = GenerateLoadCallback(receiver, holder, ecx, eax, ebx, edx,
+  bool success = GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx,
                                       callback, name, &miss, &failure);
   if (!success) return failure;
 
@@ -1666,21 +1936,19 @@
                                                    JSObject* holder,
                                                    Object* value) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_constant_function, 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
   __ j(not_equal, &miss, not_taken);
 
-  GenerateLoadConstant(receiver, holder, ecx, ebx, edx,
+  GenerateLoadConstant(receiver, holder, edx, ebx, ecx,
                        value, name, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_constant_function, 1);
@@ -1695,14 +1963,12 @@
                                                       JSObject* holder,
                                                       String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_interceptor, 1);
 
   // Check that the name has not changed.
@@ -1714,9 +1980,9 @@
   GenerateLoadInterceptor(receiver,
                           holder,
                           &lookup,
-                          ecx,
-                          eax,
                           edx,
+                          eax,
+                          ecx,
                           ebx,
                           name,
                           &miss);
@@ -1733,21 +1999,19 @@
 
 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_array_length, 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
   __ j(not_equal, &miss, not_taken);
 
-  GenerateLoadArrayLength(masm(), ecx, edx, &miss);
+  GenerateLoadArrayLength(masm(), edx, ecx, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_array_length, 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -1759,21 +2023,19 @@
 
 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_string_length, 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
   __ j(not_equal, &miss, not_taken);
 
-  GenerateLoadStringLength(masm(), ecx, edx, &miss);
+  GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_string_length, 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -1785,21 +2047,19 @@
 
 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
   // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : name
-  //  -- esp[8] : receiver
   // -----------------------------------
   Label miss;
 
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));
   __ IncrementCounter(&Counters::keyed_load_function_prototype, 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
   __ j(not_equal, &miss, not_taken);
 
-  GenerateLoadFunctionPrototype(masm(), ecx, edx, ebx, &miss);
+  GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_function_prototype, 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
diff --git a/src/ia32/virtual-frame-ia32.cc b/src/ia32/virtual-frame-ia32.cc
index 9267507..7df028e 100644
--- a/src/ia32/virtual-frame-ia32.cc
+++ b/src/ia32/virtual-frame-ia32.cc
@@ -45,7 +45,7 @@
     : elements_(parameter_count() + local_count() + kPreallocatedElements),
       stack_pointer_(parameter_count() + 1) {  // 0-based index of TOS.
   for (int i = 0; i <= stack_pointer_; i++) {
-    elements_.Add(FrameElement::MemoryElement());
+    elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
   }
   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
     register_locations_[i] = kIllegalIndex;
@@ -173,10 +173,12 @@
   for (int i = 0; i < element_count(); i++) {
     FrameElement element = elements_[i];
 
+    // All number type information is reset to unknown for a mergable frame
+    // because of incoming back edges.
     if (element.is_constant() || element.is_copy()) {
       if (element.is_synced()) {
         // Just spill.
-        elements_[i] = FrameElement::MemoryElement();
+        elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
       } else {
         // Allocate to a register.
         FrameElement backing_element;  // Invalid if not a copy.
@@ -187,7 +189,8 @@
         ASSERT(fresh.is_valid());  // A register was spilled if all were in use.
         elements_[i] =
             FrameElement::RegisterElement(fresh.reg(),
-                                          FrameElement::NOT_SYNCED);
+                                          FrameElement::NOT_SYNCED,
+                                          NumberInfo::kUnknown);
         Use(fresh.reg(), i);
 
         // Emit a move.
@@ -220,6 +223,7 @@
       // The copy flag is not relied on before the end of this loop,
       // including when registers are spilled.
       elements_[i].clear_copied();
+      elements_[i].set_number_info(NumberInfo::kUnknown);
     }
   }
 }
@@ -607,10 +611,14 @@
   // Set the new backing element.
   if (elements_[new_backing_index].is_synced()) {
     elements_[new_backing_index] =
-        FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED);
+        FrameElement::RegisterElement(backing_reg,
+                                      FrameElement::SYNCED,
+                                      original.number_info());
   } else {
     elements_[new_backing_index] =
-        FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED);
+        FrameElement::RegisterElement(backing_reg,
+                                      FrameElement::NOT_SYNCED,
+                                      original.number_info());
   }
   // Update the other copies.
   for (int i = new_backing_index + 1; i < element_count(); i++) {
@@ -641,7 +649,8 @@
       ASSERT(fresh.is_valid());
       FrameElement new_element =
           FrameElement::RegisterElement(fresh.reg(),
-                                        FrameElement::NOT_SYNCED);
+                                        FrameElement::NOT_SYNCED,
+                                        original.number_info());
       Use(fresh.reg(), element_count());
       elements_.Add(new_element);
       __ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
@@ -853,6 +862,17 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+  PrepareForCall(0, 0);
+  ASSERT(cgen()->HasValidEntryRegisters());
+  __ DebugBreak();
+  Result result = cgen()->allocator()->Allocate(eax);
+  ASSERT(result.is_valid());
+}
+#endif
+
+
 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
                                    InvokeFlag flag,
                                    int arg_count) {
@@ -877,67 +897,89 @@
 
 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
   // Name and receiver are on the top of the frame.  The IC expects
-  // name in ecx and receiver on the stack.  It does not drop the
-  // receiver.
+  // name in ecx and receiver in eax.
   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
   Result name = Pop();
-  PrepareForCall(1, 0);  // One stack arg, not callee-dropped.
-  name.ToRegister(ecx);
+  Result receiver = Pop();
+  PrepareForCall(0, 0);  // No stack arguments.
+  // Move results to the right registers:
+  if (name.is_register() && name.reg().is(eax)) {
+    if (receiver.is_register() && receiver.reg().is(ecx)) {
+      // Wrong registers.
+      __ xchg(eax, ecx);
+    } else {
+      // Register ecx is free for name, which frees eax for receiver.
+      name.ToRegister(ecx);
+      receiver.ToRegister(eax);
+    }
+  } else {
+    // Register eax is free for receiver, which frees ecx for name.
+    receiver.ToRegister(eax);
+    name.ToRegister(ecx);
+  }
   name.Unuse();
+  receiver.Unuse();
   return RawCallCodeObject(ic, mode);
 }
 
 
 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
-  // Key and receiver are on top of the frame.  The IC expects them on
-  // the stack.  It does not drop them.
+  // Key and receiver are on top of the frame. Put them in eax and edx.
+  Result key = Pop();
+  Result receiver = Pop();
+  PrepareForCall(0, 0);
+
+  if (!key.is_register() || !key.reg().is(edx)) {
+    // Register edx is available for receiver.
+    receiver.ToRegister(edx);
+    key.ToRegister(eax);
+  } else if (!receiver.is_register() || !receiver.reg().is(eax)) {
+    // Register eax is available for key.
+    key.ToRegister(eax);
+    receiver.ToRegister(edx);
+  } else {
+    __ xchg(edx, eax);
+  }
+  key.Unuse();
+  receiver.Unuse();
+
   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
-  PrepareForCall(2, 0);  // Two stack args, neither callee-dropped.
   return RawCallCodeObject(ic, mode);
 }
 
 
-Result VirtualFrame::CallStoreIC() {
-  // Name, value, and receiver are on top of the frame.  The IC
-  // expects name in ecx, value in eax, and receiver in edx.
+Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
+  // Value and (if not contextual) receiver are on top of the frame.
+  //  The IC expects name in ecx, value in eax, and receiver in edx.
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-  Result name = Pop();
   Result value = Pop();
-  Result receiver = Pop();
-  PrepareForCall(0, 0);
-
-  // Optimized for case in which name is a constant value.
-  if (name.is_register() && (name.reg().is(edx) || name.reg().is(eax))) {
-    if (!is_used(ecx)) {
-      name.ToRegister(ecx);
-    } else if (!is_used(ebx)) {
-      name.ToRegister(ebx);
-    } else {
-      ASSERT(!is_used(edi));  // Only three results are live, so edi is free.
-      name.ToRegister(edi);
-    }
-  }
-  // Now name is not in edx or eax, so we can fix them, then move name to ecx.
-  if (value.is_register() && value.reg().is(edx)) {
-    if (receiver.is_register() && receiver.reg().is(eax)) {
-      // Wrong registers.
-      __ xchg(eax, edx);
-    } else {
-      // Register eax is free for value, which frees edx for receiver.
-      value.ToRegister(eax);
-      receiver.ToRegister(edx);
-    }
-  } else {
-    // Register edx is free for receiver, which guarantees eax is free for
-    // value.
-    receiver.ToRegister(edx);
+  if (is_contextual) {
+    PrepareForCall(0, 0);
     value.ToRegister(eax);
+    __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+    __ mov(ecx, name);
+  } else {
+    Result receiver = Pop();
+    PrepareForCall(0, 0);
+
+    if (value.is_register() && value.reg().is(edx)) {
+      if (receiver.is_register() && receiver.reg().is(eax)) {
+        // Wrong registers.
+        __ xchg(eax, edx);
+      } else {
+        // Register eax is free for value, which frees edx for receiver.
+        value.ToRegister(eax);
+        receiver.ToRegister(edx);
+      }
+    } else {
+      // Register edx is free for receiver, which guarantees eax is free for
+      // value.
+      receiver.ToRegister(edx);
+      value.ToRegister(eax);
+    }
   }
-  // Receiver and value are in the right place, so ecx is free for name.
-  name.ToRegister(ecx);
-  name.Unuse();
+  __ mov(ecx, name);
   value.Unuse();
-  receiver.Unuse();
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -947,7 +989,6 @@
   // expects value in eax and key and receiver on the stack.  It does
   // not drop the key and receiver.
   Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
-  // TODO(1222589): Make the IC grab the values from the stack.
   Result value = Pop();
   PrepareForCall(2, 0);  // Two stack args, neither callee-dropped.
   value.ToRegister(eax);
@@ -1025,6 +1066,14 @@
   int index = element_count();
   ASSERT(element.is_valid());
 
+  // Get number type information of the result.
+  NumberInfo::Type info;
+  if (!element.is_copy()) {
+    info = element.number_info();
+  } else {
+    info = elements_[element.index()].number_info();
+  }
+
   bool pop_needed = (stack_pointer_ == index);
   if (pop_needed) {
     stack_pointer_--;
@@ -1032,6 +1081,7 @@
       Result temp = cgen()->allocator()->Allocate();
       ASSERT(temp.is_valid());
       __ pop(temp.reg());
+      temp.set_number_info(info);
       return temp;
     }
 
@@ -1059,14 +1109,16 @@
     ASSERT(temp.is_valid());
     Use(temp.reg(), index);
     FrameElement new_element =
-        FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED);
+        FrameElement::RegisterElement(temp.reg(),
+                                      FrameElement::SYNCED,
+                                      element.number_info());
     // Preserve the copy flag on the element.
     if (element.is_copied()) new_element.set_copied();
     elements_[index] = new_element;
     __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
-    return Result(temp.reg());
+    return Result(temp.reg(), info);
   } else if (element.is_register()) {
-    return Result(element.reg());
+    return Result(element.reg(), info);
   } else {
     ASSERT(element.is_constant());
     return Result(element.handle());
@@ -1090,30 +1142,49 @@
 }
 
 
-void VirtualFrame::EmitPush(Register reg) {
+void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(reg);
 }
 
 
-void VirtualFrame::EmitPush(Operand operand) {
+void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(operand);
 }
 
 
-void VirtualFrame::EmitPush(Immediate immediate) {
+void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(immediate);
 }
 
 
+void VirtualFrame::Push(Expression* expr) {
+  ASSERT(expr->IsTrivial());
+
+  Literal* lit = expr->AsLiteral();
+  if (lit != NULL) {
+    Push(lit->handle());
+    return;
+  }
+
+  VariableProxy* proxy = expr->AsVariableProxy();
+  if (proxy != NULL && proxy->is_this()) {
+    PushParameterAt(-1);
+    return;
+  }
+
+  UNREACHABLE();
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/ia32/virtual-frame-ia32.h b/src/ia32/virtual-frame-ia32.h
index d6d55d1..7be593c 100644
--- a/src/ia32/virtual-frame-ia32.h
+++ b/src/ia32/virtual-frame-ia32.h
@@ -28,6 +28,7 @@
 #ifndef V8_IA32_VIRTUAL_FRAME_IA32_H_
 #define V8_IA32_VIRTUAL_FRAME_IA32_H_
 
+#include "number-info.h"
 #include "register-allocator.h"
 #include "scopes.h"
 
@@ -82,7 +83,8 @@
   MacroAssembler* masm() { return cgen()->masm(); }
 
   // Create a duplicate of an existing valid frame element.
-  FrameElement CopyElementAt(int index);
+  FrameElement CopyElementAt(int index,
+    NumberInfo::Type info = NumberInfo::kUninitialized);
 
   // The number of elements on the virtual frame.
   int element_count() { return elements_.length(); }
@@ -324,21 +326,25 @@
   Result CallRuntime(Runtime::Function* f, int arg_count);
   Result CallRuntime(Runtime::FunctionId id, int arg_count);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  void DebugBreak();
+#endif
+
   // Invoke builtin given the number of arguments it expects on (and
   // removes from) the stack.
   Result InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, int arg_count);
 
   // Call load IC.  Name and receiver are found on top of the frame.
-  // Receiver is not dropped.
+  // Both are dropped.
   Result CallLoadIC(RelocInfo::Mode mode);
 
   // Call keyed load IC.  Key and receiver are found on top of the
-  // frame.  They are not dropped.
+  // frame.  Both are dropped.
   Result CallKeyedLoadIC(RelocInfo::Mode mode);
 
-  // Call store IC.  Name, value, and receiver are found on top of the
-  // frame.  Receiver is not dropped.
-  Result CallStoreIC();
+  // Call store IC.  If the load is contextual, value is found on top of the
+  // frame.  If not, value and receiver are on the frame.  Both are dropped.
+  Result CallStoreIC(Handle<String> name, bool is_contextual);
 
   // Call keyed store IC.  Value, key, and receiver are found on top
   // of the frame.  Key and receiver are not dropped.
@@ -381,12 +387,15 @@
 
   // Push an element on top of the expression stack and emit a
   // corresponding push instruction.
-  void EmitPush(Register reg);
-  void EmitPush(Operand operand);
-  void EmitPush(Immediate immediate);
+  void EmitPush(Register reg,
+                NumberInfo::Type info = NumberInfo::kUnknown);
+  void EmitPush(Operand operand,
+                NumberInfo::Type info = NumberInfo::kUnknown);
+  void EmitPush(Immediate immediate,
+                NumberInfo::Type info = NumberInfo::kUnknown);
 
   // Push an element on the virtual frame.
-  void Push(Register reg);
+  void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
   void Push(Handle<Object> value);
   void Push(Smi* value) {
     Push(Handle<Object> (value));
@@ -398,7 +407,7 @@
     // This assert will trigger if you try to push the same value twice.
     ASSERT(result->is_valid());
     if (result->is_register()) {
-      Push(result->reg());
+      Push(result->reg(), result->number_info());
     } else {
       ASSERT(result->is_constant());
       Push(result->handle());
@@ -406,6 +415,10 @@
     result->Unuse();
   }
 
+  // Pushing an expression expects that the expression is trivial (according
+  // to Expression::IsTrivial).
+  void Push(Expression* expr);
+
   // Nip removes zero or more elements from immediately below the top
   // of the frame, leaving the previous top-of-frame value on top of
   // the frame.  Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
diff --git a/src/ic.cc b/src/ic.cc
index 27a1841..b6b57dc 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -330,10 +330,11 @@
   while (true) {
     object->Lookup(name, lookup);
     // Besides normal conditions (property not found or it's not
-    // an interceptor), bail out of lookup is not cacheable: we won't
+    // an interceptor), bail out if lookup is not cacheable: we won't
     // be able to IC it anyway and regular lookup should work fine.
-    if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR ||
-        !lookup->IsCacheable()) {
+    if (!lookup->IsFound()
+        || (lookup->type() != INTERCEPTOR)
+        || !lookup->IsCacheable()) {
       return;
     }
 
@@ -343,7 +344,7 @@
     }
 
     holder->LocalLookupRealNamedProperty(name, lookup);
-    if (lookup->IsValid()) {
+    if (lookup->IsProperty()) {
       ASSERT(lookup->type() != INTERCEPTOR);
       return;
     }
@@ -422,7 +423,7 @@
   LookupResult lookup;
   LookupForRead(*object, *name, &lookup);
 
-  if (!lookup.IsValid()) {
+  if (!lookup.IsProperty()) {
     // If the object does not have the requested property, check which
     // exception we need to throw.
     if (IsContextual(object)) {
@@ -455,7 +456,7 @@
 
   if (result->IsJSFunction()) {
     // Check if there is an optimized (builtin) version of the function.
-    // Ignored this will degrade performance for Array.prototype.{push,pop}.
+    // Ignored this will degrade performance for some Array functions.
     // Please note we only return the optimized function iff
     // the JSObject has FastElements.
     if (object->IsJSObject() && JSObject::cast(*object)->HasFastElements()) {
@@ -492,7 +493,7 @@
                           Handle<Object> object,
                           Handle<String> name) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
 
   // Compute the number of arguments.
   int argc = target()->arguments_count();
@@ -641,8 +642,8 @@
   LookupResult lookup;
   LookupForRead(*object, *name, &lookup);
 
-  // If lookup is invalid, check if we need to throw an exception.
-  if (!lookup.IsValid()) {
+  // If we did not find a property, check if we need to throw an exception.
+  if (!lookup.IsProperty()) {
     if (FLAG_strict || IsContextual(object)) {
       return ReferenceError("not_defined", name);
     }
@@ -652,7 +653,7 @@
   bool can_be_inlined =
       FLAG_use_ic &&
       state == PREMONOMORPHIC &&
-      lookup.IsValid() &&
+      lookup.IsProperty() &&
       lookup.IsCacheable() &&
       lookup.holder() == *object &&
       lookup.type() == FIELD &&
@@ -679,7 +680,7 @@
   }
 
   PropertyAttributes attr;
-  if (lookup.IsValid() && lookup.type() == INTERCEPTOR) {
+  if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
     // Get the property.
     Object* result = object->GetProperty(*object, &lookup, *name, &attr);
     if (result->IsFailure()) return result;
@@ -701,7 +702,7 @@
                           Handle<Object> object,
                           Handle<String> name) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
 
   // Loading properties from values is not common, so don't try to
   // deal with non-JS objects here.
@@ -854,8 +855,8 @@
     LookupResult lookup;
     LookupForRead(*object, *name, &lookup);
 
-    // If lookup is invalid, check if we need to throw an exception.
-    if (!lookup.IsValid()) {
+    // If we did not find a property, check if we need to throw an exception.
+    if (!lookup.IsProperty()) {
       if (FLAG_strict || IsContextual(object)) {
         return ReferenceError("not_defined", name);
       }
@@ -866,7 +867,7 @@
     }
 
     PropertyAttributes attr;
-    if (lookup.IsValid() && lookup.type() == INTERCEPTOR) {
+    if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
       // Get the property.
       Object* result = object->GetProperty(*object, &lookup, *name, &attr);
       if (result->IsFailure()) return result;
@@ -893,6 +894,8 @@
       Handle<JSObject> receiver = Handle<JSObject>::cast(object);
       if (receiver->HasExternalArrayElements()) {
         stub = external_array_stub(receiver->GetElementsKind());
+      } else if (receiver->HasIndexedInterceptor()) {
+        stub = indexed_interceptor_stub();
       }
     }
     set_target(stub);
@@ -915,7 +918,7 @@
 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
                                Handle<Object> object, Handle<String> name) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
 
   if (!object->IsJSObject()) return;
   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
@@ -988,7 +991,7 @@
 
 static bool StoreICableLookup(LookupResult* lookup) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return false;
+  if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
 
   // If the property is read-only, we leave the IC in its current
   // state.
@@ -1203,7 +1206,7 @@
   if (receiver->IsJSGlobalProxy()) return;
 
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
 
   // If the property is read-only, we leave the IC in its current
   // state.
@@ -1311,16 +1314,6 @@
 }
 
 
-void LoadIC::GenerateInitialize(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
-}
-
-
-void LoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
-}
-
-
 // Used from ic_<arch>.cc
 Object* KeyedLoadIC_Miss(Arguments args) {
   NoHandleAllocation na;
@@ -1331,16 +1324,6 @@
 }
 
 
-void KeyedLoadIC::GenerateInitialize(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
-}
-
-
-void KeyedLoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
-}
-
-
 // Used from ic_<arch>.cc.
 Object* StoreIC_Miss(Arguments args) {
   NoHandleAllocation na;
@@ -1397,16 +1380,6 @@
 }
 
 
-void KeyedStoreIC::GenerateInitialize(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));
-}
-
-
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
-  Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));
-}
-
-
 static Address IC_utilities[] = {
 #define ADDR(name) FUNCTION_ADDR(name),
     IC_UTIL_LIST(ADDR)
diff --git a/src/ic.h b/src/ic.h
index a991e30..feff8c5 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -53,6 +53,7 @@
   ICU(LoadPropertyWithInterceptorOnly)                \
   ICU(LoadPropertyWithInterceptorForLoad)             \
   ICU(LoadPropertyWithInterceptorForCall)             \
+  ICU(KeyedLoadPropertyWithInterceptor)               \
   ICU(StoreInterceptorProperty)
 
 //
@@ -223,8 +224,10 @@
   Object* Load(State state, Handle<Object> object, Handle<String> name);
 
   // Code generator routines.
-  static void GenerateInitialize(MacroAssembler* masm);
-  static void GeneratePreMonomorphic(MacroAssembler* masm);
+  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
+  static void GeneratePreMonomorphic(MacroAssembler* masm) {
+    GenerateMiss(masm);
+  }
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateMegamorphic(MacroAssembler* masm);
   static void GenerateNormal(MacroAssembler* masm);
@@ -240,8 +243,6 @@
   static const int kOffsetToLoadInstruction;
 
  private:
-  static void Generate(MacroAssembler* masm, const ExternalReference& f);
-
   // Update the inline cache and the global stub cache based on the
   // lookup result.
   void UpdateCaches(LookupResult* lookup,
@@ -279,8 +280,11 @@
 
   // Code generator routines.
   static void GenerateMiss(MacroAssembler* masm);
-  static void GenerateInitialize(MacroAssembler* masm);
-  static void GeneratePreMonomorphic(MacroAssembler* masm);
+  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
+  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
+  static void GeneratePreMonomorphic(MacroAssembler* masm) {
+    GenerateMiss(masm);
+  }
   static void GenerateGeneric(MacroAssembler* masm);
   static void GenerateString(MacroAssembler* masm);
 
@@ -290,6 +294,7 @@
   // for all other types.
   static void GenerateExternalArray(MacroAssembler* masm,
                                     ExternalArrayType array_type);
+  static void GenerateIndexedInterceptor(MacroAssembler* masm);
 
   // Clear the use of the inlined version.
   static void ClearInlinedVersion(Address address);
@@ -302,8 +307,6 @@
   static const int kSlowCaseBitFieldMask =
       (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
 
-  static void Generate(MacroAssembler* masm, const ExternalReference& f);
-
   // Update the inline cache.
   void UpdateCaches(LookupResult* lookup,
                     State state,
@@ -328,6 +331,10 @@
   }
   static Code* external_array_stub(JSObject::ElementsKind elements_kind);
 
+  static Code* indexed_interceptor_stub() {
+    return Builtins::builtin(Builtins::KeyedLoadIC_IndexedInterceptor);
+  }
+
   static void Clear(Address address, Code* target);
 
   // Support for patching the map that is checked in an inlined
@@ -351,7 +358,6 @@
   static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateMegamorphic(MacroAssembler* masm);
-  static void GenerateExtendStorage(MacroAssembler* masm);
 
  private:
   // Update the inline cache and the global stub cache based on the
@@ -384,10 +390,10 @@
                 Handle<Object> value);
 
   // Code generators for stub routines.  Only called once at startup.
-  static void GenerateInitialize(MacroAssembler* masm);
+  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
   static void GenerateMiss(MacroAssembler* masm);
+  static void GenerateRuntimeSetProperty(MacroAssembler* masm);
   static void GenerateGeneric(MacroAssembler* masm);
-  static void GenerateExtendStorage(MacroAssembler* masm);
 
   // Generators for external array types. See objects.h.
   // These are similar to the generic IC; they optimize the case of
@@ -403,8 +409,6 @@
   static void RestoreInlinedVersion(Address address);
 
  private:
-  static void Generate(MacroAssembler* masm, const ExternalReference& f);
-
   // Update the inline cache.
   void UpdateCaches(LookupResult* lookup,
                     State state,
diff --git a/src/json-delay.js b/src/json-delay.js
deleted file mode 100644
index 7788f51..0000000
--- a/src/json-delay.js
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-var $JSON = global.JSON;
-
-function ParseJSONUnfiltered(text) {
-  var s = $String(text);
-  var f = %CompileString(text, true);
-  return f();
-}
-
-function Revive(holder, name, reviver) {
-  var val = holder[name];
-  if (IS_OBJECT(val)) {
-    if (IS_ARRAY(val)) {
-      var length = val.length;
-      for (var i = 0; i < length; i++) {
-        var newElement = Revive(val, $String(i), reviver);
-        val[i] = newElement;
-      }
-    } else {
-      for (var p in val) {
-        if (ObjectHasOwnProperty.call(val, p)) {
-          var newElement = Revive(val, p, reviver);
-          if (IS_UNDEFINED(newElement)) {
-            delete val[p];
-          } else {
-            val[p] = newElement;
-          }
-        }
-      }
-    }
-  }
-  return reviver.call(holder, name, val);
-}
-
-function JSONParse(text, reviver) {
-  var unfiltered = ParseJSONUnfiltered(text);
-  if (IS_FUNCTION(reviver)) {
-    return Revive({'': unfiltered}, '', reviver);
-  } else {
-    return unfiltered;
-  }
-}
-
-var characterQuoteCache = {
-  '\"': '\\"',
-  '\\': '\\\\',
-  '/': '\\/',
-  '\b': '\\b',
-  '\f': '\\f',
-  '\n': '\\n',
-  '\r': '\\r',
-  '\t': '\\t',
-  '\x0B': '\\u000b'
-};
-
-function QuoteSingleJSONCharacter(c) {
-  if (c in characterQuoteCache)
-    return characterQuoteCache[c];
-  var charCode = c.charCodeAt(0);
-  var result;
-  if (charCode < 16) result = '\\u000';
-  else if (charCode < 256) result = '\\u00';
-  else if (charCode < 4096) result = '\\u0';
-  else result = '\\u';
-  result += charCode.toString(16);
-  characterQuoteCache[c] = result;
-  return result;
-}
-
-function QuoteJSONString(str) {
-  var quotable = /[\\\"\x00-\x1f\x80-\uffff]/g;
-  return '"' + str.replace(quotable, QuoteSingleJSONCharacter) + '"';
-}
-
-function StackContains(stack, val) {
-  var length = stack.length;
-  for (var i = 0; i < length; i++) {
-    if (stack[i] === val)
-      return true;
-  }
-  return false;
-}
-
-function SerializeArray(value, replacer, stack, indent, gap) {
-  if (StackContains(stack, value))
-    throw MakeTypeError('circular_structure', []);
-  stack.push(value);
-  var stepback = indent;
-  indent += gap;
-  var partial = [];
-  var len = value.length;
-  for (var i = 0; i < len; i++) {
-    var strP = JSONSerialize($String(i), value, replacer, stack,
-        indent, gap);
-    if (IS_UNDEFINED(strP))
-      strP = "null";
-    partial.push(strP);
-  }
-  var final;
-  if (gap == "") {
-    final = "[" + partial.join(",") + "]";
-  } else if (partial.length > 0) {
-    var separator = ",\n" + indent;
-    final = "[\n" + indent + partial.join(separator) + "\n" +
-        stepback + "]";
-  } else {
-    final = "[]";
-  }
-  stack.pop();
-  return final;
-}
-
-function SerializeObject(value, replacer, stack, indent, gap) {
-  if (StackContains(stack, value))
-    throw MakeTypeError('circular_structure', []);
-  stack.push(value);
-  var stepback = indent;
-  indent += gap;
-  var partial = [];
-  if (IS_ARRAY(replacer)) {
-    var length = replacer.length;
-    for (var i = 0; i < length; i++) {
-      if (ObjectHasOwnProperty.call(replacer, i)) {
-        var p = replacer[i];
-        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
-        if (!IS_UNDEFINED(strP)) {
-          var member = QuoteJSONString(p) + ":";
-          if (gap != "") member += " ";
-          member += strP;
-          partial.push(member);
-        }
-      }
-    }
-  } else {
-    for (var p in value) {
-      if (ObjectHasOwnProperty.call(value, p)) {
-        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
-        if (!IS_UNDEFINED(strP)) {
-          var member = QuoteJSONString(p) + ":";
-          if (gap != "") member += " ";
-          member += strP;
-          partial.push(member);
-        }
-      }
-    }
-  }
-  var final;
-  if (gap == "") {
-    final = "{" + partial.join(",") + "}";
-  } else if (partial.length > 0) {
-    var separator = ",\n" + indent;
-    final = "{\n" + indent + partial.join(separator) + "\n" +
-        stepback + "}";
-  } else {
-    final = "{}";
-  }
-  stack.pop();
-  return final;
-}
-
-function JSONSerialize(key, holder, replacer, stack, indent, gap) {
-  var value = holder[key];
-  if (IS_OBJECT(value) && value) {
-    var toJSON = value.toJSON;
-    if (IS_FUNCTION(toJSON))
-      value = toJSON.call(value, key);
-  }
-  if (IS_FUNCTION(replacer))
-    value = replacer.call(holder, key, value);
-  // Unwrap value if necessary
-  if (IS_OBJECT(value)) {
-    if (IS_NUMBER_WRAPPER(value)) {
-      value = $Number(value);
-    } else if (IS_STRING_WRAPPER(value)) {
-      value = $String(value);
-    }
-  }
-  switch (typeof value) {
-    case "string":
-      return QuoteJSONString(value);
-    case "object":
-      if (!value) {
-        return "null";
-      } else if (IS_ARRAY(value)) {
-        return SerializeArray(value, replacer, stack, indent, gap);
-      } else {
-        return SerializeObject(value, replacer, stack, indent, gap);
-      }
-    case "number":
-      return $isFinite(value) ? $String(value) : "null";
-    case "boolean":
-      return value ? "true" : "false";
-  }
-}
-
-function JSONStringify(value, replacer, space) {
-  var stack = [];
-  var indent = "";
-  if (IS_OBJECT(space)) {
-    // Unwrap 'space' if it is wrapped
-    if (IS_NUMBER_WRAPPER(space)) {
-      space = $Number(space);
-    } else if (IS_STRING_WRAPPER(space)) {
-      space = $String(space);
-    }
-  }
-  var gap;
-  if (IS_NUMBER(space)) {
-    space = $Math.min(space, 100);
-    gap = "";
-    for (var i = 0; i < space; i++)
-      gap += " ";
-  } else if (IS_STRING(space)) {
-    gap = space;
-  } else {
-    gap = "";
-  }
-  return JSONSerialize('', {'': value}, replacer, stack, indent, gap);
-}
-
-function SetupJSON() {
-  InstallFunctions($JSON, DONT_ENUM, $Array(
-    "parse", JSONParse,
-    "stringify", JSONStringify
-  ));
-}
-
-SetupJSON();
diff --git a/src/jump-target-inl.h b/src/jump-target-inl.h
index 1f0676d..3cd9a8b 100644
--- a/src/jump-target-inl.h
+++ b/src/jump-target-inl.h
@@ -42,6 +42,9 @@
   } else if (target->is_copy()) {
     entry_frame_->elements_[target->index()].set_copied();
   }
+  if (direction_ == BIDIRECTIONAL && !target->is_copy()) {
+    entry_frame_->elements_[index].set_number_info(NumberInfo::kUnknown);
+  }
 }
 
 } }  // namespace v8::internal
diff --git a/src/jump-target.cc b/src/jump-target.cc
index 3782f92..bce379a 100644
--- a/src/jump-target.cc
+++ b/src/jump-target.cc
@@ -101,6 +101,16 @@
         if (element == NULL || !element->is_valid()) break;
 
         element = element->Combine(&reaching_frames_[j]->elements_[i]);
+
+        FrameElement* other = &reaching_frames_[j]->elements_[i];
+        if (element != NULL && !element->is_copy()) {
+          ASSERT(other != NULL);
+          // We overwrite the number information of one of the incoming frames.
+          // This is safe because we only use the frame for emitting merge code.
+          // The number information of incoming frames is not used anymore.
+          element->set_number_info(NumberInfo::Combine(element->number_info(),
+                                                       other->number_info()));
+        }
       }
       elements[i] = element;
     }
@@ -125,7 +135,8 @@
   for (; index < length; index++) {
     FrameElement* target = elements[index];
     if (target == NULL) {
-      entry_frame_->elements_.Add(FrameElement::MemoryElement());
+      entry_frame_->elements_.Add(
+          FrameElement::MemoryElement(NumberInfo::kUninitialized));
     } else {
       entry_frame_->elements_.Add(*target);
       InitializeEntryElement(index, target);
@@ -142,9 +153,20 @@
       RegisterFile candidate_registers;
       int best_count = kMinInt;
       int best_reg_num = RegisterAllocator::kInvalidRegister;
+      NumberInfo::Type info = NumberInfo::kUninitialized;
 
       for (int j = 0; j < reaching_frames_.length(); j++) {
         FrameElement element = reaching_frames_[j]->elements_[i];
+        if (direction_ == BIDIRECTIONAL) {
+            info = NumberInfo::kUnknown;
+        } else if (!element.is_copy()) {
+          info = NumberInfo::Combine(info, element.number_info());
+        } else {
+          // New elements will not be copies, so get number information from
+          // backing element in the reaching frame.
+          info = NumberInfo::Combine(info,
+            reaching_frames_[j]->elements_[element.index()].number_info());
+        }
         is_synced = is_synced && element.is_synced();
         if (element.is_register() && !entry_frame_->is_used(element.reg())) {
           // Count the register occurrence and remember it if better
@@ -158,11 +180,17 @@
         }
       }
 
+      // We must have a number type information now (not for copied elements).
+      ASSERT(entry_frame_->elements_[i].is_copy()
+             || info != NumberInfo::kUninitialized);
+
       // If the value is synced on all frames, put it in memory.  This
       // costs nothing at the merge code but will incur a
       // memory-to-register move when the value is needed later.
       if (is_synced) {
         // Already recorded as a memory element.
+        // Set combined number info.
+        entry_frame_->elements_[i].set_number_info(info);
         continue;
       }
 
@@ -183,14 +211,28 @@
         bool is_copied = entry_frame_->elements_[i].is_copied();
         Register reg = RegisterAllocator::ToRegister(best_reg_num);
         entry_frame_->elements_[i] =
-            FrameElement::RegisterElement(reg,
-                                          FrameElement::NOT_SYNCED);
+            FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED,
+                                          NumberInfo::kUninitialized);
         if (is_copied) entry_frame_->elements_[i].set_copied();
         entry_frame_->set_register_location(reg, i);
       }
+      // Set combined number info.
+      entry_frame_->elements_[i].set_number_info(info);
     }
   }
 
+  // If we have incoming backward edges assert we forget all number information.
+#ifdef DEBUG
+  if (direction_ == BIDIRECTIONAL) {
+    for (int i = 0; i < length; ++i) {
+      if (!entry_frame_->elements_[i].is_copy()) {
+        ASSERT(entry_frame_->elements_[i].number_info() ==
+               NumberInfo::kUnknown);
+      }
+    }
+  }
+#endif
+
   // The stack pointer is at the highest synced element or the base of
   // the expression stack.
   int stack_pointer = length - 1;
diff --git a/src/liveedit.cc b/src/liveedit.cc
new file mode 100644
index 0000000..c50e007
--- /dev/null
+++ b/src/liveedit.cc
@@ -0,0 +1,87 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#include "v8.h"
+
+#include "liveedit.h"
+#include "compiler.h"
+#include "oprofile-agent.h"
+#include "scopes.h"
+#include "global-handles.h"
+#include "debug.h"
+
+namespace v8 {
+namespace internal {
+
+
+class FunctionInfoListener {
+ public:
+  void FunctionStarted(FunctionLiteral* fun) {
+    // Implementation follows.
+  }
+
+  void FunctionDone() {
+    // Implementation follows.
+  }
+
+  void FunctionScope(Scope* scope) {
+    // Implementation follows.
+  }
+
+  void FunctionCode(Handle<Code> function_code) {
+    // Implementation follows.
+  }
+};
+
+static FunctionInfoListener* active_function_info_listener = NULL;
+
+LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) {
+  if (active_function_info_listener != NULL) {
+    active_function_info_listener->FunctionStarted(fun);
+  }
+}
+LiveEditFunctionTracker::~LiveEditFunctionTracker() {
+  if (active_function_info_listener != NULL) {
+    active_function_info_listener->FunctionDone();
+  }
+}
+void LiveEditFunctionTracker::RecordFunctionCode(Handle<Code> code) {
+  if (active_function_info_listener != NULL) {
+    active_function_info_listener->FunctionCode(code);
+  }
+}
+void LiveEditFunctionTracker::RecordFunctionScope(Scope* scope) {
+  if (active_function_info_listener != NULL) {
+    active_function_info_listener->FunctionScope(scope);
+  }
+}
+bool LiveEditFunctionTracker::IsActive() {
+  return active_function_info_listener != NULL;
+}
+
+} }  // namespace v8::internal
diff --git a/src/liveedit.h b/src/liveedit.h
new file mode 100644
index 0000000..73aa7d3
--- /dev/null
+++ b/src/liveedit.h
@@ -0,0 +1,78 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_LIVEEDIT_H_
+#define V8_LIVEEDIT_H_
+
+
+
+// Live Edit feature implementation.
+// User should be able to change script on already running VM. This feature
+// matches hot swap features in other frameworks.
+//
+// The basic use-case is when user spots some mistake in function body
+// from debugger and wishes to change the algorithm without restart.
+//
+// A single change always has a form of a simple replacement (in pseudo-code):
+//   script.source[positions, positions+length] = new_string;
+// Implementation first determines, which function's body includes this
+// change area. Then both old and new versions of script are fully compiled
+// in order to analyze, whether the function changed its outer scope
+// expectations (or number of parameters). If it didn't, function's code is
+// patched with a newly compiled code. If it did change, enclosing function
+// gets patched. All inner functions are left untouched, whatever happened
+// to them in a new script version. However, new version of code will
+// instantiate newly compiled functions.
+
+
+#include "compiler.h"
+
+namespace v8 {
+namespace internal {
+
+// This class collects some specific information on structure of functions
+// in a particular script. It gets called from compiler all the time, but
+// actually records any data only when liveedit operation is in process;
+// in any other time this class is very cheap.
+//
+// The primary interest of the Tracker is to record function scope structures
+// in order to analyze whether function code maybe safely patched (with new
+// code successfully reading existing data from function scopes). The Tracker
+// also collects compiled function codes.
+class LiveEditFunctionTracker {
+ public:
+  explicit LiveEditFunctionTracker(FunctionLiteral* fun);
+  ~LiveEditFunctionTracker();
+  void RecordFunctionCode(Handle<Code> code);
+  void RecordFunctionScope(Scope* scope);
+
+  static bool IsActive();
+};
+
+} }  // namespace v8::internal
+
+#endif /* V*_LIVEEDIT_H_ */
diff --git a/src/log-utils.cc b/src/log-utils.cc
index fd95604..722e0fc 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -351,15 +351,6 @@
 }
 
 
-void LogMessageBuilder::WriteCStringToLogFile(const char* str) {
-  const int len = StrLength(str);
-  const int written = Log::Write(str, len);
-  if (written != len && write_failure_handler != NULL) {
-    write_failure_handler();
-  }
-}
-
-
 // Formatting string for back references to the whole line. E.g. "#2" means
 // "the second line above".
 const char* LogRecordCompressor::kLineBackwardReferenceFormat = "#%d";
diff --git a/src/log-utils.h b/src/log-utils.h
index 3e25b0e..b769e90 100644
--- a/src/log-utils.h
+++ b/src/log-utils.h
@@ -268,9 +268,6 @@
   // Write the log message to the log file currently opened.
   void WriteToLogFile();
 
-  // Write a null-terminated string to to the log file currently opened.
-  void WriteCStringToLogFile(const char* str);
-
   // A handler that is called when Log::Write fails.
   typedef void (*WriteFailureHandler)();
 
diff --git a/src/log.cc b/src/log.cc
index cf2fc97..a3fef73 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -330,6 +330,8 @@
 const char** Logger::log_events_ = NULL;
 CompressionHelper* Logger::compression_helper_ = NULL;
 bool Logger::is_logging_ = false;
+int Logger::cpu_profiler_nesting_ = 0;
+int Logger::heap_profiler_nesting_ = 0;
 
 #define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name,
 const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
@@ -368,15 +370,6 @@
 #endif  // ENABLE_LOGGING_AND_PROFILING
 
 
-void Logger::Preamble(const char* content) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!Log::IsEnabled() || !FLAG_log_code) return;
-  LogMessageBuilder msg;
-  msg.WriteCStringToLogFile(content);
-#endif
-}
-
-
 void Logger::StringEvent(const char* name, const char* value) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedStringEvent(name, value);
@@ -573,20 +566,6 @@
 }
 
 
-void Logger::LogProfileMarker(Vector<const char> marker) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!Log::IsEnabled() || !FLAG_prof) return;
-  LogMessageBuilder msg;
-  for (int i = 0; i < marker.length(); i++) {
-    char c = marker[i];
-    msg.Append(c);
-  }
-  msg.Append('\n');
-  msg.WriteToLogFile();
-#endif
-}
-
-
 void Logger::ApiIndexedSecurityCheck(uint32_t index) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!Log::IsEnabled() || !FLAG_log_api) return;
@@ -1178,53 +1157,61 @@
 }
 
 
-void Logger::PauseProfiler(int flags) {
+void Logger::PauseProfiler(int flags, int tag) {
   if (!Log::IsEnabled()) return;
-  const int active_modules = GetActiveProfilerModules();
-  const int modules_to_disable = active_modules & flags;
-  if (modules_to_disable == PROFILER_MODULE_NONE) return;
-
-  if (modules_to_disable & PROFILER_MODULE_CPU) {
-    profiler_->pause();
-    if (FLAG_prof_lazy) {
-      if (!FLAG_sliding_state_window) ticker_->Stop();
-      FLAG_log_code = false;
-      // Must be the same message as Log::kDynamicBufferSeal.
-      LOG(UncheckedStringEvent("profiler", "pause"));
+  if (flags & PROFILER_MODULE_CPU) {
+    // It is OK to have negative nesting.
+    if (--cpu_profiler_nesting_ == 0) {
+      profiler_->pause();
+      if (FLAG_prof_lazy) {
+        if (!FLAG_sliding_state_window) ticker_->Stop();
+        FLAG_log_code = false;
+        // Must be the same message as Log::kDynamicBufferSeal.
+        LOG(UncheckedStringEvent("profiler", "pause"));
+      }
     }
   }
-  if (modules_to_disable &
+  if (flags &
       (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
-    FLAG_log_gc = false;
+    if (--heap_profiler_nesting_ == 0) {
+      FLAG_log_gc = false;
+    }
   }
-  // Turn off logging if no active modules remain.
-  if ((active_modules & ~flags) == PROFILER_MODULE_NONE) {
+  if (tag != 0) {
+    IntEvent("close-tag", tag);
+  }
+  if (GetActiveProfilerModules() == PROFILER_MODULE_NONE) {
     is_logging_ = false;
   }
 }
 
 
-void Logger::ResumeProfiler(int flags) {
+void Logger::ResumeProfiler(int flags, int tag) {
   if (!Log::IsEnabled()) return;
-  const int modules_to_enable = ~GetActiveProfilerModules() & flags;
-  if (modules_to_enable != PROFILER_MODULE_NONE) {
-    is_logging_ = true;
+  if (tag != 0) {
+    IntEvent("open-tag", tag);
   }
-  if (modules_to_enable & PROFILER_MODULE_CPU) {
-    if (FLAG_prof_lazy) {
-      profiler_->Engage();
-      LOG(UncheckedStringEvent("profiler", "resume"));
-      FLAG_log_code = true;
-      LogCompiledFunctions();
-      LogFunctionObjects();
-      LogAccessorCallbacks();
-      if (!FLAG_sliding_state_window) ticker_->Start();
+  if (flags & PROFILER_MODULE_CPU) {
+    if (cpu_profiler_nesting_++ == 0) {
+      is_logging_ = true;
+      if (FLAG_prof_lazy) {
+        profiler_->Engage();
+        LOG(UncheckedStringEvent("profiler", "resume"));
+        FLAG_log_code = true;
+        LogCompiledFunctions();
+        LogFunctionObjects();
+        LogAccessorCallbacks();
+        if (!FLAG_sliding_state_window) ticker_->Start();
+      }
+      profiler_->resume();
     }
-    profiler_->resume();
   }
-  if (modules_to_enable &
+  if (flags &
       (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
-    FLAG_log_gc = true;
+    if (heap_profiler_nesting_++ == 0) {
+      is_logging_ = true;
+      FLAG_log_gc = true;
+    }
   }
 }
 
@@ -1233,7 +1220,7 @@
 // either from main or Profiler's thread.
 void Logger::StopLoggingAndProfiling() {
   Log::stop();
-  PauseProfiler(PROFILER_MODULE_CPU);
+  PauseProfiler(PROFILER_MODULE_CPU, 0);
 }
 
 
diff --git a/src/log.h b/src/log.h
index ae1e4be..eb8369c 100644
--- a/src/log.h
+++ b/src/log.h
@@ -161,12 +161,6 @@
   // Enable the computation of a sliding window of states.
   static void EnableSlidingStateWindow();
 
-  // Write a raw string to the log to be used as a preamble.
-  // No check is made that the 'preamble' is actually at the beginning
-  // of the log. The preample is used to write code events saved in the
-  // snapshot.
-  static void Preamble(const char* content);
-
   // Emits an event with a string value -> (name, value).
   static void StringEvent(const char* name, const char* value);
 
@@ -265,9 +259,6 @@
   // Log an event reported from generated code
   static void LogRuntime(Vector<const char> format, JSArray* args);
 
-  // Log a profiling marker.
-  static void LogProfileMarker(Vector<const char> marker);
-
 #ifdef ENABLE_LOGGING_AND_PROFILING
   static StateTag state() {
     return current_state_ ? current_state_->state() : OTHER;
@@ -280,8 +271,8 @@
   // Pause/Resume collection of profiling data.
   // When data collection is paused, CPU Tick events are discarded until
   // data collection is Resumed.
-  static void PauseProfiler(int flags);
-  static void ResumeProfiler(int flags);
+  static void PauseProfiler(int flags, int tag);
+  static void ResumeProfiler(int flags, int tag);
   static int GetActiveProfilerModules();
 
   // If logging is performed into a memory buffer, allows to
@@ -382,6 +373,8 @@
   friend class LoggerTestHelper;
 
   static bool is_logging_;
+  static int cpu_profiler_nesting_;
+  static int heap_profiler_nesting_;
 #else
   static bool is_logging() { return false; }
 #endif
diff --git a/src/macro-assembler.h b/src/macro-assembler.h
index e33148c..81e5bf7 100644
--- a/src/macro-assembler.h
+++ b/src/macro-assembler.h
@@ -61,6 +61,8 @@
   RESULT_CONTAINS_TOP = 1 << 1
 };
 
+// Invalid depth in prototype chain.
+const int kInvalidProtoDepth = -1;
 
 #if V8_TARGET_ARCH_IA32
 #include "assembler.h"
diff --git a/src/macros.py b/src/macros.py
index 537113c..4751933 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -74,6 +74,10 @@
 const kMonthShift         = 5;
 
 # Type query macros.
+#
+# Note: We have special support for typeof(foo) === 'bar' in the compiler.
+#       It will *not* generate a runtime typeof call for the most important
+#       values of 'bar'.
 macro IS_NULL(arg)              = (arg === null);
 macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
 macro IS_UNDEFINED(arg)         = (typeof(arg) === 'undefined');
@@ -83,7 +87,7 @@
 macro IS_OBJECT(arg)            = (%_IsObject(arg));
 macro IS_ARRAY(arg)             = (%_IsArray(arg));
 macro IS_FUNCTION(arg)          = (%_IsFunction(arg));
-macro IS_REGEXP(arg)            = (%_ClassOf(arg) === 'RegExp');
+macro IS_REGEXP(arg)            = (%_IsRegExp(arg));
 macro IS_DATE(arg)              = (%_ClassOf(arg) === 'Date');
 macro IS_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
 macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
@@ -97,9 +101,11 @@
 
 # Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
 macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
-macro TO_INTEGER(arg)    = (%_IsSmi(%IS_VAR(arg)) ? arg : ToInteger(arg));
-macro TO_INT32(arg)      = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
-macro TO_UINT32(arg)     = (arg >>> 0);
+macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : ToInteger(arg));
+macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
+macro TO_UINT32(arg) = (arg >>> 0);
+macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg));
+
 
 # Macros implemented in Python.
 python macro CHAR_CODE(str) = ord(str[1]);
diff --git a/src/math.js b/src/math.js
index d804648..4c9de67 100644
--- a/src/math.js
+++ b/src/math.js
@@ -84,7 +84,7 @@
 // ECMA 262 - 15.8.2.7
 function MathCos(x) {
   if (!IS_NUMBER(x)) x = ToNumber(x);
-  return %Math_cos(x);
+  return %_Math_cos(x);
 }
 
 // ECMA 262 - 15.8.2.8
@@ -176,7 +176,7 @@
 // ECMA 262 - 15.8.2.16
 function MathSin(x) {
   if (!IS_NUMBER(x)) x = ToNumber(x);
-  return %Math_sin(x);
+  return %_Math_sin(x);
 }
 
 // ECMA 262 - 15.8.2.17
@@ -233,7 +233,7 @@
                "SQRT2",
                1.4142135623730951,
                DONT_ENUM |  DONT_DELETE | READ_ONLY);
-  %TransformToFastProperties($Math);
+  %ToFastProperties($Math);
 
   // Setup non-enumerable functions of the Math object and
   // set their names.
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 5a27c28..2de45f6 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -305,6 +305,11 @@
 }
 
 
+void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
+  UNIMPLEMENTED_MIPS();
+}
+
+
 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
   UNIMPLEMENTED_MIPS();
 }
@@ -365,6 +370,11 @@
 }
 
 
+void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
+  UNIMPLEMENTED_MIPS();
+}
+
+
 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
   UNIMPLEMENTED_MIPS();
 }
@@ -498,4 +508,3 @@
 #undef __
 
 } }  // namespace v8::internal
-
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 05138bc..147b872 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -210,6 +210,7 @@
   void GenerateIsSmi(ZoneList<Expression*>* args);
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
+  void GenerateIsRegExp(ZoneList<Expression*>* args);
 
   // Support for construct call checks.
   void GenerateIsConstructCall(ZoneList<Expression*>* args);
@@ -241,6 +242,8 @@
   void GenerateSubString(ZoneList<Expression*>* args);
   void GenerateStringCompare(ZoneList<Expression*>* args);
   void GenerateRegExpExec(ZoneList<Expression*>* args);
+  void GenerateNumberToString(ZoneList<Expression*>* args);
+
 
   // Fast support for Math.sin and Math.cos.
   inline void GenerateMathSin(ZoneList<Expression*>* args);
@@ -308,4 +311,3 @@
 } }  // namespace v8::internal
 
 #endif  // V8_MIPS_CODEGEN_MIPS_H_
-
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 3b34797..dfe297b 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -546,14 +546,16 @@
   return this.value_.length;
 };
 
+StringMirror.prototype.getTruncatedValue = function(maxLength) {
+  if (maxLength != -1 && this.length() > maxLength) {
+    return this.value_.substring(0, maxLength) +
+           '... (length: ' + this.length() + ')';
+  }
+  return this.value_;
+}
 
 StringMirror.prototype.toText = function() {
-  if (this.length() > kMaxProtocolStringLength) {
-    return this.value_.substring(0, kMaxProtocolStringLength) +
-           '... (length: ' + this.length() + ')';
-  } else {
-    return this.value_;
-  }
+  return this.getTruncatedValue(kMaxProtocolStringLength);
 }
 
 
@@ -1726,7 +1728,8 @@
 
 
 ScriptMirror.prototype.name = function() {
-  return this.script_.name;
+  // If we have name, we trust it more than sourceURL from comments
+  return this.script_.name || this.sourceUrlFromComment_();
 };
 
 
@@ -1822,6 +1825,29 @@
 
 
 /**
+ * Returns a suggested script URL from comments in script code (if found), 
+ * undefined otherwise. Used primarily by debuggers for identifying eval()'ed
+ * scripts. See 
+ * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
+ * for details.
+ * 
+ * @return {?string} value for //@ sourceURL comment
+ */
+ScriptMirror.prototype.sourceUrlFromComment_ = function() {
+  if (!('sourceUrl_' in this) && this.source()) {
+    // TODO(608): the spaces in a regexp below had to be escaped as \040 
+    // because this file is being processed by js2c whose handling of spaces
+    // in regexps is broken.
+    // We're not using \s here to prevent \n from matching.
+    var sourceUrlPattern = /\/\/@[\040\t]sourceURL=[\040\t]*(\S+)[\040\t]*$/m;
+    var match = sourceUrlPattern.exec(this.source());
+    this.sourceUrl_ = match ? match[1] : undefined;
+  }
+  return this.sourceUrl_;
+};
+
+
+/**
  * Mirror object for context.
  * @param {Object} data The context data
  * @constructor
@@ -1924,6 +1950,15 @@
 }
 
 
+JSONProtocolSerializer.prototype.maxStringLength_ = function() {
+  if (IS_UNDEFINED(this.options_) ||
+      IS_UNDEFINED(this.options_.maxStringLength)) {
+    return kMaxProtocolStringLength;
+  }
+  return this.options_.maxStringLength;
+}
+
+
 JSONProtocolSerializer.prototype.add_ = function(mirror) {
   // If this mirror is already in the list just return.
   for (var i = 0; i < this.mirrors_.length; i++) {
@@ -1956,8 +1991,7 @@
       o.value = mirror.value();
       break;
     case STRING_TYPE:
-      // Limit string length.
-      o.value = mirror.toText();
+      o.value = mirror.getTruncatedValue(this.maxStringLength_());
       break;
     case FUNCTION_TYPE:
       o.name = mirror.name();
@@ -2021,11 +2055,12 @@
 
     case STRING_TYPE:
       // String values might have their value cropped to keep down size.
-      if (mirror.length() > kMaxProtocolStringLength) {
-        var str = mirror.value().substring(0, kMaxProtocolStringLength);
+      if (this.maxStringLength_() != -1 &&
+          mirror.length() > this.maxStringLength_()) {
+        var str = mirror.getTruncatedValue(this.maxStringLength_());
         content.value = str;
         content.fromIndex = 0;
-        content.toIndex = kMaxProtocolStringLength;
+        content.toIndex = this.maxStringLength_();
       } else {
         content.value = mirror.value();
       }
diff --git a/src/mirror-delay.js b/src/mirror-delay.js
deleted file mode 100644
index 1487ce5..0000000
--- a/src/mirror-delay.js
+++ /dev/null
@@ -1,2334 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Touch the RegExp and Date functions to make sure that date-delay.js and
-// regexp-delay.js has been loaded. This is required as the mirrors use
-// functions within these files through the builtins object.
-RegExp;
-Date;
-
-
-// Handle id counters.
-var next_handle_ = 0;
-var next_transient_handle_ = -1;
-
-// Mirror cache.
-var mirror_cache_ = [];
-
-
-/**
- * Clear the mirror handle cache.
- */
-function ClearMirrorCache() {
-  next_handle_ = 0;
-  mirror_cache_ = [];
-}
-
-
-/**
- * Returns the mirror for a specified value or object.
- *
- * @param {value or Object} value the value or object to retreive the mirror for
- * @param {boolean} transient indicate whether this object is transient and
- *    should not be added to the mirror cache. The default is not transient.
- * @returns {Mirror} the mirror reflects the passed value or object
- */
-function MakeMirror(value, opt_transient) {
-  var mirror;
-
-  // Look for non transient mirrors in the mirror cache.
-  if (!opt_transient) {
-    for (id in mirror_cache_) {
-      mirror = mirror_cache_[id];
-      if (mirror.value() === value) {
-        return mirror;
-      }
-      // Special check for NaN as NaN == NaN is false.
-      if (mirror.isNumber() && isNaN(mirror.value()) &&
-          typeof value == 'number' && isNaN(value)) {
-        return mirror;
-      }
-    }
-  }
-  
-  if (IS_UNDEFINED(value)) {
-    mirror = new UndefinedMirror();
-  } else if (IS_NULL(value)) {
-    mirror = new NullMirror();
-  } else if (IS_BOOLEAN(value)) {
-    mirror = new BooleanMirror(value);
-  } else if (IS_NUMBER(value)) {
-    mirror = new NumberMirror(value);
-  } else if (IS_STRING(value)) {
-    mirror = new StringMirror(value);
-  } else if (IS_ARRAY(value)) {
-    mirror = new ArrayMirror(value);
-  } else if (IS_DATE(value)) {
-    mirror = new DateMirror(value);
-  } else if (IS_FUNCTION(value)) {
-    mirror = new FunctionMirror(value);
-  } else if (IS_REGEXP(value)) {
-    mirror = new RegExpMirror(value);
-  } else if (IS_ERROR(value)) {
-    mirror = new ErrorMirror(value);
-  } else if (IS_SCRIPT(value)) {
-    mirror = new ScriptMirror(value);
-  } else {
-    mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
-  }
-
-  mirror_cache_[mirror.handle()] = mirror;
-  return mirror;
-}
-
-
-/**
- * Returns the mirror for a specified mirror handle.
- *
- * @param {number} handle the handle to find the mirror for
- * @returns {Mirror or undefiend} the mirror with the requested handle or
- *     undefined if no mirror with the requested handle was found
- */
-function LookupMirror(handle) {
-  return mirror_cache_[handle];
-}
-
-  
-/**
- * Returns the mirror for the undefined value.
- *
- * @returns {Mirror} the mirror reflects the undefined value
- */
-function GetUndefinedMirror() {
-  return MakeMirror(void 0);
-}
-
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be revritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- *     prototype
- * @param {function} superCtor Constructor function to inherit prototype from
- */
-function inherits(ctor, superCtor) {
-  var tempCtor = function(){};
-  tempCtor.prototype = superCtor.prototype;
-  ctor.super_ = superCtor.prototype;
-  ctor.prototype = new tempCtor();
-  ctor.prototype.constructor = ctor;
-}
-
-
-// Type names of the different mirrors.
-const UNDEFINED_TYPE = 'undefined';
-const NULL_TYPE = 'null';
-const BOOLEAN_TYPE = 'boolean';
-const NUMBER_TYPE = 'number';
-const STRING_TYPE = 'string';
-const OBJECT_TYPE = 'object';
-const FUNCTION_TYPE = 'function';
-const REGEXP_TYPE = 'regexp';
-const ERROR_TYPE = 'error';
-const PROPERTY_TYPE = 'property';
-const FRAME_TYPE = 'frame';
-const SCRIPT_TYPE = 'script';
-const CONTEXT_TYPE = 'context';
-const SCOPE_TYPE = 'scope';
-
-// Maximum length when sending strings through the JSON protocol.
-const kMaxProtocolStringLength = 80;
-
-// Different kind of properties.
-PropertyKind = {};
-PropertyKind.Named   = 1;
-PropertyKind.Indexed = 2;
-
-
-// A copy of the PropertyType enum from global.h
-PropertyType = {};
-PropertyType.Normal             = 0;
-PropertyType.Field              = 1;
-PropertyType.ConstantFunction   = 2;
-PropertyType.Callbacks          = 3;
-PropertyType.Interceptor        = 4;
-PropertyType.MapTransition      = 5;
-PropertyType.ConstantTransition = 6;
-PropertyType.NullDescriptor     = 7;
-
-
-// Different attributes for a property.
-PropertyAttribute = {};
-PropertyAttribute.None       = NONE;
-PropertyAttribute.ReadOnly   = READ_ONLY;
-PropertyAttribute.DontEnum   = DONT_ENUM;
-PropertyAttribute.DontDelete = DONT_DELETE;
-
-
-// A copy of the scope types from runtime.cc.
-ScopeType = { Global: 0,
-              Local: 1,
-              With: 2,
-              Closure: 3,
-              Catch: 4 };
-
-
-// Mirror hierarchy:
-//   - Mirror
-//     - ValueMirror
-//       - UndefinedMirror
-//       - NullMirror
-//       - NumberMirror
-//       - StringMirror
-//       - ObjectMirror
-//         - FunctionMirror
-//           - UnresolvedFunctionMirror
-//         - ArrayMirror
-//         - DateMirror
-//         - RegExpMirror
-//         - ErrorMirror
-//     - PropertyMirror
-//     - FrameMirror
-//     - ScriptMirror
-
-
-/**
- * Base class for all mirror objects.
- * @param {string} type The type of the mirror
- * @constructor
- */
-function Mirror(type) {
-  this.type_ = type;
-};
-
-
-Mirror.prototype.type = function() {
-  return this.type_;
-};
-
-
-/**
- * Check whether the mirror reflects a value.
- * @returns {boolean} True if the mirror reflects a value.
- */
-Mirror.prototype.isValue = function() {
-  return this instanceof ValueMirror;
-}
-
-
-/**
- * Check whether the mirror reflects the undefined value.
- * @returns {boolean} True if the mirror reflects the undefined value.
- */
-Mirror.prototype.isUndefined = function() {
-  return this instanceof UndefinedMirror;
-}
-
-
-/**
- * Check whether the mirror reflects the null value.
- * @returns {boolean} True if the mirror reflects the null value
- */
-Mirror.prototype.isNull = function() {
-  return this instanceof NullMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a boolean value.
- * @returns {boolean} True if the mirror reflects a boolean value
- */
-Mirror.prototype.isBoolean = function() {
-  return this instanceof BooleanMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a number value.
- * @returns {boolean} True if the mirror reflects a number value
- */
-Mirror.prototype.isNumber = function() {
-  return this instanceof NumberMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a string value.
- * @returns {boolean} True if the mirror reflects a string value
- */
-Mirror.prototype.isString = function() {
-  return this instanceof StringMirror;
-}
-
-
-/**
- * Check whether the mirror reflects an object.
- * @returns {boolean} True if the mirror reflects an object
- */
-Mirror.prototype.isObject = function() {
-  return this instanceof ObjectMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a function.
- * @returns {boolean} True if the mirror reflects a function
- */
-Mirror.prototype.isFunction = function() {
-  return this instanceof FunctionMirror;
-}
-
-
-/**
- * Check whether the mirror reflects an unresolved function.
- * @returns {boolean} True if the mirror reflects an unresolved function
- */
-Mirror.prototype.isUnresolvedFunction = function() {
-  return this instanceof UnresolvedFunctionMirror;
-}
-
-
-/**
- * Check whether the mirror reflects an array.
- * @returns {boolean} True if the mirror reflects an array
- */
-Mirror.prototype.isArray = function() {
-  return this instanceof ArrayMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a date.
- * @returns {boolean} True if the mirror reflects a date
- */
-Mirror.prototype.isDate = function() {
-  return this instanceof DateMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a regular expression.
- * @returns {boolean} True if the mirror reflects a regular expression
- */
-Mirror.prototype.isRegExp = function() {
-  return this instanceof RegExpMirror;
-}
-
-
-/**
- * Check whether the mirror reflects an error.
- * @returns {boolean} True if the mirror reflects an error
- */
-Mirror.prototype.isError = function() {
-  return this instanceof ErrorMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a property.
- * @returns {boolean} True if the mirror reflects a property
- */
-Mirror.prototype.isProperty = function() {
-  return this instanceof PropertyMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a stack frame.
- * @returns {boolean} True if the mirror reflects a stack frame
- */
-Mirror.prototype.isFrame = function() {
-  return this instanceof FrameMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a script.
- * @returns {boolean} True if the mirror reflects a script
- */
-Mirror.prototype.isScript = function() {
-  return this instanceof ScriptMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a context.
- * @returns {boolean} True if the mirror reflects a context
- */
-Mirror.prototype.isContext = function() {
-  return this instanceof ContextMirror;
-}
-
-
-/**
- * Check whether the mirror reflects a scope.
- * @returns {boolean} True if the mirror reflects a scope
- */
-Mirror.prototype.isScope = function() {
-  return this instanceof ScopeMirror;
-}
-
-
-/**
- * Allocate a handle id for this object.
- */
-Mirror.prototype.allocateHandle_ = function() {
-  this.handle_ = next_handle_++;
-}
-
-
-/**
- * Allocate a transient handle id for this object. Transient handles are
- * negative.
- */
-Mirror.prototype.allocateTransientHandle_ = function() {
-  this.handle_ = next_transient_handle_--;
-}
-
-
-Mirror.prototype.toText = function() {
-  // Simpel to text which is used when on specialization in subclass.
-  return "#<" + builtins.GetInstanceName(this.constructor.name) + ">";
-}
-
-
-/**
- * Base class for all value mirror objects.
- * @param {string} type The type of the mirror
- * @param {value} value The value reflected by this mirror
- * @param {boolean} transient indicate whether this object is transient with a
- *    transient handle
- * @constructor
- * @extends Mirror
- */
-function ValueMirror(type, value, transient) {
-  Mirror.call(this, type);
-  this.value_ = value;
-  if (!transient) {
-    this.allocateHandle_();
-  } else {
-    this.allocateTransientHandle_();
-  }
-}
-inherits(ValueMirror, Mirror);
-
-
-Mirror.prototype.handle = function() {
-  return this.handle_;
-};
-
-
-/**
- * Check whether this is a primitive value.
- * @return {boolean} True if the mirror reflects a primitive value
- */
-ValueMirror.prototype.isPrimitive = function() {
-  var type = this.type();
-  return type === 'undefined' ||
-         type === 'null' ||
-         type === 'boolean' ||
-         type === 'number' ||
-         type === 'string';
-};
-
-
-/**
- * Get the actual value reflected by this mirror.
- * @return {value} The value reflected by this mirror
- */
-ValueMirror.prototype.value = function() {
-  return this.value_;
-};
-
-
-/**
- * Mirror object for Undefined.
- * @constructor
- * @extends ValueMirror
- */
-function UndefinedMirror() {
-  ValueMirror.call(this, UNDEFINED_TYPE, void 0);
-}
-inherits(UndefinedMirror, ValueMirror);
-
-
-UndefinedMirror.prototype.toText = function() {
-  return 'undefined';
-}
-
-
-/**
- * Mirror object for null.
- * @constructor
- * @extends ValueMirror
- */
-function NullMirror() {
-  ValueMirror.call(this, NULL_TYPE, null);
-}
-inherits(NullMirror, ValueMirror);
-
-
-NullMirror.prototype.toText = function() {
-  return 'null';
-}
-
-
-/**
- * Mirror object for boolean values.
- * @param {boolean} value The boolean value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function BooleanMirror(value) {
-  ValueMirror.call(this, BOOLEAN_TYPE, value);
-}
-inherits(BooleanMirror, ValueMirror);
-
-
-BooleanMirror.prototype.toText = function() {
-  return this.value_ ? 'true' : 'false';
-}
-
-
-/**
- * Mirror object for number values.
- * @param {number} value The number value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function NumberMirror(value) {
-  ValueMirror.call(this, NUMBER_TYPE, value);
-}
-inherits(NumberMirror, ValueMirror);
-
-
-NumberMirror.prototype.toText = function() {
-  return %NumberToString(this.value_);
-}
-
-
-/**
- * Mirror object for string values.
- * @param {string} value The string value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function StringMirror(value) {
-  ValueMirror.call(this, STRING_TYPE, value);
-}
-inherits(StringMirror, ValueMirror);
-
-
-StringMirror.prototype.length = function() {
-  return this.value_.length;
-};
-
-
-StringMirror.prototype.toText = function() {
-  if (this.length() > kMaxProtocolStringLength) {
-    return this.value_.substring(0, kMaxProtocolStringLength) +
-           '... (length: ' + this.length() + ')';
-  } else {
-    return this.value_;
-  }
-}
-
-
-/**
- * Mirror object for objects.
- * @param {object} value The object reflected by this mirror
- * @param {boolean} transient indicate whether this object is transient with a
- *    transient handle
- * @constructor
- * @extends ValueMirror
- */
-function ObjectMirror(value, type, transient) {
-  ValueMirror.call(this, type || OBJECT_TYPE, value, transient);
-}
-inherits(ObjectMirror, ValueMirror);
-
-
-ObjectMirror.prototype.className = function() {
-  return %_ClassOf(this.value_);
-};
-
-
-ObjectMirror.prototype.constructorFunction = function() {
-  return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
-};
-
-
-ObjectMirror.prototype.prototypeObject = function() {
-  return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
-};
-
-
-ObjectMirror.prototype.protoObject = function() {
-  return MakeMirror(%DebugGetPrototype(this.value_));
-};
-
-
-ObjectMirror.prototype.hasNamedInterceptor = function() {
-  // Get information on interceptors for this object.
-  var x = %GetInterceptorInfo(this.value_);
-  return (x & 2) != 0;
-};
-
-
-ObjectMirror.prototype.hasIndexedInterceptor = function() {
-  // Get information on interceptors for this object.
-  var x = %GetInterceptorInfo(this.value_);
-  return (x & 1) != 0;
-};
-
-
-/**
- * Return the property names for this object.
- * @param {number} kind Indicate whether named, indexed or both kinds of
- *     properties are requested
- * @param {number} limit Limit the number of names returend to the specified
-       value
- * @return {Array} Property names for this object
- */
-ObjectMirror.prototype.propertyNames = function(kind, limit) {
-  // Find kind and limit and allocate array for the result
-  kind = kind || PropertyKind.Named | PropertyKind.Indexed;
-
-  var propertyNames;
-  var elementNames;
-  var total = 0;
-  
-  // Find all the named properties.
-  if (kind & PropertyKind.Named) {
-    // Get the local property names.
-    propertyNames = %GetLocalPropertyNames(this.value_);
-    total += propertyNames.length;
-
-    // Get names for named interceptor properties if any.
-    if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
-      var namedInterceptorNames =
-          %GetNamedInterceptorPropertyNames(this.value_);
-      if (namedInterceptorNames) {
-        propertyNames = propertyNames.concat(namedInterceptorNames);
-        total += namedInterceptorNames.length;
-      }
-    }
-  }
-
-  // Find all the indexed properties.
-  if (kind & PropertyKind.Indexed) {
-    // Get the local element names.
-    elementNames = %GetLocalElementNames(this.value_);
-    total += elementNames.length;
-
-    // Get names for indexed interceptor properties.
-    if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
-      var indexedInterceptorNames =
-          %GetIndexedInterceptorElementNames(this.value_);
-      if (indexedInterceptorNames) {
-        elementNames = elementNames.concat(indexedInterceptorNames);
-        total += indexedInterceptorNames.length;
-      }
-    }
-  }
-  limit = Math.min(limit || total, total);
-
-  var names = new Array(limit);
-  var index = 0;
-
-  // Copy names for named properties.
-  if (kind & PropertyKind.Named) {
-    for (var i = 0; index < limit && i < propertyNames.length; i++) {
-      names[index++] = propertyNames[i];
-    }
-  }
-
-  // Copy names for indexed properties.
-  if (kind & PropertyKind.Indexed) {
-    for (var i = 0; index < limit && i < elementNames.length; i++) {
-      names[index++] = elementNames[i];
-    }
-  }
-
-  return names;
-};
-
-
-/**
- * Return the properties for this object as an array of PropertyMirror objects.
- * @param {number} kind Indicate whether named, indexed or both kinds of
- *     properties are requested
- * @param {number} limit Limit the number of properties returend to the
-       specified value
- * @return {Array} Property mirrors for this object
- */
-ObjectMirror.prototype.properties = function(kind, limit) {
-  var names = this.propertyNames(kind, limit);
-  var properties = new Array(names.length);
-  for (var i = 0; i < names.length; i++) {
-    properties[i] = this.property(names[i]);
-  }
-
-  return properties;
-};
-
-
-ObjectMirror.prototype.property = function(name) {
-  var details = %DebugGetPropertyDetails(this.value_, %ToString(name));
-  if (details) {
-    return new PropertyMirror(this, name, details);
-  }
-
-  // Nothing found.
-  return GetUndefinedMirror();
-};
-
-
-
-/**
- * Try to find a property from its value.
- * @param {Mirror} value The property value to look for
- * @return {PropertyMirror} The property with the specified value. If no
- *     property was found with the specified value UndefinedMirror is returned
- */
-ObjectMirror.prototype.lookupProperty = function(value) {
-  var properties = this.properties();
-
-  // Look for property value in properties.
-  for (var i = 0; i < properties.length; i++) {
-
-    // Skip properties which are defined through assessors.
-    var property = properties[i];
-    if (property.propertyType() != PropertyType.Callbacks) {
-      if (%_ObjectEquals(property.value_, value.value_)) {
-        return property;
-      }
-    }
-  }
-
-  // Nothing found.
-  return GetUndefinedMirror();
-};
-
-
-/**
- * Returns objects which has direct references to this object
- * @param {number} opt_max_objects Optional parameter specifying the maximum
- *     number of referencing objects to return.
- * @return {Array} The objects which has direct references to this object.
- */
-ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
-  // Find all objects with direct references to this object.
-  var result = %DebugReferencedBy(this.value_,
-                                  Mirror.prototype, opt_max_objects || 0);
-
-  // Make mirrors for all the references found.
-  for (var i = 0; i < result.length; i++) {
-    result[i] = MakeMirror(result[i]);
-  }
-
-  return result;
-};
-
-
-ObjectMirror.prototype.toText = function() {
-  var name;
-  var ctor = this.constructorFunction();
-  if (!ctor.isFunction()) {
-    name = this.className();
-  } else {
-    name = ctor.name();
-    if (!name) {
-      name = this.className();
-    }
-  }
-  return '#<' + builtins.GetInstanceName(name) + '>';
-};
-
-
-/**
- * Mirror object for functions.
- * @param {function} value The function object reflected by this mirror.
- * @constructor
- * @extends ObjectMirror
- */
-function FunctionMirror(value) {
-  ObjectMirror.call(this, value, FUNCTION_TYPE);
-  this.resolved_ = true;
-}
-inherits(FunctionMirror, ObjectMirror);
-
-
-/**
- * Returns whether the function is resolved.
- * @return {boolean} True if the function is resolved. Unresolved functions can
- *     only originate as functions from stack frames
- */
-FunctionMirror.prototype.resolved = function() {
-  return this.resolved_;
-};
-
-
-/**
- * Returns the name of the function.
- * @return {string} Name of the function
- */
-FunctionMirror.prototype.name = function() {
-  return %FunctionGetName(this.value_);
-};
-
-
-/**
- * Returns the inferred name of the function.
- * @return {string} Name of the function
- */
-FunctionMirror.prototype.inferredName = function() {
-  return %FunctionGetInferredName(this.value_);
-};
-
-
-/**
- * Returns the source code for the function.
- * @return {string or undefined} The source code for the function. If the
- *     function is not resolved undefined will be returned.
- */
-FunctionMirror.prototype.source = function() {
-  // Return source if function is resolved. Otherwise just fall through to
-  // return undefined.
-  if (this.resolved()) {
-    return builtins.FunctionSourceString(this.value_);
-  }
-};
-
-
-/**
- * Returns the script object for the function.
- * @return {ScriptMirror or undefined} Script object for the function or
- *     undefined if the function has no script
- */
-FunctionMirror.prototype.script = function() {
-  // Return script if function is resolved. Otherwise just fall through
-  // to return undefined.
-  if (this.resolved()) {
-    var script = %FunctionGetScript(this.value_);
-    if (script) {
-      return MakeMirror(script);
-    }
-  }
-};
-
-
-/**
- * Returns the script source position for the function. Only makes sense
- * for functions which has a script defined.
- * @return {Number or undefined} in-script position for the function
- */
-FunctionMirror.prototype.sourcePosition_ = function() {
-  // Return script if function is resolved. Otherwise just fall through
-  // to return undefined.
-  if (this.resolved()) {
-    return %FunctionGetScriptSourcePosition(this.value_);
-  }
-};
-
-
-/**
- * Returns the script source location object for the function. Only makes sense
- * for functions which has a script defined.
- * @return {Location or undefined} in-script location for the function begin
- */
-FunctionMirror.prototype.sourceLocation = function() {
-  if (this.resolved() && this.script()) {
-    return this.script().locationFromPosition(this.sourcePosition_(),
-                                              true);
-  }
-};
-
-
-/**
- * Returns objects constructed by this function.
- * @param {number} opt_max_instances Optional parameter specifying the maximum
- *     number of instances to return.
- * @return {Array or undefined} The objects constructed by this function.
- */
-FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
-  if (this.resolved()) {
-    // Find all objects constructed from this function.
-    var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
-
-    // Make mirrors for all the instances found.
-    for (var i = 0; i < result.length; i++) {
-      result[i] = MakeMirror(result[i]);
-    }
-
-    return result;
-  } else {
-    return [];
-  }
-};
-
-
-FunctionMirror.prototype.toText = function() {
-  return this.source();
-}
-
-
-/**
- * Mirror object for unresolved functions.
- * @param {string} value The name for the unresolved function reflected by this
- *     mirror.
- * @constructor
- * @extends ObjectMirror
- */
-function UnresolvedFunctionMirror(value) {
-  // Construct this using the ValueMirror as an unresolved function is not a
-  // real object but just a string.
-  ValueMirror.call(this, FUNCTION_TYPE, value);
-  this.propertyCount_ = 0;
-  this.elementCount_ = 0;
-  this.resolved_ = false;
-}
-inherits(UnresolvedFunctionMirror, FunctionMirror);
-
-
-UnresolvedFunctionMirror.prototype.className = function() {
-  return 'Function';
-};
-
-
-UnresolvedFunctionMirror.prototype.constructorFunction = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.prototypeObject = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.protoObject = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.name = function() {
-  return this.value_;
-};
-
-
-UnresolvedFunctionMirror.prototype.inferredName = function() {
-  return undefined;
-};
-
-
-UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
-  return [];
-}
-
-
-/**
- * Mirror object for arrays.
- * @param {Array} value The Array object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function ArrayMirror(value) {
-  ObjectMirror.call(this, value);
-}
-inherits(ArrayMirror, ObjectMirror);
-
-
-ArrayMirror.prototype.length = function() {
-  return this.value_.length;
-};
-
-
-ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index, opt_to_index) {
-  var from_index = opt_from_index || 0;
-  var to_index = opt_to_index || this.length() - 1;
-  if (from_index > to_index) return new Array();
-  var values = new Array(to_index - from_index + 1);
-  for (var i = from_index; i <= to_index; i++) {
-    var details = %DebugGetPropertyDetails(this.value_, %ToString(i));
-    var value;
-    if (details) {
-      value = new PropertyMirror(this, i, details);
-    } else {
-      value = GetUndefinedMirror();
-    }
-    values[i - from_index] = value;
-  }
-  return values;
-}
-
-
-/**
- * Mirror object for dates.
- * @param {Date} value The Date object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function DateMirror(value) {
-  ObjectMirror.call(this, value);
-}
-inherits(DateMirror, ObjectMirror);
-
-
-DateMirror.prototype.toText = function() {
-  var s = JSON.stringify(this.value_);
-  return s.substring(1, s.length - 1);  // cut quotes
-}
-
-
-/**
- * Mirror object for regular expressions.
- * @param {RegExp} value The RegExp object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function RegExpMirror(value) {
-  ObjectMirror.call(this, value, REGEXP_TYPE);
-}
-inherits(RegExpMirror, ObjectMirror);
-
-
-/**
- * Returns the source to the regular expression.
- * @return {string or undefined} The source to the regular expression
- */
-RegExpMirror.prototype.source = function() {
-  return this.value_.source;
-};
-
-
-/**
- * Returns whether this regular expression has the global (g) flag set.
- * @return {boolean} Value of the global flag
- */
-RegExpMirror.prototype.global = function() {
-  return this.value_.global;
-};
-
-
-/**
- * Returns whether this regular expression has the ignore case (i) flag set.
- * @return {boolean} Value of the ignore case flag
- */
-RegExpMirror.prototype.ignoreCase = function() {
-  return this.value_.ignoreCase;
-};
-
-
-/**
- * Returns whether this regular expression has the multiline (m) flag set.
- * @return {boolean} Value of the multiline flag
- */
-RegExpMirror.prototype.multiline = function() {
-  return this.value_.multiline;
-};
-
-
-RegExpMirror.prototype.toText = function() {
-  // Simpel to text which is used when on specialization in subclass.
-  return "/" + this.source() + "/";
-}
-
-
-/**
- * Mirror object for error objects.
- * @param {Error} value The error object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function ErrorMirror(value) {
-  ObjectMirror.call(this, value, ERROR_TYPE);
-}
-inherits(ErrorMirror, ObjectMirror);
-
-
-/**
- * Returns the message for this eror object.
- * @return {string or undefined} The message for this eror object
- */
-ErrorMirror.prototype.message = function() {
-  return this.value_.message;
-};
-
-
-ErrorMirror.prototype.toText = function() {
-  // Use the same text representation as in messages.js.
-  var text;
-  try {
-    str = builtins.ToDetailString(this.value_);
-  } catch (e) {
-    str = '#<an Error>';
-  }
-  return str;
-}
-
-
-/**
- * Base mirror object for properties.
- * @param {ObjectMirror} mirror The mirror object having this property
- * @param {string} name The name of the property
- * @param {Array} details Details about the property
- * @constructor
- * @extends Mirror
- */
-function PropertyMirror(mirror, name, details) {
-  Mirror.call(this, PROPERTY_TYPE);
-  this.mirror_ = mirror;
-  this.name_ = name;
-  this.value_ = details[0];
-  this.details_ = details[1];
-  if (details.length > 2) {
-    this.exception_ = details[2]
-    this.getter_ = details[3];
-    this.setter_ = details[4];
-  }
-}
-inherits(PropertyMirror, Mirror);
-
-
-PropertyMirror.prototype.isReadOnly = function() {
-  return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
-}
-
-
-PropertyMirror.prototype.isEnum = function() {
-  return (this.attributes() & PropertyAttribute.DontEnum) == 0;
-}
-
-
-PropertyMirror.prototype.canDelete = function() {
-  return (this.attributes() & PropertyAttribute.DontDelete) == 0;
-}
-
-
-PropertyMirror.prototype.name = function() {
-  return this.name_;
-}
-
-
-PropertyMirror.prototype.isIndexed = function() {
-  for (var i = 0; i < this.name_.length; i++) {
-    if (this.name_[i] < '0' || '9' < this.name_[i]) {
-      return false;
-    }
-  }
-  return true;
-}
-
-
-PropertyMirror.prototype.value = function() {
-  return MakeMirror(this.value_, false);
-}
-
-
-/**
- * Returns whether this property value is an exception.
- * @return {booolean} True if this property value is an exception
- */
-PropertyMirror.prototype.isException = function() {
-  return this.exception_ ? true : false;
-}
-
-
-PropertyMirror.prototype.attributes = function() {
-  return %DebugPropertyAttributesFromDetails(this.details_);
-}
-
-
-PropertyMirror.prototype.propertyType = function() {
-  return %DebugPropertyTypeFromDetails(this.details_);
-}
-
-
-PropertyMirror.prototype.insertionIndex = function() {
-  return %DebugPropertyIndexFromDetails(this.details_);
-}
-
-
-/**
- * Returns whether this property has a getter defined through __defineGetter__.
- * @return {booolean} True if this property has a getter
- */
-PropertyMirror.prototype.hasGetter = function() {
-  return this.getter_ ? true : false;
-}
-
-
-/**
- * Returns whether this property has a setter defined through __defineSetter__.
- * @return {booolean} True if this property has a setter
- */
-PropertyMirror.prototype.hasSetter = function() {
-  return this.setter_ ? true : false;
-}
-
-
-/**
- * Returns the getter for this property defined through __defineGetter__.
- * @return {Mirror} FunctionMirror reflecting the getter function or
- *     UndefinedMirror if there is no getter for this property
- */
-PropertyMirror.prototype.getter = function() {
-  if (this.hasGetter()) {
-    return MakeMirror(this.getter_);
-  } else {
-    return GetUndefinedMirror();
-  }
-}
-
-
-/**
- * Returns the setter for this property defined through __defineSetter__.
- * @return {Mirror} FunctionMirror reflecting the setter function or
- *     UndefinedMirror if there is no setter for this property
- */
-PropertyMirror.prototype.setter = function() {
-  if (this.hasSetter()) {
-    return MakeMirror(this.setter_);
-  } else {
-    return GetUndefinedMirror();
-  }
-}
-
-
-/**
- * Returns whether this property is natively implemented by the host or a set
- * through JavaScript code.
- * @return {boolean} True if the property is 
- *     UndefinedMirror if there is no setter for this property
- */
-PropertyMirror.prototype.isNative = function() {
-  return (this.propertyType() == PropertyType.Interceptor) ||
-         ((this.propertyType() == PropertyType.Callbacks) &&
-          !this.hasGetter() && !this.hasSetter());
-}
-
-
-const kFrameDetailsFrameIdIndex = 0;
-const kFrameDetailsReceiverIndex = 1;
-const kFrameDetailsFunctionIndex = 2;
-const kFrameDetailsArgumentCountIndex = 3;
-const kFrameDetailsLocalCountIndex = 4;
-const kFrameDetailsSourcePositionIndex = 5;
-const kFrameDetailsConstructCallIndex = 6;
-const kFrameDetailsDebuggerFrameIndex = 7;
-const kFrameDetailsFirstDynamicIndex = 8;
-
-const kFrameDetailsNameIndex = 0;
-const kFrameDetailsValueIndex = 1;
-const kFrameDetailsNameValueSize = 2;
-
-/**
- * Wrapper for the frame details information retreived from the VM. The frame
- * details from the VM is an array with the following content. See runtime.cc
- * Runtime_GetFrameDetails.
- *     0: Id
- *     1: Receiver
- *     2: Function
- *     3: Argument count
- *     4: Local count
- *     5: Source position
- *     6: Construct call
- *     Arguments name, value
- *     Locals name, value
- * @param {number} break_id Current break id
- * @param {number} index Frame number
- * @constructor
- */
-function FrameDetails(break_id, index) {
-  this.break_id_ = break_id;
-  this.details_ = %GetFrameDetails(break_id, index);
-}
-
-
-FrameDetails.prototype.frameId = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsFrameIdIndex];
-}
-
-
-FrameDetails.prototype.receiver = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsReceiverIndex];
-}
-
-
-FrameDetails.prototype.func = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsFunctionIndex];
-}
-
-
-FrameDetails.prototype.isConstructCall = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsConstructCallIndex];
-}
-
-
-FrameDetails.prototype.isDebuggerFrame = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsDebuggerFrameIndex];
-}
-
-
-FrameDetails.prototype.argumentCount = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsArgumentCountIndex];
-}
-
-
-FrameDetails.prototype.argumentName = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.argumentCount()) {
-    return this.details_[kFrameDetailsFirstDynamicIndex +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsNameIndex]
-  }
-}
-
-
-FrameDetails.prototype.argumentValue = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.argumentCount()) {
-    return this.details_[kFrameDetailsFirstDynamicIndex +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsValueIndex]
-  }
-}
-
-
-FrameDetails.prototype.localCount = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsLocalCountIndex];
-}
-
-
-FrameDetails.prototype.sourcePosition = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsSourcePositionIndex];
-}
-
-
-FrameDetails.prototype.localName = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.localCount()) {
-    var locals_offset = kFrameDetailsFirstDynamicIndex + this.argumentCount() * kFrameDetailsNameValueSize
-    return this.details_[locals_offset +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsNameIndex]
-  }
-}
-
-
-FrameDetails.prototype.localValue = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.localCount()) {
-    var locals_offset = kFrameDetailsFirstDynamicIndex + this.argumentCount() * kFrameDetailsNameValueSize
-    return this.details_[locals_offset +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsValueIndex]
-  }
-}
-
-
-FrameDetails.prototype.scopeCount = function() {
-  return %GetScopeCount(this.break_id_, this.frameId());
-}
-
-
-/**
- * Mirror object for stack frames.
- * @param {number} break_id The break id in the VM for which this frame is
-       valid
- * @param {number} index The frame index (top frame is index 0)
- * @constructor
- * @extends Mirror
- */
-function FrameMirror(break_id, index) {
-  Mirror.call(this, FRAME_TYPE);
-  this.break_id_ = break_id;
-  this.index_ = index;
-  this.details_ = new FrameDetails(break_id, index);
-}
-inherits(FrameMirror, Mirror);
-
-
-FrameMirror.prototype.index = function() {
-  return this.index_;
-};
-
-
-FrameMirror.prototype.func = function() {
-  // Get the function for this frame from the VM.
-  var f = this.details_.func();
-  
-  // Create a function mirror. NOTE: MakeMirror cannot be used here as the
-  // value returned from the VM might be a string if the function for the
-  // frame is unresolved.
-  if (IS_FUNCTION(f)) {
-    return MakeMirror(f);
-  } else {
-    return new UnresolvedFunctionMirror(f);
-  }
-};
-
-
-FrameMirror.prototype.receiver = function() {
-  return MakeMirror(this.details_.receiver());
-};
-
-
-FrameMirror.prototype.isConstructCall = function() {
-  return this.details_.isConstructCall();
-};
-
-
-FrameMirror.prototype.isDebuggerFrame = function() {
-  return this.details_.isDebuggerFrame();
-};
-
-
-FrameMirror.prototype.argumentCount = function() {
-  return this.details_.argumentCount();
-};
-
-
-FrameMirror.prototype.argumentName = function(index) {
-  return this.details_.argumentName(index);
-};
-
-
-FrameMirror.prototype.argumentValue = function(index) {
-  return MakeMirror(this.details_.argumentValue(index));
-};
-
-
-FrameMirror.prototype.localCount = function() {
-  return this.details_.localCount();
-};
-
-
-FrameMirror.prototype.localName = function(index) {
-  return this.details_.localName(index);
-};
-
-
-FrameMirror.prototype.localValue = function(index) {
-  return MakeMirror(this.details_.localValue(index));
-};
-
-
-FrameMirror.prototype.sourcePosition = function() {
-  return this.details_.sourcePosition();
-};
-
-
-FrameMirror.prototype.sourceLocation = function() {
-  if (this.func().resolved() && this.func().script()) {
-    return this.func().script().locationFromPosition(this.sourcePosition(),
-                                                     true);
-  }
-};
-
-
-FrameMirror.prototype.sourceLine = function() {
-  if (this.func().resolved()) {
-    var location = this.sourceLocation();
-    if (location) {
-      return location.line;
-    }
-  }
-};
-
-
-FrameMirror.prototype.sourceColumn = function() {
-  if (this.func().resolved()) {
-    var location = this.sourceLocation();
-    if (location) {
-      return location.column;
-    }
-  }
-};
-
-
-FrameMirror.prototype.sourceLineText = function() {
-  if (this.func().resolved()) {
-    var location = this.sourceLocation();
-    if (location) {
-      return location.sourceText();
-    }
-  }
-};
-
-
-FrameMirror.prototype.scopeCount = function() {
-  return this.details_.scopeCount();
-};
-
-
-FrameMirror.prototype.scope = function(index) {
-  return new ScopeMirror(this, index);
-};
-
-
-FrameMirror.prototype.evaluate = function(source, disable_break) {
-  var result = %DebugEvaluate(this.break_id_, this.details_.frameId(),
-                              source, Boolean(disable_break));
-  return MakeMirror(result);
-};
-
-
-FrameMirror.prototype.invocationText = function() {
-  // Format frame invoaction (receiver, function and arguments).
-  var result = '';
-  var func = this.func();
-  var receiver = this.receiver();
-  if (this.isConstructCall()) {
-    // For constructor frames display new followed by the function name.
-    result += 'new ';
-    result += func.name() ? func.name() : '[anonymous]';
-  } else if (this.isDebuggerFrame()) {
-    result += '[debugger]';
-  } else {
-    // If the receiver has a className which is 'global' don't display it.
-    var display_receiver = !receiver.className || receiver.className() != 'global';
-    if (display_receiver) {
-      result += receiver.toText();
-    }
-    // Try to find the function as a property in the receiver. Include the
-    // prototype chain in the lookup.
-    var property = GetUndefinedMirror();
-    if (!receiver.isUndefined()) {
-      for (var r = receiver; !r.isNull() && property.isUndefined(); r = r.protoObject()) {
-        property = r.lookupProperty(func);
-      }
-    }
-    if (!property.isUndefined()) {
-      // The function invoked was found on the receiver. Use the property name
-      // for the backtrace.
-      if (!property.isIndexed()) {
-        if (display_receiver) {
-          result += '.';
-        }
-        result += property.name();
-      } else {
-        result += '[';
-        result += property.name();
-        result += ']';
-      }
-      // Also known as - if the name in the function doesn't match the name
-      // under which it was looked up.
-      if (func.name() && func.name() != property.name()) {
-        result += '(aka ' + func.name() + ')';
-      }
-    } else {
-      // The function invoked was not found on the receiver. Use the function
-      // name if available for the backtrace.
-      if (display_receiver) {
-        result += '.';
-      }
-      result += func.name() ? func.name() : '[anonymous]';
-    }
-  }
-
-  // Render arguments for normal frames.
-  if (!this.isDebuggerFrame()) {
-    result += '(';
-    for (var i = 0; i < this.argumentCount(); i++) {
-      if (i != 0) result += ', ';
-      if (this.argumentName(i)) {
-        result += this.argumentName(i);
-        result += '=';
-      }
-      result += this.argumentValue(i).toText();
-    }
-    result += ')';
-  }
-
-  return result;
-}
-
-
-FrameMirror.prototype.sourceAndPositionText = function() {
-  // Format source and position.
-  var result = '';
-  var func = this.func();
-  if (func.resolved()) {
-    if (func.script()) {
-      if (func.script().name()) {
-        result += func.script().name();
-      } else {
-        result += '[unnamed]';
-      }
-      if (!this.isDebuggerFrame()) {
-        var location = this.sourceLocation();
-        result += ' line ';
-        result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
-        result += ' column ';
-        result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
-        if (!IS_UNDEFINED(this.sourcePosition())) {
-          result += ' (position ' + (this.sourcePosition() + 1) + ')';
-        }
-      }
-    } else {
-      result += '[no source]';
-    }
-  } else {
-    result += '[unresolved]';
-  }
-
-  return result;
-}
-
-
-FrameMirror.prototype.localsText = function() {
-  // Format local variables.
-  var result = '';
-  var locals_count = this.localCount()
-  if (locals_count > 0) {
-    for (var i = 0; i < locals_count; ++i) {
-      result += '      var ';
-      result += this.localName(i);
-      result += ' = ';
-      result += this.localValue(i).toText();
-      if (i < locals_count - 1) result += '\n';
-    }
-  }
-
-  return result;
-}
-
-
-FrameMirror.prototype.toText = function(opt_locals) {
-  var result = '';
-  result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
-  result += ' ';
-  result += this.invocationText();
-  result += ' ';
-  result += this.sourceAndPositionText();
-  if (opt_locals) {
-    result += '\n';
-    result += this.localsText();
-  }
-  return result;
-}
-
-
-const kScopeDetailsTypeIndex = 0;
-const kScopeDetailsObjectIndex = 1;
-
-function ScopeDetails(frame, index) {
-  this.break_id_ = frame.break_id_;
-  this.details_ = %GetScopeDetails(frame.break_id_,
-                                   frame.details_.frameId(),
-                                   index);
-}
-
-
-ScopeDetails.prototype.type = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kScopeDetailsTypeIndex];
-}
-
-
-ScopeDetails.prototype.object = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kScopeDetailsObjectIndex];
-}
-
-
-/**
- * Mirror object for scope.
- * @param {FrameMirror} frame The frame this scope is a part of
- * @param {number} index The scope index in the frame
- * @constructor
- * @extends Mirror
- */
-function ScopeMirror(frame, index) {
-  Mirror.call(this, SCOPE_TYPE);
-  this.frame_index_ = frame.index_;
-  this.scope_index_ = index;
-  this.details_ = new ScopeDetails(frame, index);
-}
-inherits(ScopeMirror, Mirror);
-
-
-ScopeMirror.prototype.frameIndex = function() {
-  return this.frame_index_;
-};
-
-
-ScopeMirror.prototype.scopeIndex = function() {
-  return this.scope_index_;
-};
-
-
-ScopeMirror.prototype.scopeType = function() {
-  return this.details_.type();
-};
-
-
-ScopeMirror.prototype.scopeObject = function() {
-  // For local and closure scopes create a transient mirror as these objects are
-  // created on the fly materializing the local or closure scopes and
-  // therefore will not preserve identity.
-  var transient = this.scopeType() == ScopeType.Local ||
-                  this.scopeType() == ScopeType.Closure;
-  return MakeMirror(this.details_.object(), transient);
-};
-
-
-/**
- * Mirror object for script source.
- * @param {Script} script The script object
- * @constructor
- * @extends Mirror
- */
-function ScriptMirror(script) {
-  Mirror.call(this, SCRIPT_TYPE);
-  this.script_ = script;
-  this.context_ = new ContextMirror(script.context_data);
-  this.allocateHandle_();
-}
-inherits(ScriptMirror, Mirror);
-
-
-ScriptMirror.prototype.value = function() {
-  return this.script_;
-};
-
-
-ScriptMirror.prototype.name = function() {
-  return this.script_.name;
-};
-
-
-ScriptMirror.prototype.id = function() {
-  return this.script_.id;
-};
-
-
-ScriptMirror.prototype.source = function() {
-  return this.script_.source;
-};
-
-
-ScriptMirror.prototype.lineOffset = function() {
-  return this.script_.line_offset;
-};
-
-
-ScriptMirror.prototype.columnOffset = function() {
-  return this.script_.column_offset;
-};
-
-
-ScriptMirror.prototype.data = function() {
-  return this.script_.data;
-};
-
-
-ScriptMirror.prototype.scriptType = function() {
-  return this.script_.type;
-};
-
-
-ScriptMirror.prototype.compilationType = function() {
-  return this.script_.compilation_type;
-};
-
-
-ScriptMirror.prototype.lineCount = function() {
-  return this.script_.lineCount();
-};
-
-
-ScriptMirror.prototype.locationFromPosition = function(
-    position, include_resource_offset) {
-  return this.script_.locationFromPosition(position, include_resource_offset);
-}
-
-
-ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
-  return this.script_.sourceSlice(opt_from_line, opt_to_line);
-}
-
-
-ScriptMirror.prototype.context = function() {
-  return this.context_;
-};
-
-
-ScriptMirror.prototype.evalFromScript = function() {
-  return MakeMirror(this.script_.eval_from_script);
-};
-
-
-ScriptMirror.prototype.evalFromFunctionName = function() {
-  return MakeMirror(this.script_.eval_from_function_name);
-};
-
-
-ScriptMirror.prototype.evalFromLocation = function() {
-  var eval_from_script = this.evalFromScript();
-  if (!eval_from_script.isUndefined()) {
-    var position = this.script_.eval_from_script_position;
-    return eval_from_script.locationFromPosition(position, true);
-  }
-};
-
-
-ScriptMirror.prototype.toText = function() {
-  var result = '';
-  result += this.name();
-  result += ' (lines: ';
-  if (this.lineOffset() > 0) {
-    result += this.lineOffset();
-    result += '-';
-    result += this.lineOffset() + this.lineCount() - 1;
-  } else {
-    result += this.lineCount();
-  }
-  result += ')';
-  return result;
-}
-
-
-/**
- * Mirror object for context.
- * @param {Object} data The context data
- * @constructor
- * @extends Mirror
- */
-function ContextMirror(data) {
-  Mirror.call(this, CONTEXT_TYPE);
-  this.data_ = data;
-  this.allocateHandle_();
-}
-inherits(ContextMirror, Mirror);
-
-
-ContextMirror.prototype.data = function() {
-  return this.data_;
-};
-
-
-/**
- * Returns a mirror serializer
- *
- * @param {boolean} details Set to true to include details
- * @param {Object} options Options comtrolling the serialization
- *     The following options can be set:
- *       includeSource: include ths full source of scripts
- * @returns {MirrorSerializer} mirror serializer
- */
-function MakeMirrorSerializer(details, options) {
-  return new JSONProtocolSerializer(details, options);
-}
-
-
-/**
- * Object for serializing a mirror objects and its direct references.
- * @param {boolean} details Indicates whether to include details for the mirror
- *     serialized
- * @constructor
- */
-function JSONProtocolSerializer(details, options) {
-  this.details_ = details;
-  this.options_ = options;
-  this.mirrors_ = [ ];
-}
-
-
-/**
- * Returns a serialization of an object reference. The referenced object are
- * added to the serialization state.
- *
- * @param {Mirror} mirror The mirror to serialize
- * @returns {String} JSON serialization
- */
-JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
-  return this.serialize_(mirror, true, true);
-}
-
-
-/**
- * Returns a serialization of an object value. The referenced objects are
- * added to the serialization state.
- *
- * @param {Mirror} mirror The mirror to serialize
- * @returns {String} JSON serialization
- */
-JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
-  var json = this.serialize_(mirror, false, true);
-  return json;
-}
-
-
-/**
- * Returns a serialization of all the objects referenced.
- *
- * @param {Mirror} mirror The mirror to serialize.
- * @returns {Array.<Object>} Array of the referenced objects converted to
- *     protcol objects.
- */
-JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
-  // Collect the protocol representation of the referenced objects in an array.
-  var content = [];
-  
-  // Get the number of referenced objects.
-  var count = this.mirrors_.length;
-  
-  for (var i = 0; i < count; i++) {
-    content.push(this.serialize_(this.mirrors_[i], false, false));
-  }
-
-  return content;
-}
-
-
-JSONProtocolSerializer.prototype.includeSource_ = function() {
-  return this.options_ && this.options_.includeSource;
-}
-
-
-JSONProtocolSerializer.prototype.inlineRefs_ = function() {
-  return this.options_ && this.options_.inlineRefs;
-}
-
-
-JSONProtocolSerializer.prototype.add_ = function(mirror) {
-  // If this mirror is already in the list just return.
-  for (var i = 0; i < this.mirrors_.length; i++) {
-    if (this.mirrors_[i] === mirror) {
-      return;
-    }
-  }
-  
-  // Add the mirror to the list of mirrors to be serialized.
-  this.mirrors_.push(mirror);
-}
-
-
-/**
- * Formats mirror object to protocol reference object with some data that can
- * be used to display the value in debugger.
- * @param {Mirror} mirror Mirror to serialize.
- * @return {Object} Protocol reference object.
- */
-JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ = 
-    function(mirror) {
-  var o = {};
-  o.ref = mirror.handle();
-  o.type = mirror.type();
-  switch (mirror.type()) {
-    case UNDEFINED_TYPE:
-    case NULL_TYPE:
-    case BOOLEAN_TYPE:
-    case NUMBER_TYPE:
-      o.value = mirror.value();
-      break;
-    case STRING_TYPE:
-      // Limit string length.
-      o.value = mirror.toText();
-      break;
-    case FUNCTION_TYPE:
-      o.name = mirror.name();
-      o.inferredName = mirror.inferredName();
-      if (mirror.script()) {
-        o.scriptId = mirror.script().id();
-      }
-      break;
-    case ERROR_TYPE:
-    case REGEXP_TYPE:
-      o.value = mirror.toText();
-      break;
-    case OBJECT_TYPE:
-      o.className = mirror.className();
-      break;
-  }
-  return o;
-};
-
-
-JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
-                                                       details) {
-  // If serializing a reference to a mirror just return the reference and add
-  // the mirror to the referenced mirrors.
-  if (reference &&
-      (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
-    if (this.inlineRefs_() && mirror.isValue()) {
-      return this.serializeReferenceWithDisplayData_(mirror);
-    } else {
-      this.add_(mirror);
-      return {'ref' : mirror.handle()};
-    }
-  }
-  
-  // Collect the JSON property/value pairs.
-  var content = {};
-
-  // Add the mirror handle.
-  if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
-    content.handle = mirror.handle();
-  }
-
-  // Always add the type.
-  content.type = mirror.type();
-
-  switch (mirror.type()) {
-    case UNDEFINED_TYPE:
-    case NULL_TYPE:
-      // Undefined and null are represented just by their type.
-      break;
-
-    case BOOLEAN_TYPE:
-      // Boolean values are simply represented by their value.
-      content.value = mirror.value();
-      break;
-
-    case NUMBER_TYPE:
-      // Number values are simply represented by their value.
-      content.value = NumberToJSON_(mirror.value());
-      break;
-
-    case STRING_TYPE:
-      // String values might have their value cropped to keep down size.
-      if (mirror.length() > kMaxProtocolStringLength) {
-        var str = mirror.value().substring(0, kMaxProtocolStringLength);
-        content.value = str;
-        content.fromIndex = 0;
-        content.toIndex = kMaxProtocolStringLength;
-      } else {
-        content.value = mirror.value();
-      }
-      content.length = mirror.length();
-      break;
-
-    case OBJECT_TYPE:
-    case FUNCTION_TYPE:
-    case ERROR_TYPE:
-    case REGEXP_TYPE:
-      // Add object representation.
-      this.serializeObject_(mirror, content, details);
-      break;
-
-    case PROPERTY_TYPE:
-      throw new Error('PropertyMirror cannot be serialized independeltly')
-      break;
-
-    case FRAME_TYPE:
-      // Add object representation.
-      this.serializeFrame_(mirror, content);
-      break;
-
-    case SCOPE_TYPE:
-      // Add object representation.
-      this.serializeScope_(mirror, content);
-      break;
-
-    case SCRIPT_TYPE:
-      // Script is represented by id, name and source attributes.
-      if (mirror.name()) {
-        content.name = mirror.name();
-      }
-      content.id = mirror.id();
-      content.lineOffset = mirror.lineOffset();
-      content.columnOffset = mirror.columnOffset();
-      content.lineCount = mirror.lineCount();
-      if (mirror.data()) {
-        content.data = mirror.data();
-      }
-      if (this.includeSource_()) {
-        content.source = mirror.source();
-      } else {
-        var sourceStart = mirror.source().substring(0, 80);
-        content.sourceStart = sourceStart;
-      }
-      content.sourceLength = mirror.source().length;
-      content.scriptType = mirror.scriptType();
-      content.compilationType = mirror.compilationType();
-      // For compilation type eval emit information on the script from which
-      // eval was called if a script is present.
-      if (mirror.compilationType() == 1 &&
-          mirror.evalFromScript()) {
-        content.evalFromScript =
-            this.serializeReference(mirror.evalFromScript());
-        var evalFromLocation = mirror.evalFromLocation()
-        if (evalFromLocation) {
-          content.evalFromLocation = { line: evalFromLocation.line,
-                                       column: evalFromLocation.column };
-        }
-        if (mirror.evalFromFunctionName()) {
-          content.evalFromFunctionName = mirror.evalFromFunctionName();
-        }
-      }
-      if (mirror.context()) {
-        content.context = this.serializeReference(mirror.context());
-      }
-      break;
-
-    case CONTEXT_TYPE:
-      content.data = mirror.data();
-      break;
-  }
-
-  // Always add the text representation.
-  content.text = mirror.toText();
-  
-  // Create and return the JSON string.
-  return content;
-}
-
-
-/**
- * Serialize object information to the following JSON format.
- *
- *   {"className":"<class name>",
- *    "constructorFunction":{"ref":<number>},
- *    "protoObject":{"ref":<number>},
- *    "prototypeObject":{"ref":<number>},
- *    "namedInterceptor":<boolean>,
- *    "indexedInterceptor":<boolean>,
- *    "properties":[<properties>]}
- */
-JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
-                                                             details) {
-  // Add general object properties.
-  content.className = mirror.className();
-  content.constructorFunction =
-      this.serializeReference(mirror.constructorFunction());
-  content.protoObject = this.serializeReference(mirror.protoObject());
-  content.prototypeObject = this.serializeReference(mirror.prototypeObject());
-
-  // Add flags to indicate whether there are interceptors.
-  if (mirror.hasNamedInterceptor()) {
-    content.namedInterceptor = true;
-  }
-  if (mirror.hasIndexedInterceptor()) {
-    content.indexedInterceptor = true;
-  }
-  
-  // Add function specific properties.
-  if (mirror.isFunction()) {
-    // Add function specific properties.
-    content.name = mirror.name();
-    if (!IS_UNDEFINED(mirror.inferredName())) {
-      content.inferredName = mirror.inferredName();
-    }
-    content.resolved = mirror.resolved();
-    if (mirror.resolved()) {
-      content.source = mirror.source();
-    }
-    if (mirror.script()) {
-      content.script = this.serializeReference(mirror.script());
-      content.scriptId = mirror.script().id();
-      
-      serializeLocationFields(mirror.sourceLocation(), content);
-    }
-  }
-
-  // Add date specific properties.
-  if (mirror.isDate()) {
-    // Add date specific properties.
-    content.value = mirror.value();
-  }
-
-  // Add actual properties - named properties followed by indexed properties.
-  var propertyNames = mirror.propertyNames(PropertyKind.Named);
-  var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
-  var p = new Array(propertyNames.length + propertyIndexes.length);
-  for (var i = 0; i < propertyNames.length; i++) {
-    var propertyMirror = mirror.property(propertyNames[i]);
-    p[i] = this.serializeProperty_(propertyMirror);
-    if (details) {
-      this.add_(propertyMirror.value());
-    }
-  }
-  for (var i = 0; i < propertyIndexes.length; i++) {
-    var propertyMirror = mirror.property(propertyIndexes[i]);
-    p[propertyNames.length + i] = this.serializeProperty_(propertyMirror);
-    if (details) {
-      this.add_(propertyMirror.value());
-    }
-  }
-  content.properties = p;
-}
-
-
-/**
- * Serialize location information to the following JSON format:
- *
- *   "position":"<position>",
- *   "line":"<line>",
- *   "column":"<column>",
- * 
- * @param {SourceLocation} location The location to serialize, may be undefined.
- */
-function serializeLocationFields (location, content) {
-  if (!location) {
-    return;
-  }                                                                     
-  content.position = location.position;
-  var line = location.line;
-  if (!IS_UNDEFINED(line)) {
-    content.line = line;
-  }
-  var column = location.column;
-  if (!IS_UNDEFINED(column)) {
-    content.column = column;
-  }
-}
-
-
-/**
- * Serialize property information to the following JSON format for building the
- * array of properties.
- *
- *   {"name":"<property name>",
- *    "attributes":<number>,
- *    "propertyType":<number>,
- *    "ref":<number>}
- *
- * If the attribute for the property is PropertyAttribute.None it is not added.
- * If the propertyType for the property is PropertyType.Normal it is not added.
- * Here are a couple of examples.
- *
- *   {"name":"hello","ref":1}
- *   {"name":"length","attributes":7,"propertyType":3,"ref":2}
- *
- * @param {PropertyMirror} propertyMirror The property to serialize.
- * @returns {Object} Protocol object representing the property.
- */
-JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
-  var result = {};
-  
-  result.name = propertyMirror.name();
-  var propertyValue = propertyMirror.value();
-  if (this.inlineRefs_() && propertyValue.isValue()) {
-    result.value = this.serializeReferenceWithDisplayData_(propertyValue);
-  } else {
-    if (propertyMirror.attributes() != PropertyAttribute.None) {
-      result.attributes = propertyMirror.attributes();
-    }
-    if (propertyMirror.propertyType() != PropertyType.Normal) {
-      result.propertyType = propertyMirror.propertyType();
-    }
-    result.ref = propertyValue.handle();
-  }
-  return result;
-}
-
-
-JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
-  content.index = mirror.index();
-  content.receiver = this.serializeReference(mirror.receiver());
-  var func = mirror.func();
-  content.func = this.serializeReference(func);
-  if (func.script()) {
-    content.script = this.serializeReference(func.script());
-  }
-  content.constructCall = mirror.isConstructCall();
-  content.debuggerFrame = mirror.isDebuggerFrame();
-  var x = new Array(mirror.argumentCount());
-  for (var i = 0; i < mirror.argumentCount(); i++) {
-    var arg = {};
-    var argument_name = mirror.argumentName(i)
-    if (argument_name) {
-      arg.name = argument_name;
-    }
-    arg.value = this.serializeReference(mirror.argumentValue(i));
-    x[i] = arg;
-  }
-  content.arguments = x;
-  var x = new Array(mirror.localCount());
-  for (var i = 0; i < mirror.localCount(); i++) {
-    var local = {};
-    local.name = mirror.localName(i);
-    local.value = this.serializeReference(mirror.localValue(i));
-    x[i] = local;
-  }
-  content.locals = x;
-  serializeLocationFields(mirror.sourceLocation(), content);
-  var source_line_text = mirror.sourceLineText();
-  if (!IS_UNDEFINED(source_line_text)) {
-    content.sourceLineText = source_line_text;
-  }
-  
-  content.scopes = [];
-  for (var i = 0; i < mirror.scopeCount(); i++) {
-    var scope = mirror.scope(i);
-    content.scopes.push({
-      type: scope.scopeType(),
-      index: i
-    });
-  }
-}
-
-
-JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
-  content.index = mirror.scopeIndex();
-  content.frameIndex = mirror.frameIndex();
-  content.type = mirror.scopeType();
-  content.object = this.inlineRefs_() ?
-                   this.serializeValue(mirror.scopeObject()) :
-                   this.serializeReference(mirror.scopeObject());
-}
-
-
-/**
- * Convert a number to a protocol value. For all finite numbers the number
- * itself is returned. For non finite numbers NaN, Infinite and
- * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
- * (not including the quotes) is returned.
- *
- * @param {number} value The number value to convert to a protocol value.
- * @returns {number|string} Protocol value.
- */
-function NumberToJSON_(value) {
-  if (isNaN(value)) {
-    return 'NaN';
-  }
-  if (!isFinite(value)) {
-    if (value > 0) {
-      return 'Infinity';
-    } else {
-      return '-Infinity';
-    }
-  }
-  return value; 
-}
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index 37cf263..a30b450 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -205,7 +205,6 @@
 
 
 int main(int argc, char** argv) {
-
 #ifdef ENABLE_LOGGING_AND_PROFILING
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
diff --git a/src/number-info.h b/src/number-info.h
new file mode 100644
index 0000000..c6f32e4
--- /dev/null
+++ b/src/number-info.h
@@ -0,0 +1,72 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_NUMBER_INFO_H_
+#define V8_NUMBER_INFO_H_
+
+namespace v8 {
+namespace internal {
+
+class NumberInfo : public AllStatic {
+ public:
+  enum Type {
+    kUnknown = 0,
+    kNumber = 1,
+    kSmi = 3,
+    kHeapNumber = 5,
+    kUninitialized = 7
+  };
+
+  // Return the weakest (least precise) common type.
+  static Type Combine(Type a, Type b) {
+    // Make use of the order of enum values.
+    return static_cast<Type>(a & b);
+  }
+
+  static bool IsNumber(Type a) {
+    ASSERT(a != kUninitialized);
+    return ((a & kNumber) != 0);
+  }
+
+  static const char* ToString(Type a) {
+    switch (a) {
+      case kUnknown: return "UnknownType";
+      case kNumber: return "NumberType";
+      case kSmi: return "SmiType";
+      case kHeapNumber: return "HeapNumberType";
+      case kUninitialized:
+        UNREACHABLE();
+        return "UninitializedType";
+    }
+    UNREACHABLE();
+    return "Unreachable code";
+  }
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_NUMBER_INFO_H_
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index ded213b..8f26f74 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1033,6 +1033,8 @@
 
 void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
   HeapObject::PrintHeader("FunctionTemplateInfo");
+  PrintF("\n - class name: ");
+  class_name()->ShortPrint();
   PrintF("\n - tag: ");
   tag()->ShortPrint();
   PrintF("\n - property_list: ");
diff --git a/src/objects.cc b/src/objects.cc
index a8328ac..99532ac 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -219,7 +219,7 @@
     LookupResult* result,
     String* name,
     PropertyAttributes* attributes) {
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case CALLBACKS: {
         // Only allow API accessors.
@@ -242,7 +242,7 @@
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r;
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
                                                   &r,
                                                   name,
@@ -255,16 +255,16 @@
         // No access check in GetPropertyAttributeWithInterceptor.
         LookupResult r;
         result->holder()->LookupRealNamedProperty(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
                                                   &r,
                                                   name,
                                                   attributes);
         }
-      }
-      default: {
         break;
       }
+      default:
+        UNREACHABLE();
     }
   }
 
@@ -280,7 +280,7 @@
     LookupResult* result,
     String* name,
     bool continue_search) {
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case CALLBACKS: {
         // Only allow API accessors.
@@ -301,7 +301,7 @@
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r;
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyAttributeWithFailedAccessCheck(receiver,
                                                            &r,
                                                            name,
@@ -319,7 +319,7 @@
         } else {
           result->holder()->LocalLookupRealNamedProperty(name, &r);
         }
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyAttributeWithFailedAccessCheck(receiver,
                                                            &r,
                                                            name,
@@ -328,9 +328,8 @@
         break;
       }
 
-      default: {
-        break;
-      }
+      default:
+        UNREACHABLE();
     }
   }
 
@@ -456,7 +455,7 @@
   // holder will always be the interceptor holder and the search may
   // only continue with a current object just after the interceptor
   // holder in the prototype chain.
-  Object* last = result->IsValid() ? result->holder() : Heap::null_value();
+  Object* last = result->IsProperty() ? result->holder() : Heap::null_value();
   for (Object* current = this; true; current = current->GetPrototype()) {
     if (current->IsAccessCheckNeeded()) {
       // Check if we're allowed to read from the current object. Note
@@ -1408,8 +1407,12 @@
   // Check local property, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (result.IsValid()) return SetProperty(&result, name, value, attributes);
-  // Add real property.
+  if (result.IsFound()) {
+    // An existing property, a map transition or a null descriptor was
+    // found.  Use set property to handle all these cases.
+    return SetProperty(&result, name, value, attributes);
+  }
+  // Add a new real property.
   return AddProperty(name, value, attributes);
 }
 
@@ -1641,8 +1644,8 @@
        pt != Heap::null_value();
        pt = pt->GetPrototype()) {
     JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid()) {
-      if (!result->IsTransitionType() && result->IsReadOnly()) {
+    if (result->IsProperty()) {
+      if (result->IsReadOnly()) {
         result->NotFound();
         return;
       }
@@ -1703,7 +1706,11 @@
 
   if (HasFastProperties()) {
     LookupInDescriptor(name, result);
-    if (result->IsValid()) {
+    if (result->IsFound()) {
+      // A property, a map transition or a null descriptor was found.
+      // We return all of these result types because
+      // LocalLookupRealNamedProperty is used when setting properties
+      // where map transitions and null descriptors are handled.
       ASSERT(result->holder() == this && result->type() != NORMAL);
       // Disallow caching for uninitialized constants. These can only
       // occur as fields.
@@ -1752,16 +1759,7 @@
        pt != Heap::null_value();
        pt = JSObject::cast(pt)->GetPrototype()) {
     JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid()) {
-      switch (result->type()) {
-        case NORMAL:
-        case FIELD:
-        case CONSTANT_FUNCTION:
-        case CALLBACKS:
-          return;
-        default: break;
-      }
-    }
+    if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
   }
   result->NotFound();
 }
@@ -1847,14 +1845,15 @@
     // accessor that wants to handle the property.
     LookupResult accessor_result;
     LookupCallbackSetterInPrototypes(name, &accessor_result);
-    if (accessor_result.IsValid()) {
+    if (accessor_result.IsProperty()) {
       return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
                                      name,
                                      value,
                                      accessor_result.holder());
     }
   }
-  if (result->IsNotFound()) {
+  if (!result->IsFound()) {
+    // Neither properties nor transitions found.
     return AddProperty(name, value, attributes);
   }
   if (result->IsReadOnly() && result->IsProperty()) return value;
@@ -1913,15 +1912,12 @@
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc;
-  // ADDED TO CLONE
-  LookupResult result_struct;
-  LocalLookup(name, &result_struct);
-  LookupResult* result = &result_struct;
-  // END ADDED TO CLONE
+  LookupResult result;
+  LocalLookup(name, &result);
   // Check access rights if needed.
   if (IsAccessCheckNeeded()
-    && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
-    return SetPropertyWithFailedAccessCheck(result, name, value);
+      && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
+    return SetPropertyWithFailedAccessCheck(&result, name, value);
   }
 
   if (IsJSGlobalProxy()) {
@@ -1935,28 +1931,31 @@
   }
 
   // Check for accessor in prototype chain removed here in clone.
-  if (result->IsNotFound()) {
+  if (!result.IsFound()) {
+    // Neither properties nor transitions found.
     return AddProperty(name, value, attributes);
   }
+  PropertyDetails details = PropertyDetails(attributes, NORMAL);
+
   // Check of IsReadOnly removed from here in clone.
-  switch (result->type()) {
+  switch (result.type()) {
     case NORMAL:
-      return SetNormalizedProperty(result, value);
+      return SetNormalizedProperty(name, value, details);
     case FIELD:
-      return FastPropertyAtPut(result->GetFieldIndex(), value);
+      return FastPropertyAtPut(result.GetFieldIndex(), value);
     case MAP_TRANSITION:
-      if (attributes == result->GetAttributes()) {
+      if (attributes == result.GetAttributes()) {
         // Only use map transition if the attributes match.
-        return AddFastPropertyUsingMap(result->GetTransitionMap(),
+        return AddFastPropertyUsingMap(result.GetTransitionMap(),
                                        name,
                                        value);
       }
       return ConvertDescriptorToField(name, value, attributes);
     case CONSTANT_FUNCTION:
       // Only replace the function if necessary.
-      if (value == result->GetConstantFunction()) return value;
+      if (value == result.GetConstantFunction()) return value;
       // Preserve the attributes of this existing property.
-      attributes = result->GetAttributes();
+      attributes = result.GetAttributes();
       return ConvertDescriptorToField(name, value, attributes);
     case CALLBACKS:
     case INTERCEPTOR:
@@ -2072,7 +2071,7 @@
                                                      name,
                                                      continue_search);
   }
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case NORMAL:  // fall through
       case FIELD:
@@ -2082,13 +2081,8 @@
       case INTERCEPTOR:
         return result->holder()->
           GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
-      case MAP_TRANSITION:
-      case CONSTANT_TRANSITION:
-      case NULL_DESCRIPTOR:
-        return ABSENT;
       default:
         UNREACHABLE();
-        break;
     }
   }
   return ABSENT;
@@ -2261,7 +2255,7 @@
   // Check local property, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (!result.IsValid()) return Heap::true_value();
+  if (!result.IsProperty()) return Heap::true_value();
 
   // Normalize object if needed.
   Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
@@ -2445,7 +2439,7 @@
   } else {
     LookupResult result;
     LocalLookup(name, &result);
-    if (!result.IsValid()) return Heap::true_value();
+    if (!result.IsProperty()) return Heap::true_value();
     // Ignore attributes if forcing a deletion.
     if (result.IsDontDelete() && mode != FORCE_DELETION) {
       return Heap::false_value();
@@ -2675,7 +2669,7 @@
        current != Heap::null_value();
        current = JSObject::cast(current)->GetPrototype()) {
     JSObject::cast(current)->LocalLookup(name, result);
-    if (result->IsValid() && !result->IsTransitionType()) return;
+    if (result->IsProperty()) return;
   }
   result->NotFound();
 }
@@ -2687,7 +2681,7 @@
        current != Heap::null_value();
        current = JSObject::cast(current)->GetPrototype()) {
     JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid() && result->type() == CALLBACKS) return;
+    if (result->IsProperty() && result->type() == CALLBACKS) return;
   }
   result->NotFound();
 }
@@ -2717,7 +2711,7 @@
   // cause security problems.
   LookupResult callback_result;
   LookupCallback(name, &callback_result);
-  if (callback_result.IsValid()) {
+  if (callback_result.IsFound()) {
     Object* obj = callback_result.GetCallbackObject();
     if (obj->IsAccessorInfo() &&
         AccessorInfo::cast(obj)->prohibits_overwriting()) {
@@ -2768,11 +2762,16 @@
     // Lookup the name.
     LookupResult result;
     LocalLookup(name, &result);
-    if (result.IsValid()) {
+    if (result.IsProperty()) {
       if (result.IsReadOnly()) return Heap::undefined_value();
       if (result.type() == CALLBACKS) {
         Object* obj = result.GetCallbackObject();
         if (obj->IsFixedArray()) {
+          // The object might be in fast mode even though it has
+          // a getter/setter.
+          Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+          if (ok->IsFailure()) return ok;
+
           PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
           SetNormalizedProperty(name, obj, details);
           return obj;
@@ -2885,7 +2884,7 @@
          obj = JSObject::cast(obj)->GetPrototype()) {
       LookupResult result;
       JSObject::cast(obj)->LocalLookup(name, &result);
-      if (result.IsValid()) {
+      if (result.IsProperty()) {
         if (result.IsReadOnly()) return Heap::undefined_value();
         if (result.type() == CALLBACKS) {
           Object* obj = result.GetCallbackObject();
@@ -4753,6 +4752,40 @@
 }
 
 
+bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
+  // Check the basic conditions for generating inline constructor code.
+  if (!FLAG_inline_new
+      || !has_only_simple_this_property_assignments()
+      || this_property_assignments_count() == 0) {
+    return false;
+  }
+
+  // If the prototype is null inline constructors cause no problems.
+  if (!prototype->IsJSObject()) {
+    ASSERT(prototype->IsNull());
+    return true;
+  }
+
+  // Traverse the proposed prototype chain looking for setters for properties of
+  // the same names as are set by the inline constructor.
+  for (Object* obj = prototype;
+       obj != Heap::null_value();
+       obj = obj->GetPrototype()) {
+    JSObject* js_object = JSObject::cast(obj);
+    for (int i = 0; i < this_property_assignments_count(); i++) {
+      LookupResult result;
+      String* name = GetThisPropertyAssignmentName(i);
+      js_object->LocalLookupRealNamedProperty(name, &result);
+      if (result.IsProperty() && result.type() == CALLBACKS) {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+
 void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
     bool only_simple_this_property_assignments,
     FixedArray* assignments) {
@@ -4808,7 +4841,6 @@
 }
 
 
-
 // Support function for printing the source code to a StringStream
 // without any allocation in the heap.
 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
@@ -5286,6 +5318,48 @@
 }
 
 
+Object* JSObject::SetPrototype(Object* value,
+                               bool skip_hidden_prototypes) {
+  // Silently ignore the change if value is not a JSObject or null.
+  // SpiderMonkey behaves this way.
+  if (!value->IsJSObject() && !value->IsNull()) return value;
+
+  // Before we can set the prototype we need to be sure
+  // prototype cycles are prevented.
+  // It is sufficient to validate that the receiver is not in the new prototype
+  // chain.
+  for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) {
+    if (JSObject::cast(pt) == this) {
+      // Cycle detected.
+      HandleScope scope;
+      return Top::Throw(*Factory::NewError("cyclic_proto",
+                                           HandleVector<Object>(NULL, 0)));
+    }
+  }
+
+  JSObject* real_receiver = this;
+
+  if (skip_hidden_prototypes) {
+    // Find the first object in the chain whose prototype object is not
+    // hidden and set the new prototype on that object.
+    Object* current_proto = real_receiver->GetPrototype();
+    while (current_proto->IsJSObject() &&
+          JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
+      real_receiver = JSObject::cast(current_proto);
+      current_proto = current_proto->GetPrototype();
+    }
+  }
+
+  // Set the new prototype of the object.
+  Object* new_map = real_receiver->map()->CopyDropTransitions();
+  if (new_map->IsFailure()) return new_map;
+  Map::cast(new_map)->set_prototype(value);
+  real_receiver->set_map(Map::cast(new_map));
+
+  return value;
+}
+
+
 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
   switch (GetElementsKind()) {
     case FAST_ELEMENTS: {
@@ -6103,7 +6177,9 @@
   // Check local property in holder, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (result.IsValid()) return GetProperty(receiver, &result, name, attributes);
+  if (result.IsProperty()) {
+    return GetProperty(receiver, &result, name, attributes);
+  }
   // Continue searching via the prototype chain.
   Object* pt = GetPrototype();
   *attributes = ABSENT;
@@ -6119,8 +6195,10 @@
   // Check local property in holder, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (!result.IsValid()) return Heap::undefined_value();
-  return GetProperty(receiver, &result, name, attributes);
+  if (result.IsProperty()) {
+    return GetProperty(receiver, &result, name, attributes);
+  }
+  return Heap::undefined_value();
 }
 
 
@@ -6172,24 +6250,7 @@
 
   LookupResult result;
   LocalLookupRealNamedProperty(key, &result);
-  if (result.IsValid()) {
-    switch (result.type()) {
-      case NORMAL:    // fall through.
-      case FIELD:     // fall through.
-      case CALLBACKS:  // fall through.
-      case CONSTANT_FUNCTION:
-        return true;
-      case INTERCEPTOR:
-      case MAP_TRANSITION:
-      case CONSTANT_TRANSITION:
-      case NULL_DESCRIPTOR:
-        return false;
-      default:
-        UNREACHABLE();
-    }
-  }
-
-  return false;
+  return result.IsProperty() && (result.type() != INTERCEPTOR);
 }
 
 
@@ -6251,7 +6312,7 @@
 
   LookupResult result;
   LocalLookupRealNamedProperty(key, &result);
-  return result.IsValid() && (result.type() == CALLBACKS);
+  return result.IsProperty() && (result.type() == CALLBACKS);
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 4893666..0030496 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -179,7 +179,7 @@
   class TypeField:       public BitField<PropertyType,       0, 3> {};
   class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
   class DeletedField:    public BitField<uint32_t,           6, 1> {};
-  class IndexField:      public BitField<uint32_t,           7, 31-7> {};
+  class IndexField:      public BitField<uint32_t,           7, 32-7> {};
 
   static const int kInitialIndex = 1;
  private:
@@ -1301,6 +1301,9 @@
   // Return the object's prototype (might be Heap::null_value()).
   inline Object* GetPrototype();
 
+  // Set the object's prototype (only JSObject and null are allowed).
+  Object* SetPrototype(Object* value, bool skip_hidden_prototypes);
+
   // Tells whether the index'th element is present.
   inline bool HasElement(uint32_t index);
   bool HasElementWithReceiver(JSObject* receiver, uint32_t index);
@@ -3200,6 +3203,10 @@
   inline bool try_full_codegen();
   inline void set_try_full_codegen(bool flag);
 
+  // Check whether a inlined constructor can be generated with the given
+  // prototype.
+  bool CanGenerateInlineConstructor(Object* prototype);
+
   // For functions which only contains this property assignments this provides
   // access to the names for the properties assigned.
   DECL_ACCESSORS(this_property_assignments, Object)
diff --git a/src/parser.cc b/src/parser.cc
index b06d86f..5058296 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1690,7 +1690,8 @@
   // Propagate the collected information on this property assignments.
   if (top_scope_->is_function_scope()) {
     bool only_simple_this_property_assignments =
-        this_property_assignment_finder.only_simple_this_property_assignments();
+        this_property_assignment_finder.only_simple_this_property_assignments()
+        && top_scope_->declarations()->length() == 0;
     if (only_simple_this_property_assignments) {
       temp_scope_->SetThisPropertyAssignmentInfo(
           only_simple_this_property_assignments,
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index ff75776..a978777 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -192,7 +192,8 @@
 
 
 void OS::DebugBreak() {
-#if defined(__arm__) || defined(__thumb__)
+#if (defined(__arm__) || defined(__thumb__)) && \
+    defined(CAN_USE_ARMV5_INSTRUCTIONS)
   asm("bkpt 0");
 #else
   asm("int $3");
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index ef4ae17..8cc513d 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -266,7 +266,8 @@
 void OS::DebugBreak() {
 // TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x,
 //  which is the architecture of generated code).
-#if defined(__arm__) || defined(__thumb__)
+#if (defined(__arm__) || defined(__thumb__)) && \
+    defined(CAN_USE_ARMV5_INSTRUCTIONS)
   asm("bkpt 0");
 #elif defined(__mips__)
   asm("break");
@@ -721,11 +722,9 @@
 
 
 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
-    return;
-/*#ifndef V8_HOST_ARCH_MIPS
+#ifndef V8_HOST_ARCH_MIPS
   USE(info);
   if (signal != SIGPROF) return;
-  if (!IsVmThread()) return;
   if (active_sampler_ == NULL) return;
 
   TickSample sample;
@@ -766,7 +765,7 @@
   sample.state = Logger::state();
 
   active_sampler_->Tick(&sample);
-#endif*/
+#endif
 }
 
 
@@ -805,7 +804,7 @@
   sa.sa_sigaction = ProfilerSignalHandler;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = SA_SIGINFO;
-  if (sigaction(SIGALRM, &sa, &data_->old_signal_handler_) != 0) return;
+  if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
   data_->signal_handler_installed_ = true;
 
   // Set the itimer to generate a tick for each interval.
@@ -814,7 +813,7 @@
   itimer.it_interval.tv_usec = (interval_ % 1000) * 1000;
   itimer.it_value.tv_sec = itimer.it_interval.tv_sec;
   itimer.it_value.tv_usec = itimer.it_interval.tv_usec;
-  setitimer(ITIMER_REAL, &itimer, &data_->old_timer_value_);
+  setitimer(ITIMER_PROF, &itimer, &data_->old_timer_value_);
 
   // Set this sampler as the active sampler.
   active_sampler_ = this;
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 62e6004..f96e769 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -190,7 +190,8 @@
 
 
 void OS::DebugBreak() {
-#if defined(__arm__) || defined(__thumb__)
+#if (defined(__arm__) || defined(__thumb__)) && \
+    defined(CAN_USE_ARMV5_INSTRUCTIONS)
   asm("bkpt 0");
 #else
   asm("int $3");
diff --git a/src/property.cc b/src/property.cc
index caa7397..b579b68 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -33,7 +33,7 @@
 
 #ifdef DEBUG
 void LookupResult::Print() {
-  if (!IsValid()) {
+  if (!IsFound()) {
     PrintF("Not Found\n");
     return;
   }
diff --git a/src/property.h b/src/property.h
index b993af1..15a5652 100644
--- a/src/property.h
+++ b/src/property.h
@@ -201,23 +201,17 @@
   }
 
   JSObject* holder() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return holder_;
   }
 
   PropertyType type() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return details_.type();
   }
 
-  bool IsTransitionType() {
-    PropertyType t = type();
-    if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true;
-    return false;
-  }
-
   PropertyAttributes GetAttributes() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return details_.attributes();
   }
 
@@ -229,14 +223,17 @@
   bool IsDontDelete() { return details_.IsDontDelete(); }
   bool IsDontEnum() { return details_.IsDontEnum(); }
   bool IsDeleted() { return details_.IsDeleted(); }
+  bool IsFound() { return lookup_type_ != NOT_FOUND; }
 
-  bool IsValid() { return  lookup_type_ != NOT_FOUND; }
-  bool IsNotFound() { return lookup_type_ == NOT_FOUND; }
-
-  // Tells whether the result is a property.
-  // Excluding transitions and the null descriptor.
+  // Is the result is a property excluding transitions and the null
+  // descriptor?
   bool IsProperty() {
-    return IsValid() && type() < FIRST_PHANTOM_PROPERTY_TYPE;
+    return IsFound() && (type() < FIRST_PHANTOM_PROPERTY_TYPE);
+  }
+
+  // Is the result a property or a transition?
+  bool IsPropertyOrTransition() {
+    return IsFound() && (type() != NULL_DESCRIPTOR);
   }
 
   bool IsCacheable() { return cacheable_; }
diff --git a/src/regexp-delay.js b/src/regexp-delay.js
deleted file mode 100644
index 7bec455..0000000
--- a/src/regexp-delay.js
+++ /dev/null
@@ -1,406 +0,0 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Expect $Object = global.Object;
-// Expect $Array = global.Array;
-
-const $RegExp = global.RegExp;
-
-// A recursive descent parser for Patterns according to the grammar of
-// ECMA-262 15.10.1, with deviations noted below.
-function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
-  // RegExp : Called as constructor; see ECMA-262, section 15.10.4.
-  if (IS_REGEXP(pattern)) {
-    if (!IS_UNDEFINED(flags)) {
-      throw MakeTypeError('regexp_flags', []);
-    }
-    flags = (pattern.global ? 'g' : '')
-        + (pattern.ignoreCase ? 'i' : '')
-        + (pattern.multiline ? 'm' : '');
-    pattern = pattern.source;
-  }
-
-  pattern = IS_UNDEFINED(pattern) ? '' : ToString(pattern);
-  flags = IS_UNDEFINED(flags) ? '' : ToString(flags);
-
-  var global = false;
-  var ignoreCase = false;
-  var multiline = false;
-
-  for (var i = 0; i < flags.length; i++) {
-    var c = StringCharAt.call(flags, i);
-    switch (c) {
-      case 'g':
-        // Allow duplicate flags to be consistent with JSC and others.
-        global = true;
-        break;
-      case 'i':
-        ignoreCase = true;
-        break;
-      case 'm':
-        multiline = true;
-        break;
-      default:
-        // Ignore flags that have no meaning to be consistent with
-        // JSC.
-        break;
-    }
-  }
-
-  if (isConstructorCall) {
-    // ECMA-262, section 15.10.7.1.
-    %SetProperty(object, 'source', pattern,
-                 DONT_DELETE |  READ_ONLY | DONT_ENUM);
-
-    // ECMA-262, section 15.10.7.2.
-    %SetProperty(object, 'global', global, DONT_DELETE | READ_ONLY | DONT_ENUM);
-
-    // ECMA-262, section 15.10.7.3.
-    %SetProperty(object, 'ignoreCase', ignoreCase,
-                 DONT_DELETE | READ_ONLY | DONT_ENUM);
-
-    // ECMA-262, section 15.10.7.4.
-    %SetProperty(object, 'multiline', multiline,
-                 DONT_DELETE | READ_ONLY | DONT_ENUM);
-
-    // ECMA-262, section 15.10.7.5.
-    %SetProperty(object, 'lastIndex', 0, DONT_DELETE | DONT_ENUM);
-  } else { // RegExp is being recompiled via RegExp.prototype.compile.
-    %IgnoreAttributesAndSetProperty(object, 'source', pattern);
-    %IgnoreAttributesAndSetProperty(object, 'global', global);
-    %IgnoreAttributesAndSetProperty(object, 'ignoreCase', ignoreCase);
-    %IgnoreAttributesAndSetProperty(object, 'multiline', multiline);
-    %IgnoreAttributesAndSetProperty(object, 'lastIndex', 0);
-  }
-
-  // Call internal function to compile the pattern.
-  %RegExpCompile(object, pattern, flags);
-}
-
-
-function RegExpConstructor(pattern, flags) {
-  if (%_IsConstructCall()) {
-    DoConstructRegExp(this, pattern, flags, true);
-  } else {
-    // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
-    if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) {
-      return pattern;
-    }
-    return new $RegExp(pattern, flags);
-  }
-}
-
-
-// Deprecated RegExp.prototype.compile method.  We behave like the constructor
-// were called again.  In SpiderMonkey, this method returns the regexp object.
-// In JSC, it returns undefined.  For compatibility with JSC, we match their
-// behavior.
-function CompileRegExp(pattern, flags) {
-  // Both JSC and SpiderMonkey treat a missing pattern argument as the
-  // empty subject string, and an actual undefined value passed as the
-  // pattern as the string 'undefined'.  Note that JSC is inconsistent
-  // here, treating undefined values differently in
-  // RegExp.prototype.compile and in the constructor, where they are
-  // the empty string.  For compatibility with JSC, we match their
-  // behavior.
-  if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) {
-    DoConstructRegExp(this, 'undefined', flags, false);
-  } else {
-    DoConstructRegExp(this, pattern, flags, false);
-  }
-}
-
-
-function DoRegExpExec(regexp, string, index) {
-  return %_RegExpExec(regexp, string, index, lastMatchInfo);
-}
-
-
-function RegExpExec(string) {
-  if (!IS_REGEXP(this)) {
-    throw MakeTypeError('method_called_on_incompatible',
-                        ['RegExp.prototype.exec', this]);
-  }
-  if (%_ArgumentsLength() == 0) {
-    var regExpInput = LAST_INPUT(lastMatchInfo);
-    if (IS_UNDEFINED(regExpInput)) {
-      throw MakeError('no_input_to_regexp', [this]);
-    }
-    string = regExpInput;
-  }
-  var s = ToString(string);
-  var length = s.length;
-  var lastIndex = this.lastIndex;
-  var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
-  if (i < 0 || i > s.length) {
-    this.lastIndex = 0;
-    return null;
-  }
-
-  %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
-  // matchIndices is either null or the lastMatchInfo array.
-  var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
-
-  if (matchIndices == null) {
-    if (this.global) this.lastIndex = 0;
-    return matchIndices; // no match
-  }
-
-  var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
-  var result = new $Array(numResults);
-  for (var i = 0; i < numResults; i++) {
-    var matchStart = lastMatchInfo[CAPTURE(i << 1)];
-    var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
-    if (matchStart != -1 && matchEnd != -1) {
-      result[i] = SubString(s, matchStart, matchEnd);
-    } else {
-      // Make sure the element is present. Avoid reading the undefined
-      // property from the global object since this may change.
-      result[i] = void 0;
-    }
-  }
-
-  if (this.global)
-    this.lastIndex = lastMatchInfo[CAPTURE1];
-  result.index = lastMatchInfo[CAPTURE0];
-  result.input = s;
-  return result;
-}
-
-
-// Section 15.10.6.3 doesn't actually make sense, but the intention seems to be
-// that test is defined in terms of String.prototype.exec. However, it probably
-// means the original value of String.prototype.exec, which is what everybody
-// else implements.
-function RegExpTest(string) {
-  if (!IS_REGEXP(this)) {
-    throw MakeTypeError('method_called_on_incompatible',
-                        ['RegExp.prototype.test', this]);
-  }
-  if (%_ArgumentsLength() == 0) {
-    var regExpInput = LAST_INPUT(lastMatchInfo);
-    if (IS_UNDEFINED(regExpInput)) {
-      throw MakeError('no_input_to_regexp', [this]);
-    }
-    string = regExpInput;
-  }
-  var s = ToString(string);
-  var length = s.length;
-  var lastIndex = this.lastIndex;
-  var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
-  if (i < 0 || i > s.length) {
-    this.lastIndex = 0;
-    return false;
-  }
-
-  %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
-  // matchIndices is either null or the lastMatchInfo array.
-  var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
-
-  if (matchIndices == null) {
-    if (this.global) this.lastIndex = 0;
-    return false;
-  }
-
-  if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
-  return true;
-}
-
-
-function RegExpToString() {
-  // If this.source is an empty string, output /(?:)/.
-  // http://bugzilla.mozilla.org/show_bug.cgi?id=225550
-  // ecma_2/RegExp/properties-001.js.
-  var src = this.source ? this.source : '(?:)';
-  var result = '/' + src + '/';
-  if (this.global)
-    result += 'g';
-  if (this.ignoreCase)
-    result += 'i';
-  if (this.multiline)
-    result += 'm';
-  return result;
-}
-
-
-// Getters for the static properties lastMatch, lastParen, leftContext, and
-// rightContext of the RegExp constructor.  The properties are computed based
-// on the captures array of the last successful match and the subject string
-// of the last successful match.
-function RegExpGetLastMatch() {
-  var regExpSubject = LAST_SUBJECT(lastMatchInfo);
-  return SubString(regExpSubject,
-                   lastMatchInfo[CAPTURE0],
-                   lastMatchInfo[CAPTURE1]);
-}
-
-
-function RegExpGetLastParen() {
-  var length = NUMBER_OF_CAPTURES(lastMatchInfo);
-  if (length <= 2) return '';  // There were no captures.
-  // We match the SpiderMonkey behavior: return the substring defined by the
-  // last pair (after the first pair) of elements of the capture array even if
-  // it is empty.
-  var regExpSubject = LAST_SUBJECT(lastMatchInfo);
-  var start = lastMatchInfo[CAPTURE(length - 2)];
-  var end = lastMatchInfo[CAPTURE(length - 1)];
-  if (start != -1 && end != -1) {
-    return SubString(regExpSubject, start, end);
-  }
-  return "";
-}
-
-
-function RegExpGetLeftContext() {
-  return SubString(LAST_SUBJECT(lastMatchInfo),
-                   0,
-                   lastMatchInfo[CAPTURE0]);
-}
-
-
-function RegExpGetRightContext() {
-  var subject = LAST_SUBJECT(lastMatchInfo);
-  return SubString(subject,
-                   lastMatchInfo[CAPTURE1],
-                   subject.length);
-}
-
-
-// The properties $1..$9 are the first nine capturing substrings of the last
-// successful match, or ''.  The function RegExpMakeCaptureGetter will be
-// called with indices from 1 to 9.
-function RegExpMakeCaptureGetter(n) {
-  return function() {
-    var index = n * 2;
-    if (index >= NUMBER_OF_CAPTURES(lastMatchInfo)) return '';
-    var matchStart = lastMatchInfo[CAPTURE(index)];
-    var matchEnd = lastMatchInfo[CAPTURE(index + 1)];
-    if (matchStart == -1 || matchEnd == -1) return '';
-    return SubString(LAST_SUBJECT(lastMatchInfo), matchStart, matchEnd);
-  };
-}
-
-
-// Property of the builtins object for recording the result of the last
-// regexp match.  The property lastMatchInfo includes the matchIndices
-// array of the last successful regexp match (an array of start/end index
-// pairs for the match and all the captured substrings), the invariant is
-// that there are at least two capture indeces.  The array also contains
-// the subject string for the last successful match.
-var lastMatchInfo = [
-    2,                 // REGEXP_NUMBER_OF_CAPTURES
-    "",                // Last subject.
-    void 0,            // Last input - settable with RegExpSetInput.
-    0,                 // REGEXP_FIRST_CAPTURE + 0
-    0,                 // REGEXP_FIRST_CAPTURE + 1
-];
-
-// -------------------------------------------------------------------
-
-function SetupRegExp() {
-  %FunctionSetInstanceClassName($RegExp, 'RegExp');
-  %FunctionSetPrototype($RegExp, new $Object());
-  %SetProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
-  %SetCode($RegExp, RegExpConstructor);
-
-  InstallFunctions($RegExp.prototype, DONT_ENUM, $Array(
-    "exec", RegExpExec,
-    "test", RegExpTest,
-    "toString", RegExpToString,
-    "compile", CompileRegExp
-  ));
-
-  // The length of compile is 1 in SpiderMonkey.
-  %FunctionSetLength($RegExp.prototype.compile, 1);
-
-  // The properties input, $input, and $_ are aliases for each other.  When this
-  // value is set the value it is set to is coerced to a string. 
-  // Getter and setter for the input.
-  function RegExpGetInput() {
-    var regExpInput = LAST_INPUT(lastMatchInfo);
-    return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
-  }
-  function RegExpSetInput(string) {
-    LAST_INPUT(lastMatchInfo) = ToString(string);
-  };
-
-  %DefineAccessor($RegExp, 'input', GETTER, RegExpGetInput, DONT_DELETE);
-  %DefineAccessor($RegExp, 'input', SETTER, RegExpSetInput, DONT_DELETE);
-  %DefineAccessor($RegExp, '$_', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$_', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$input', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$input', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
-
-  // The properties multiline and $* are aliases for each other.  When this
-  // value is set in SpiderMonkey, the value it is set to is coerced to a
-  // boolean.  We mimic that behavior with a slight difference: in SpiderMonkey
-  // the value of the expression 'RegExp.multiline = null' (for instance) is the
-  // boolean false (ie, the value after coercion), while in V8 it is the value
-  // null (ie, the value before coercion).
-
-  // Getter and setter for multiline.
-  var multiline = false;
-  function RegExpGetMultiline() { return multiline; };
-  function RegExpSetMultiline(flag) { multiline = flag ? true : false; };
-
-  %DefineAccessor($RegExp, 'multiline', GETTER, RegExpGetMultiline, DONT_DELETE);
-  %DefineAccessor($RegExp, 'multiline', SETTER, RegExpSetMultiline, DONT_DELETE);
-  %DefineAccessor($RegExp, '$*', GETTER, RegExpGetMultiline, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$*', SETTER, RegExpSetMultiline, DONT_ENUM | DONT_DELETE);
-
-
-  function NoOpSetter(ignored) {}
-
-
-  // Static properties set by a successful match.
-  %DefineAccessor($RegExp, 'lastMatch', GETTER, RegExpGetLastMatch, DONT_DELETE);
-  %DefineAccessor($RegExp, 'lastMatch', SETTER, NoOpSetter, DONT_DELETE);
-  %DefineAccessor($RegExp, '$&', GETTER, RegExpGetLastMatch, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$&', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, 'lastParen', GETTER, RegExpGetLastParen, DONT_DELETE);
-  %DefineAccessor($RegExp, 'lastParen', SETTER, NoOpSetter, DONT_DELETE);
-  %DefineAccessor($RegExp, '$+', GETTER, RegExpGetLastParen, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$+', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, 'leftContext', GETTER, RegExpGetLeftContext, DONT_DELETE);
-  %DefineAccessor($RegExp, 'leftContext', SETTER, NoOpSetter, DONT_DELETE);
-  %DefineAccessor($RegExp, '$`', GETTER, RegExpGetLeftContext, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, '$`', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, 'rightContext', GETTER, RegExpGetRightContext, DONT_DELETE);
-  %DefineAccessor($RegExp, 'rightContext', SETTER, NoOpSetter, DONT_DELETE);
-  %DefineAccessor($RegExp, "$'", GETTER, RegExpGetRightContext, DONT_ENUM | DONT_DELETE);
-  %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-
-  for (var i = 1; i < 10; ++i) {
-    %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_DELETE);
-    %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE);
-  }
-}
-
-
-SetupRegExp();
diff --git a/src/register-allocator-inl.h b/src/register-allocator-inl.h
index b3fa474..a99f455 100644
--- a/src/register-allocator-inl.h
+++ b/src/register-allocator-inl.h
@@ -48,6 +48,20 @@
 namespace v8 {
 namespace internal {
 
+Result::Result(const Result& other) {
+  other.CopyTo(this);
+}
+
+
+Result& Result::operator=(const Result& other) {
+  if (this != &other) {
+    Unuse();
+    other.CopyTo(this);
+  }
+  return *this;
+}
+
+
 Result::~Result() {
   if (is_register()) {
     CodeGeneratorScope::Current()->allocator()->Unuse(reg());
@@ -71,6 +85,25 @@
 }
 
 
+bool RegisterAllocator::is_used(Register reg) {
+  return registers_.is_used(ToNumber(reg));
+}
+
+
+int RegisterAllocator::count(Register reg) {
+  return registers_.count(ToNumber(reg));
+}
+
+
+void RegisterAllocator::Use(Register reg) {
+  registers_.Use(ToNumber(reg));
+}
+
+
+void RegisterAllocator::Unuse(Register reg) {
+  registers_.Unuse(ToNumber(reg));
+}
+
 } }  // namespace v8::internal
 
 #endif  // V8_REGISTER_ALLOCATOR_INL_H_
diff --git a/src/register-allocator.cc b/src/register-allocator.cc
index d55f949..349cc24 100644
--- a/src/register-allocator.cc
+++ b/src/register-allocator.cc
@@ -37,10 +37,12 @@
 // Result implementation.
 
 
-Result::Result(Register reg) {
+Result::Result(Register reg, NumberInfo::Type info) {
   ASSERT(reg.is_valid() && !RegisterAllocator::IsReserved(reg));
   CodeGeneratorScope::Current()->allocator()->Use(reg);
-  value_ = TypeField::encode(REGISTER) | DataField::encode(reg.code_);
+  value_ = TypeField::encode(REGISTER)
+      | NumberInfoField::encode(info)
+      | DataField::encode(reg.code_);
 }
 
 
@@ -50,6 +52,23 @@
 }
 
 
+NumberInfo::Type Result::number_info() {
+  ASSERT(is_valid());
+  if (!is_constant()) return NumberInfoField::decode(value_);
+  Handle<Object> value = handle();
+  if (value->IsSmi()) return NumberInfo::kSmi;
+  if (value->IsHeapNumber()) return NumberInfo::kHeapNumber;
+  return NumberInfo::kUnknown;
+}
+
+
+void Result::set_number_info(NumberInfo::Type info) {
+  ASSERT(is_valid());
+  value_ = value_ & ~NumberInfoField::mask();
+  value_ = value_ | NumberInfoField::encode(info);
+}
+
+
 // -------------------------------------------------------------------------
 // RegisterAllocator implementation.
 
diff --git a/src/register-allocator.h b/src/register-allocator.h
index 0f46996..747200a 100644
--- a/src/register-allocator.h
+++ b/src/register-allocator.h
@@ -29,6 +29,7 @@
 #define V8_REGISTER_ALLOCATOR_H_
 
 #include "macro-assembler.h"
+#include "number-info.h"
 
 #if V8_TARGET_ARCH_IA32
 #include "ia32/register-allocator-ia32.h"
@@ -64,28 +65,21 @@
   Result() { invalidate(); }
 
   // Construct a register Result.
-  explicit Result(Register reg);
+  explicit Result(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
 
   // Construct a Result whose value is a compile-time constant.
   explicit Result(Handle<Object> value) {
     value_ = TypeField::encode(CONSTANT)
+        | NumberInfoField::encode(NumberInfo::kUninitialized)
         | DataField::encode(ConstantList()->length());
     ConstantList()->Add(value);
   }
 
   // The copy constructor and assignment operators could each create a new
   // register reference.
-  Result(const Result& other) {
-    other.CopyTo(this);
-  }
+  inline Result(const Result& other);
 
-  Result& operator=(const Result& other) {
-    if (this != &other) {
-      Unuse();
-      other.CopyTo(this);
-    }
-    return *this;
-  }
+  inline Result& operator=(const Result& other);
 
   inline ~Result();
 
@@ -107,6 +101,14 @@
 
   void invalidate() { value_ = TypeField::encode(INVALID); }
 
+  NumberInfo::Type number_info();
+  void set_number_info(NumberInfo::Type info);
+  bool is_number() {
+    return (number_info() & NumberInfo::kNumber) != 0;
+  }
+  bool is_smi() { return number_info() == NumberInfo::kSmi; }
+  bool is_heap_number() { return number_info() == NumberInfo::kHeapNumber; }
+
   bool is_valid() const { return type() != INVALID; }
   bool is_register() const { return type() == REGISTER; }
   bool is_constant() const { return type() == CONSTANT; }
@@ -138,7 +140,8 @@
   uint32_t value_;
 
   class TypeField: public BitField<Type, 0, 2> {};
-  class DataField: public BitField<uint32_t, 2, 32 - 3> {};
+  class NumberInfoField : public BitField<NumberInfo::Type, 2, 3> {};
+  class DataField: public BitField<uint32_t, 5, 32 - 5> {};
 
   inline void CopyTo(Result* destination) const;
 
@@ -237,18 +240,18 @@
 
   // Predicates and accessors for the registers' reference counts.
   bool is_used(int num) { return registers_.is_used(num); }
-  bool is_used(Register reg) { return registers_.is_used(ToNumber(reg)); }
+  inline bool is_used(Register reg);
 
   int count(int num) { return registers_.count(num); }
-  int count(Register reg) { return registers_.count(ToNumber(reg)); }
+  inline int count(Register reg);
 
   // Explicitly record a reference to a register.
   void Use(int num) { registers_.Use(num); }
-  void Use(Register reg) { registers_.Use(ToNumber(reg)); }
+  inline void Use(Register reg);
 
   // Explicitly record that a register will no longer be used.
   void Unuse(int num) { registers_.Unuse(num); }
-  void Unuse(Register reg) { registers_.Unuse(ToNumber(reg)); }
+  inline void Unuse(Register reg);
 
   // Reset the register reference counts to free all non-reserved registers.
   void Reset() { registers_.Reset(); }
diff --git a/src/runtime.cc b/src/runtime.cc
index aa94ce5..7075542 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1208,17 +1208,6 @@
 }
 
 
-static Object* Runtime_TransformToFastProperties(Arguments args) {
-  HandleScope scope;
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSObject, object, 0);
-  if (!object->HasFastProperties() && !object->IsGlobalObject()) {
-    TransformToFastProperties(object, 0);
-  }
-  return *object;
-}
-
-
 static Object* Runtime_RegExpExec(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 4);
@@ -2287,6 +2276,20 @@
   return -1;
 }
 
+
+template <typename schar>
+static int SingleCharLastIndexOf(Vector<const schar> string,
+                                 schar pattern_char,
+                                 int start_index) {
+  for (int i = start_index; i >= 0; i--) {
+    if (pattern_char == string[i]) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
 // Trivial string search for shorter strings.
 // On return, if "complete" is set to true, the return value is the
 // final result of searching for the patter in the subject.
@@ -2363,7 +2366,7 @@
   // We have an ASCII haystack and a non-ASCII needle. Check if there
   // really is a non-ASCII character in the needle and bail out if there
   // is.
-  if (sizeof(pchar) > 1 && sizeof(schar) == 1) {
+  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
     for (int i = 0; i < pat.length(); i++) {
       uc16 c = pat[i];
       if (c > String::kMaxAsciiCharCode) {
@@ -2466,39 +2469,115 @@
 }
 
 
+template <typename schar, typename pchar>
+static int StringMatchBackwards(Vector<const schar> sub,
+                                Vector<const pchar> pat,
+                                int idx) {
+  ASSERT(pat.length() >= 1);
+  ASSERT(idx + pat.length() <= sub.length());
+
+  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
+    for (int i = 0; i < pat.length(); i++) {
+      uc16 c = pat[i];
+      if (c > String::kMaxAsciiCharCode) {
+        return -1;
+      }
+    }
+  }
+
+  pchar pattern_first_char = pat[0];
+  for (int i = idx; i >= 0; i--) {
+    if (sub[i] != pattern_first_char) continue;
+    int j = 1;
+    while (j < pat.length()) {
+      if (pat[j] != sub[i+j]) {
+        break;
+      }
+      j++;
+    }
+    if (j == pat.length()) {
+      return i;
+    }
+  }
+  return -1;
+}
+
 static Object* Runtime_StringLastIndexOf(Arguments args) {
-  NoHandleAllocation ha;
+  HandleScope scope;  // create a new handle scope
   ASSERT(args.length() == 3);
 
-  CONVERT_CHECKED(String, sub, args[0]);
-  CONVERT_CHECKED(String, pat, args[1]);
+  CONVERT_ARG_CHECKED(String, sub, 0);
+  CONVERT_ARG_CHECKED(String, pat, 1);
+
   Object* index = args[2];
-
-  sub->TryFlattenIfNotFlat();
-  pat->TryFlattenIfNotFlat();
-
   uint32_t start_index;
   if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
 
-  uint32_t pattern_length = pat->length();
+  uint32_t pat_length = pat->length();
   uint32_t sub_length = sub->length();
 
-  if (start_index + pattern_length > sub_length) {
-    start_index = sub_length - pattern_length;
+  if (start_index + pat_length > sub_length) {
+    start_index = sub_length - pat_length;
   }
 
-  for (int i = start_index; i >= 0; i--) {
-    bool found = true;
-    for (uint32_t j = 0; j < pattern_length; j++) {
-      if (sub->Get(i + j) != pat->Get(j)) {
-        found = false;
-        break;
+  if (pat_length == 0) {
+    return Smi::FromInt(start_index);
+  }
+
+  if (!sub->IsFlat()) {
+    FlattenString(sub);
+  }
+
+  if (pat_length == 1) {
+    AssertNoAllocation no_heap_allocation;  // ensure vectors stay valid
+    if (sub->IsAsciiRepresentation()) {
+      uc16 pchar = pat->Get(0);
+      if (pchar > String::kMaxAsciiCharCode) {
+        return Smi::FromInt(-1);
       }
+      return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
+                                                static_cast<char>(pat->Get(0)),
+                                                start_index));
+    } else {
+      return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
+                                                pat->Get(0),
+                                                start_index));
     }
-    if (found) return Smi::FromInt(i);
   }
 
-  return Smi::FromInt(-1);
+  if (!pat->IsFlat()) {
+    FlattenString(pat);
+  }
+
+  AssertNoAllocation no_heap_allocation;  // ensure vectors stay valid
+
+  int position = -1;
+
+  if (pat->IsAsciiRepresentation()) {
+    Vector<const char> pat_vector = pat->ToAsciiVector();
+    if (sub->IsAsciiRepresentation()) {
+      position = StringMatchBackwards(sub->ToAsciiVector(),
+                                      pat_vector,
+                                      start_index);
+    } else {
+      position = StringMatchBackwards(sub->ToUC16Vector(),
+                                      pat_vector,
+                                      start_index);
+    }
+  } else {
+    Vector<const uc16> pat_vector = pat->ToUC16Vector();
+    if (sub->IsAsciiRepresentation()) {
+      position = StringMatchBackwards(sub->ToAsciiVector(),
+                                      pat_vector,
+                                      start_index);
+    } else {
+      position = StringMatchBackwards(sub->ToUC16Vector(),
+                                      pat_vector,
+                                      start_index);
+    }
+  }
+
+  return Smi::FromInt(position);
 }
 
 
@@ -2906,7 +2985,7 @@
   // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
   // delete it to avoid running into trouble in DefineAccessor, which
   // handles this incorrectly if the property is readonly (does nothing)
-  if (result.IsValid() &&
+  if (result.IsProperty() &&
       (result.type() == FIELD || result.type() == NORMAL
        || result.type() == CONSTANT_FUNCTION)) {
     obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
@@ -2937,12 +3016,14 @@
   // correctly in the case where a property is a field and is reset with
   // new attributes.
   if (result.IsProperty() && attr != result.GetAttributes()) {
-    PropertyDetails details = PropertyDetails(attr, NORMAL);
     // New attributes - normalize to avoid writing to instance descriptor
-    js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0);
-    return js_object->SetNormalizedProperty(*name, *obj_value, details);
+    js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+    // Use IgnoreAttributes version since a readonly property may be
+    // overridden and SetProperty does not allow this.
+    return js_object->IgnoreAttributesAndSetLocalProperty(*name,
+                                                          *obj_value,
+                                                          attr);
   }
-
   return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
 }
 
@@ -2969,8 +3050,6 @@
   // 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.
@@ -2990,7 +3069,6 @@
   if (key->IsString()) {
     Handle<Object> result;
     if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
-      ASSERT(attr == NONE);
       result = SetElement(js_object, index, value);
     } else {
       Handle<String> key_string = Handle<String>::cast(key);
@@ -3008,7 +3086,6 @@
   Handle<String> name = Handle<String>::cast(converted);
 
   if (name->AsArrayIndex(&index)) {
-    ASSERT(attr == NONE);
     return js_object->SetElement(index, *value);
   } else {
     return js_object->SetProperty(*name, *value, attr);
@@ -3025,8 +3102,6 @@
   // 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.
@@ -3043,7 +3118,6 @@
 
   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);
@@ -3061,7 +3135,6 @@
   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);
@@ -3520,17 +3593,23 @@
 
 
 static Object* Runtime_ToFastProperties(Arguments args) {
+  HandleScope scope;
+
   ASSERT(args.length() == 1);
   Handle<Object> object = args.at<Object>(0);
   if (object->IsJSObject()) {
     Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-    js_object->TransformToFastProperties(0);
+    if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
+      js_object->TransformToFastProperties(0);
+    }
   }
   return *object;
 }
 
 
 static Object* Runtime_ToSlowProperties(Arguments args) {
+  HandleScope scope;
+
   ASSERT(args.length() == 1);
   Handle<Object> object = args.at<Object>(0);
   if (object->IsJSObject()) {
@@ -4559,6 +4638,7 @@
 static Object* Runtime_Math_abs(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_abs.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return Heap::AllocateHeapNumber(fabs(x));
@@ -4568,6 +4648,7 @@
 static Object* Runtime_Math_acos(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_acos.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::ACOS, x);
@@ -4577,6 +4658,7 @@
 static Object* Runtime_Math_asin(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_asin.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::ASIN, x);
@@ -4586,6 +4668,7 @@
 static Object* Runtime_Math_atan(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_atan.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::ATAN, x);
@@ -4595,6 +4678,7 @@
 static Object* Runtime_Math_atan2(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
+  Counters::math_atan2.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   CONVERT_DOUBLE_CHECKED(y, args[1]);
@@ -4618,6 +4702,7 @@
 static Object* Runtime_Math_ceil(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_ceil.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return Heap::NumberFromDouble(ceiling(x));
@@ -4627,6 +4712,7 @@
 static Object* Runtime_Math_cos(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_cos.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::COS, x);
@@ -4636,6 +4722,7 @@
 static Object* Runtime_Math_exp(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_exp.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::EXP, x);
@@ -4645,6 +4732,7 @@
 static Object* Runtime_Math_floor(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_floor.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return Heap::NumberFromDouble(floor(x));
@@ -4654,6 +4742,7 @@
 static Object* Runtime_Math_log(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_log.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::LOG, x);
@@ -4694,6 +4783,7 @@
 static Object* Runtime_Math_pow(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
+  Counters::math_pow.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
 
@@ -4732,6 +4822,7 @@
 static Object* Runtime_Math_round(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_round.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   if (signbit(x) && x >= -0.5) return Heap::minus_zero_value();
@@ -4744,6 +4835,7 @@
 static Object* Runtime_Math_sin(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_sin.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::SIN, x);
@@ -4753,6 +4845,7 @@
 static Object* Runtime_Math_sqrt(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_sqrt.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return Heap::AllocateHeapNumber(sqrt(x));
@@ -4762,47 +4855,13 @@
 static Object* Runtime_Math_tan(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
+  Counters::math_tan.Increment();
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   return TranscendentalCache::Get(TranscendentalCache::TAN, x);
 }
 
 
-// The NewArguments function is only used when constructing the
-// arguments array when calling non-functions from JavaScript in
-// runtime.js:CALL_NON_FUNCTION.
-static Object* Runtime_NewArguments(Arguments args) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
-
-  // ECMA-262, 3rd., 10.1.8, p.39
-  CONVERT_CHECKED(JSFunction, callee, args[0]);
-
-  // Compute the frame holding the arguments.
-  JavaScriptFrameIterator it;
-  it.AdvanceToArgumentsFrame();
-  JavaScriptFrame* frame = it.frame();
-
-  const int length = frame->GetProvidedParametersCount();
-  Object* result = Heap::AllocateArgumentsObject(callee, length);
-  if (result->IsFailure()) return result;
-  if (length > 0) {
-    Object* obj =  Heap::AllocateFixedArray(length);
-    if (obj->IsFailure()) return obj;
-    FixedArray* array = FixedArray::cast(obj);
-    ASSERT(array->length() == length);
-
-    AssertNoAllocation no_gc;
-    WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
-    for (int i = 0; i < length; i++) {
-      array->set(i, frame->GetParameter(i), mode);
-    }
-    JSObject::cast(result)->set_elements(array);
-  }
-  return result;
-}
-
-
 static Object* Runtime_NewArgumentsFast(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
@@ -4849,21 +4908,21 @@
 }
 
 
-static Code* ComputeConstructStub(Handle<SharedFunctionInfo> shared) {
-  // TODO(385): Change this to create a construct stub specialized for
-  // the given map to make allocation of simple objects - and maybe
-  // arrays - much faster.
-  if (FLAG_inline_new
-      && shared->has_only_simple_this_property_assignments()) {
+static Code* ComputeConstructStub(Handle<JSFunction> function) {
+  Handle<Object> prototype = Factory::null_value();
+  if (function->has_instance_prototype()) {
+    prototype = Handle<Object>(function->instance_prototype());
+  }
+  if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
     ConstructStubCompiler compiler;
-    Object* code = compiler.CompileConstructStub(*shared);
+    Object* code = compiler.CompileConstructStub(function->shared());
     if (code->IsFailure()) {
       return Builtins::builtin(Builtins::JSConstructStubGeneric);
     }
     return Code::cast(code);
   }
 
-  return shared->construct_stub();
+  return function->shared()->construct_stub();
 }
 
 
@@ -4913,10 +4972,9 @@
   bool first_allocation = !function->has_initial_map();
   Handle<JSObject> result = Factory::NewJSObject(function);
   if (first_allocation) {
-    Handle<Map> map = Handle<Map>(function->initial_map());
     Handle<Code> stub = Handle<Code>(
-        ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared())));
-    function->shared()->set_construct_stub(*stub);
+        ComputeConstructStub(Handle<JSFunction>(function)));
+    shared->set_construct_stub(*stub);
   }
 
   Counters::constructed_objects.Increment();
@@ -4955,28 +5013,6 @@
 }
 
 
-static Object* Runtime_GetCalledFunction(Arguments args) {
-  HandleScope scope;
-  ASSERT(args.length() == 0);
-  StackFrameIterator it;
-  // Get past the JS-to-C exit frame.
-  ASSERT(it.frame()->is_exit());
-  it.Advance();
-  // Get past the CALL_NON_FUNCTION activation frame.
-  ASSERT(it.frame()->is_java_script());
-  it.Advance();
-  // Argument adaptor frames do not copy the function; we have to skip
-  // past them to get to the real calling frame.
-  if (it.frame()->is_arguments_adaptor()) it.Advance();
-  // Get the function from the top of the expression stack of the
-  // calling frame.
-  StandardFrame* frame = StandardFrame::cast(it.frame());
-  int index = frame->ComputeExpressionsCount() - 1;
-  Object* result = frame->GetExpression(index);
-  return result;
-}
-
-
 static Object* Runtime_GetFunctionDelegate(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 1);
@@ -7981,20 +8017,22 @@
 
 static Object* Runtime_ProfilerResume(Arguments args) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 2);
 
   CONVERT_CHECKED(Smi, smi_modules, args[0]);
-  v8::V8::ResumeProfilerEx(smi_modules->value());
+  CONVERT_CHECKED(Smi, smi_tag, args[1]);
+  v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
   return Heap::undefined_value();
 }
 
 
 static Object* Runtime_ProfilerPause(Arguments args) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 2);
 
   CONVERT_CHECKED(Smi, smi_modules, args[0]);
-  v8::V8::PauseProfilerEx(smi_modules->value());
+  CONVERT_CHECKED(Smi, smi_tag, args[1]);
+  v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
   return Heap::undefined_value();
 }
 
@@ -8159,15 +8197,6 @@
 }
 
 
-static Object* Runtime_ProfileLogMarker(Arguments args) {
-  ASSERT(args.length() == 1);
-  CONVERT_CHECKED(String, format, args[0]);
-  Vector<const char> marker = format->ToAsciiVector();
-  Logger::LogProfileMarker(marker);
-  return Heap::undefined_value();
-}
-
-
 #ifdef DEBUG
 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
 // Exclude the code in release mode.
diff --git a/src/runtime.h b/src/runtime.h
index 12f969d..e2e5c22 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -71,10 +71,8 @@
   F(IsExtensible, 1, 1) \
   \
   /* Utilities */ \
-  F(GetCalledFunction, 0, 1) \
   F(GetFunctionDelegate, 1, 1) \
   F(GetConstructorDelegate, 1, 1) \
-  F(NewArguments, 1, 1) \
   F(NewArgumentsFast, 3, 1) \
   F(LazyCompile, 1, 1) \
   F(SetNewFunctionAttributes, 1, 1) \
@@ -268,7 +266,6 @@
   F(InitializeConstGlobal, 2, 1) \
   F(InitializeConstContextSlot, 3, 1) \
   F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
-  F(TransformToFastProperties, 1, 1) \
   \
   /* Debugging */ \
   F(DebugPrint, 1, 1) \
@@ -284,11 +281,7 @@
   F(DeleteHandleScopeExtensions, 0, 1) \
   \
   /* Pseudo functions - handled as macros by parser */ \
-  F(IS_VAR, 1, 1) \
-  \
-  /* Profile marker support for more fine grained profiling of page cyclers. */ \
-  /* Also known as a stupid hack. :) */                                 \
-  F(ProfileLogMarker, 1, 1)
+  F(IS_VAR, 1, 1)
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
@@ -335,8 +328,8 @@
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
 #define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F) \
-  F(ProfilerResume, 1, 1) \
-  F(ProfilerPause, 1, 1)
+  F(ProfilerResume, 2, 1) \
+  F(ProfilerPause, 2, 1)
 #else
 #define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
 #endif
diff --git a/src/runtime.js b/src/runtime.js
index 10ef98e..e9d9848 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -178,7 +178,7 @@
       y = %_ValueOf(y);
     } else {
       y = IS_NUMBER(y)
-          ? %NumberToString(y)
+          ? %_NumberToString(y)
           : %ToString(%ToPrimitive(y, NO_HINT));
     }
   }
@@ -194,7 +194,7 @@
       x = %_ValueOf(x);
     } else {
       x = IS_NUMBER(x)
-          ? %NumberToString(x)
+          ? %_NumberToString(x)
           : %ToString(%ToPrimitive(x, NO_HINT));
     }
   }
@@ -395,26 +395,20 @@
 
 
 function CALL_NON_FUNCTION() {
-  var callee = %GetCalledFunction();
-  var delegate = %GetFunctionDelegate(callee);
+  var delegate = %GetFunctionDelegate(this);
   if (!IS_FUNCTION(delegate)) {
-    throw %MakeTypeError('called_non_callable', [typeof callee]);
+    throw %MakeTypeError('called_non_callable', [typeof this]);
   }
-
-  var parameters = %NewArguments(delegate);
-  return delegate.apply(callee, parameters);
+  return delegate.apply(this, arguments);
 }
 
 
 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
-  var callee = %GetCalledFunction();
-  var delegate = %GetConstructorDelegate(callee);
+  var delegate = %GetConstructorDelegate(this);
   if (!IS_FUNCTION(delegate)) {
-    throw %MakeTypeError('called_non_callable', [typeof callee]);
+    throw %MakeTypeError('called_non_callable', [typeof this]);
   }
-
-  var parameters = %NewArguments(delegate);
-  return delegate.apply(callee, parameters);
+  return delegate.apply(this, arguments);
 }
 
 
@@ -529,6 +523,13 @@
 // ECMA-262, section 9.8, page 35.
 function ToString(x) {
   if (IS_STRING(x)) return x;
+  if (IS_NUMBER(x)) return %_NumberToString(x);
+  if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
+  if (IS_UNDEFINED(x)) return 'undefined';
+  return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
+}
+
+function NonStringToString(x) {
   if (IS_NUMBER(x)) return %NumberToString(x);
   if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
   if (IS_UNDEFINED(x)) return 'undefined';
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 8b989d7..de1841b 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -536,7 +536,7 @@
   // Uses only lower 32 bits if pointers are larger.
   uintptr_t addr_hash =
       static_cast<uint32_t>(reinterpret_cast<uintptr_t>(code)) >> 2;
-  return (addr_hash ^ name->Hash()) % kLength;
+  return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
 }
 
 
diff --git a/src/serialize.cc b/src/serialize.cc
index ad8e20f..110e461 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -359,79 +359,87 @@
       UNCLASSIFIED,
       7,
       "Heap::NewSpaceStart()");
-  Add(ExternalReference::heap_always_allocate_scope_depth().address(),
+  Add(ExternalReference::new_space_mask().address(),
       UNCLASSIFIED,
       8,
+      "Heap::NewSpaceMask()");
+  Add(ExternalReference::heap_always_allocate_scope_depth().address(),
+      UNCLASSIFIED,
+      9,
       "Heap::always_allocate_scope_depth()");
   Add(ExternalReference::new_space_allocation_limit_address().address(),
       UNCLASSIFIED,
-      9,
+      10,
       "Heap::NewSpaceAllocationLimitAddress()");
   Add(ExternalReference::new_space_allocation_top_address().address(),
       UNCLASSIFIED,
-      10,
+      11,
       "Heap::NewSpaceAllocationTopAddress()");
 #ifdef ENABLE_DEBUGGER_SUPPORT
   Add(ExternalReference::debug_break().address(),
       UNCLASSIFIED,
-      11,
+      12,
       "Debug::Break()");
   Add(ExternalReference::debug_step_in_fp_address().address(),
       UNCLASSIFIED,
-      12,
+      13,
       "Debug::step_in_fp_addr()");
 #endif
   Add(ExternalReference::double_fp_operation(Token::ADD).address(),
       UNCLASSIFIED,
-      13,
+      14,
       "add_two_doubles");
   Add(ExternalReference::double_fp_operation(Token::SUB).address(),
       UNCLASSIFIED,
-      14,
+      15,
       "sub_two_doubles");
   Add(ExternalReference::double_fp_operation(Token::MUL).address(),
       UNCLASSIFIED,
-      15,
+      16,
       "mul_two_doubles");
   Add(ExternalReference::double_fp_operation(Token::DIV).address(),
       UNCLASSIFIED,
-      16,
+      17,
       "div_two_doubles");
   Add(ExternalReference::double_fp_operation(Token::MOD).address(),
       UNCLASSIFIED,
-      17,
+      18,
       "mod_two_doubles");
   Add(ExternalReference::compare_doubles().address(),
       UNCLASSIFIED,
-      18,
+      19,
       "compare_doubles");
 #ifdef V8_NATIVE_REGEXP
   Add(ExternalReference::re_case_insensitive_compare_uc16().address(),
       UNCLASSIFIED,
-      19,
+      20,
       "NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()");
   Add(ExternalReference::re_check_stack_guard_state().address(),
       UNCLASSIFIED,
-      20,
+      21,
       "RegExpMacroAssembler*::CheckStackGuardState()");
   Add(ExternalReference::re_grow_stack().address(),
       UNCLASSIFIED,
-      21,
+      22,
       "NativeRegExpMacroAssembler::GrowStack()");
   Add(ExternalReference::re_word_character_map().address(),
       UNCLASSIFIED,
-      22,
+      23,
       "NativeRegExpMacroAssembler::word_character_map");
 #endif
   // Keyed lookup cache.
   Add(ExternalReference::keyed_lookup_cache_keys().address(),
       UNCLASSIFIED,
-      23,
+      24,
       "KeyedLookupCache::keys()");
   Add(ExternalReference::keyed_lookup_cache_field_offsets().address(),
       UNCLASSIFIED,
-      24,
+      25,
       "KeyedLookupCache::field_offsets()");
+  Add(ExternalReference::transcendental_cache_array_address().address(),
+      UNCLASSIFIED,
+      26,
+      "TranscendentalCache::caches()");
 }
 
 
@@ -852,10 +860,10 @@
   const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7;
   for (int shift = max_shift; shift > 0; shift -= 7) {
     if (integer >= static_cast<uintptr_t>(1u) << shift) {
-      Put(((integer >> shift) & 0x7f) | 0x80, "IntPart");
+      Put((static_cast<int>((integer >> shift)) & 0x7f) | 0x80, "IntPart");
     }
   }
-  PutSection(integer & 0x7f, "IntLastPart");
+  PutSection(static_cast<int>(integer & 0x7f), "IntLastPart");
 }
 
 #ifdef DEBUG
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index 4fd8a6c..72f8305 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -183,7 +183,7 @@
 
 int MemoryAllocator::GetChunkId(Page* p) {
   ASSERT(p->is_valid());
-  return p->opaque_header & Page::kPageAlignmentMask;
+  return static_cast<int>(p->opaque_header & Page::kPageAlignmentMask);
 }
 
 
diff --git a/src/string.js b/src/string.js
index b2af050..a8fc8d4 100644
--- a/src/string.js
+++ b/src/string.js
@@ -34,7 +34,7 @@
 
 // Set the String function and constructor.
 %SetCode($String, function(x) {
-  var value = %_ArgumentsLength() == 0 ? '' : ToString(x);
+  var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x);
   if (%_IsConstructCall()) {
     %_SetValueOf(this, value);
   } else {
@@ -64,7 +64,7 @@
 function StringCharAt(pos) {
   var char_code = %_FastCharCodeAt(this, pos);
   if (!%_IsSmi(char_code)) {
-    var subject = ToString(this);
+    var subject = TO_STRING_INLINE(this);
     var index = TO_INTEGER(pos);
     if (index >= subject.length || index < 0) return "";
     char_code = %StringCharCodeAt(subject, index);
@@ -79,7 +79,7 @@
   if (%_IsSmi(fast_answer)) {
     return fast_answer;
   }
-  var subject = ToString(this);
+  var subject = TO_STRING_INLINE(this);
   var index = TO_INTEGER(pos);
   return %StringCharCodeAt(subject, index);
 }
@@ -87,14 +87,18 @@
 
 // ECMA-262, section 15.5.4.6
 function StringConcat() {
-  var len = %_ArgumentsLength() + 1;
-  var parts = new $Array(len);
-  parts[0] = IS_STRING(this) ? this : ToString(this);
-  for (var i = 1; i < len; i++) {
-    var part = %_Arguments(i - 1);
-    parts[i] = IS_STRING(part) ? part : ToString(part);
+  var len = %_ArgumentsLength();
+  var this_as_string = TO_STRING_INLINE(this);
+  if (len === 1) {
+    return this_as_string + %_Arguments(0);
   }
-  return %StringBuilderConcat(parts, len, "");
+  var parts = new $Array(len + 1);
+  parts[0] = this_as_string;
+  for (var i = 0; i < len; i++) {
+    var part = %_Arguments(i);
+    parts[i + 1] = TO_STRING_INLINE(part);
+  }
+  return %StringBuilderConcat(parts, len + 1, "");
 }
 
 // Match ES3 and Safari
@@ -103,8 +107,8 @@
 
 // ECMA-262 section 15.5.4.7
 function StringIndexOf(searchString /* position */) {  // length == 1
-  var subject_str = ToString(this);
-  var pattern_str = ToString(searchString);
+  var subject_str = TO_STRING_INLINE(this);
+  var pattern_str = TO_STRING_INLINE(searchString);
   var subject_str_len = subject_str.length;
   var pattern_str_len = pattern_str.length;
   var index = 0;
@@ -121,9 +125,9 @@
 
 // ECMA-262 section 15.5.4.8
 function StringLastIndexOf(searchString /* position */) {  // length == 1
-  var sub = ToString(this);
+  var sub = TO_STRING_INLINE(this);
   var subLength = sub.length;
-  var pat = ToString(searchString);
+  var pat = TO_STRING_INLINE(searchString);
   var patLength = pat.length;
   var index = subLength - patLength;
   if (%_ArgumentsLength() > 1) {
@@ -152,8 +156,8 @@
 function StringLocaleCompare(other) {
   if (%_ArgumentsLength() === 0) return 0;
 
-  var this_str = ToString(this);
-  var other_str = ToString(other);
+  var this_str = TO_STRING_INLINE(this);
+  var other_str = TO_STRING_INLINE(other);
   return %StringLocaleCompare(this_str, other_str);
 }
 
@@ -161,7 +165,7 @@
 // ECMA-262 section 15.5.4.10
 function StringMatch(regexp) {
   if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp);
-  var subject = ToString(this);
+  var subject = TO_STRING_INLINE(this);
 
   if (!regexp.global) return regexp.exec(subject);
   %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
@@ -196,7 +200,7 @@
 
 // ECMA-262, section 15.5.4.11
 function StringReplace(search, replace) {
-  var subject = IS_STRING(this) ? this : ToString(this);
+  var subject = TO_STRING_INLINE(this);
 
   // Delegate to one of the regular expression variants if necessary.
   if (IS_REGEXP(search)) {
@@ -209,7 +213,7 @@
   }
 
   // Convert the search argument to a string and search for it.
-  search = IS_STRING(search) ? search : ToString(search);
+  search = TO_STRING_INLINE(search);
   var start = %StringIndexOf(subject, search, 0);
   if (start < 0) return subject;
   var end = start + search.length;
@@ -224,7 +228,7 @@
   } else {
     reusableMatchInfo[CAPTURE0] = start;
     reusableMatchInfo[CAPTURE1] = end;
-    if (!IS_STRING(replace)) replace = ToString(replace);
+    replace = TO_STRING_INLINE(replace);
     ExpandReplacement(replace, subject, reusableMatchInfo, builder);
   }
 
@@ -237,7 +241,7 @@
 
 // Helper function for regular expressions in String.prototype.replace.
 function StringReplaceRegExp(subject, regexp, replace) {
-  replace = ToString(replace);
+  replace = TO_STRING_INLINE(replace);
   return %StringReplaceRegExpWithString(subject,
                                         regexp,
                                         replace,
@@ -458,7 +462,7 @@
 // ECMA-262 section 15.5.4.12
 function StringSearch(re) {
   var regexp = new $RegExp(re);
-  var s = ToString(this);
+  var s = TO_STRING_INLINE(this);
   var last_idx = regexp.lastIndex; // keep old lastIndex
   regexp.lastIndex = 0;            // ignore re.global property
   var result = regexp.exec(s);
@@ -472,7 +476,7 @@
 
 // ECMA-262 section 15.5.4.13
 function StringSlice(start, end) {
-  var s = ToString(this);
+  var s = TO_STRING_INLINE(this);
   var s_len = s.length;
   var start_i = TO_INTEGER(start);
   var end_i = s_len;
@@ -507,7 +511,7 @@
 
 // ECMA-262 section 15.5.4.14
 function StringSplit(separator, limit) {
-  var subject = ToString(this);
+  var subject = TO_STRING_INLINE(this);
   limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit);
   if (limit === 0) return [];
 
@@ -521,18 +525,35 @@
   }
 
   var length = subject.length;
-  if (IS_REGEXP(separator)) {
-    %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
-  } else {
-    separator = ToString(separator);
+  if (!IS_REGEXP(separator)) {
+    separator = TO_STRING_INLINE(separator);
+    var separator_length = separator.length;
+
     // If the separator string is empty then return the elements in the subject.
-    if (separator.length == 0) {
+    if (separator_length === 0) {
       var result = $Array(length);
       for (var i = 0; i < length; i++) result[i] = subject[i];
       return result;
     }
+
+    var result = [];
+    var start_index = 0;
+    var index;
+    while (true) {
+      if (start_index + separator_length > length ||
+          (index = %StringIndexOf(subject, separator, start_index)) === -1) {
+        result.push(SubString(subject, start_index, length));
+        break;
+      }
+      if (result.push(SubString(subject, start_index, index)) === limit) break;
+      start_index = index + separator_length;
+    }
+
+    return result;
   }
 
+  %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
+
   if (length === 0) {
     if (splitMatch(separator, subject, 0, 0) != null) return [];
     return [subject];
@@ -567,7 +588,8 @@
     result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0]);
     if (result.length === limit) return result;
 
-    for (var i = 2; i < NUMBER_OF_CAPTURES(matchInfo); i += 2) {
+    var num_captures = NUMBER_OF_CAPTURES(matchInfo);
+    for (var i = 2; i < num_captures; i += 2) {
       var start = matchInfo[CAPTURE(i)];
       var end = matchInfo[CAPTURE(i + 1)];
       if (start != -1 && end != -1) {
@@ -587,28 +609,18 @@
 // Helper function used by split.  This version returns the matchInfo
 // instead of allocating a new array with basically the same information.
 function splitMatch(separator, subject, current_index, start_index) {
-  if (IS_REGEXP(separator)) {
-    var matchInfo = DoRegExpExec(separator, subject, start_index);
-    if (matchInfo == null) return null;
-    // Section 15.5.4.14 paragraph two says that we do not allow zero length
-    // matches at the end of the string.
-    if (matchInfo[CAPTURE0] === subject.length) return null;
-    return matchInfo;
-  }
-
-  var separatorIndex = subject.indexOf(separator, start_index);
-  if (separatorIndex === -1) return null;
-
-  reusableMatchInfo[CAPTURE0] = separatorIndex;
-  reusableMatchInfo[CAPTURE1] = separatorIndex + separator.length;
-  return reusableMatchInfo;
-};
+  var matchInfo = DoRegExpExec(separator, subject, start_index);
+  if (matchInfo == null) return null;
+  // Section 15.5.4.14 paragraph two says that we do not allow zero length
+  // matches at the end of the string.
+  if (matchInfo[CAPTURE0] === subject.length) return null;
+  return matchInfo;
+}
 
 
 // ECMA-262 section 15.5.4.15
 function StringSubstring(start, end) {
-  var s = this;
-  if (!IS_STRING(s)) s = ToString(s);
+  var s = TO_STRING_INLINE(this);
   var s_len = s.length;
 
   var start_i = TO_INTEGER(start);
@@ -639,7 +651,7 @@
 
 // This is not a part of ECMA-262.
 function StringSubstr(start, n) {
-  var s = ToString(this);
+  var s = TO_STRING_INLINE(this);
   var len;
 
   // Correct n: If not given, set to string length; if explicitly
@@ -677,38 +689,38 @@
 
 // ECMA-262, 15.5.4.16
 function StringToLowerCase() {
-  return %StringToLowerCase(ToString(this));
+  return %StringToLowerCase(TO_STRING_INLINE(this));
 }
 
 
 // ECMA-262, 15.5.4.17
 function StringToLocaleLowerCase() {
-  return %StringToLowerCase(ToString(this));
+  return %StringToLowerCase(TO_STRING_INLINE(this));
 }
 
 
 // ECMA-262, 15.5.4.18
 function StringToUpperCase() {
-  return %StringToUpperCase(ToString(this));
+  return %StringToUpperCase(TO_STRING_INLINE(this));
 }
 
 
 // ECMA-262, 15.5.4.19
 function StringToLocaleUpperCase() {
-  return %StringToUpperCase(ToString(this));
+  return %StringToUpperCase(TO_STRING_INLINE(this));
 }
 
 // ES5, 15.5.4.20
 function StringTrim() {
-  return %StringTrim(ToString(this), true, true);
+  return %StringTrim(TO_STRING_INLINE(this), true, true);
 }
 
 function StringTrimLeft() {
-  return %StringTrim(ToString(this), true, false);
+  return %StringTrim(TO_STRING_INLINE(this), true, false);
 }
 
 function StringTrimRight() {
-  return %StringTrim(ToString(this), false, true);
+  return %StringTrim(TO_STRING_INLINE(this), false, true);
 }
 
 // ECMA-262, section 15.5.3.2
@@ -727,10 +739,10 @@
 
 // Helper function for very basic XSS protection.
 function HtmlEscape(str) {
-  return ToString(str).replace(/</g, "&lt;")
-                      .replace(/>/g, "&gt;")
-                      .replace(/"/g, "&quot;")
-                      .replace(/'/g, "&#039;");
+  return TO_STRING_INLINE(str).replace(/</g, "&lt;")
+                              .replace(/>/g, "&gt;")
+                              .replace(/"/g, "&quot;")
+                              .replace(/'/g, "&#039;");
 };
 
 
@@ -809,7 +821,7 @@
 
 
 ReplaceResultBuilder.prototype.add = function(str) {
-  if (!IS_STRING(str)) str = ToString(str);
+  str = TO_STRING_INLINE(str);
   if (str.length > 0) {
     var elements = this.elements;
     elements[elements.length] = str;
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 81f89fd..577c2d7 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -105,7 +105,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -124,7 +124,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -143,7 +143,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -160,7 +160,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -189,7 +189,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -351,7 +351,7 @@
     if (code->IsFailure()) return code;
     LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -484,7 +484,10 @@
   Object* code = map->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
     CallStubCompiler compiler(argc, in_loop);
-    code = compiler.CompileCallField(object, holder, index, name);
+    code = compiler.CompileCallField(JSObject::cast(object),
+                                     holder,
+                                     index,
+                                     name);
     if (code->IsFailure()) return code;
     ASSERT_EQ(flags, Code::cast(code)->flags());
     LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
@@ -518,7 +521,9 @@
   Object* code = map->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
     CallStubCompiler compiler(argc, NOT_IN_LOOP);
-    code = compiler.CompileCallInterceptor(object, holder, name);
+    code = compiler.CompileCallInterceptor(JSObject::cast(object),
+                                           holder,
+                                           name);
     if (code->IsFailure()) return code;
     ASSERT_EQ(flags, Code::cast(code)->flags());
     LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
@@ -561,7 +566,7 @@
     ASSERT_EQ(flags, Code::cast(code)->flags());
     LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
     Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
-    if (result->IsFailure()) return code;
+    if (result->IsFailure()) return result;
   }
   return Set(name, receiver->map(), Code::cast(code));
 }
@@ -920,6 +925,13 @@
 }
 
 
+Object* KeyedLoadPropertyWithInterceptor(Arguments args) {
+  JSObject* receiver = JSObject::cast(args[0]);
+  uint32_t index = Smi::cast(args[1])->value();
+  return receiver->GetElementWithInterceptor(receiver, index);
+}
+
+
 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) {
   HandleScope scope;
   int argc = Code::ExtractArgumentsCountFromFlags(flags);
@@ -1058,11 +1070,13 @@
   return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
 }
 
+
 void StubCompiler::LookupPostInterceptor(JSObject* holder,
                                          String* name,
                                          LookupResult* lookup) {
   holder->LocalLookupRealNamedProperty(name, lookup);
-  if (lookup->IsNotFound()) {
+  if (!lookup->IsProperty()) {
+    lookup->NotFound();
     Object* proto = holder->GetPrototype();
     if (proto != Heap::null_value()) {
       proto->Lookup(name, lookup);
diff --git a/src/stub-cache.h b/src/stub-cache.h
index d97fe77..43354db 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -312,6 +312,7 @@
 Object* LoadPropertyWithInterceptorForCall(Arguments args);
 Object* StoreInterceptorProperty(Arguments args);
 Object* CallInterceptorProperty(Arguments args);
+Object* KeyedLoadPropertyWithInterceptor(Arguments args);
 
 
 // Support function for computing call IC miss stubs.
@@ -346,6 +347,7 @@
   static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
                                                   int index,
                                                   Register prototype);
+
   static void GenerateFastPropertyLoad(MacroAssembler* masm,
                                        Register dst, Register src,
                                        JSObject* holder, int index);
@@ -354,22 +356,20 @@
                                       Register receiver,
                                       Register scratch,
                                       Label* miss_label);
+
   static void GenerateLoadStringLength(MacroAssembler* masm,
                                        Register receiver,
-                                       Register scratch,
+                                       Register scratch1,
+                                       Register scratch2,
                                        Label* miss_label);
-  static void GenerateLoadStringLength2(MacroAssembler* masm,
-                                        Register receiver,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Label* miss_label);
+
   static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
                                             Register receiver,
                                             Register scratch1,
                                             Register scratch2,
                                             Label* miss_label);
+
   static void GenerateStoreField(MacroAssembler* masm,
-                                 Builtins::Name storage_extend,
                                  JSObject* object,
                                  int index,
                                  Map* transition,
@@ -377,16 +377,30 @@
                                  Register name_reg,
                                  Register scratch,
                                  Label* miss_label);
+
   static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);
 
   // Check the integrity of the prototype chain to make sure that the
   // current IC is still valid.
+
   Register CheckPrototypes(JSObject* object,
                            Register object_reg,
                            JSObject* holder,
                            Register holder_reg,
                            Register scratch,
                            String* name,
+                           Label* miss) {
+    return CheckPrototypes(object, object_reg, holder, holder_reg, scratch,
+                           name, kInvalidProtoDepth, miss);
+  }
+
+  Register CheckPrototypes(JSObject* object,
+                           Register object_reg,
+                           JSObject* holder,
+                           Register holder_reg,
+                           Register scratch,
+                           String* name,
+                           int save_at_depth,
                            Label* miss);
 
  protected:
@@ -538,7 +552,7 @@
   explicit CallStubCompiler(int argc, InLoopFlag in_loop)
       : arguments_(argc), in_loop_(in_loop) { }
 
-  Object* CompileCallField(Object* object,
+  Object* CompileCallField(JSObject* object,
                            JSObject* holder,
                            int index,
                            String* name);
@@ -547,7 +561,7 @@
                               JSFunction* function,
                               String* name,
                               CheckType check);
-  Object* CompileCallInterceptor(Object* object,
+  Object* CompileCallInterceptor(JSObject* object,
                                  JSObject* holder,
                                  String* name);
   Object* CompileCallGlobal(JSObject* object,
diff --git a/src/top.cc b/src/top.cc
index 056d384..d174175 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -949,10 +949,15 @@
 }
 
 
+bool Top::CanHaveSpecialFunctions(JSObject* object) {
+  return object->IsJSArray();
+}
+
+
 Object* Top::LookupSpecialFunction(JSObject* receiver,
                                    JSObject* prototype,
                                    JSFunction* function) {
-  if (receiver->IsJSArray()) {
+  if (CanHaveSpecialFunctions(receiver)) {
     FixedArray* table = context()->global_context()->special_function_table();
     for (int index = 0; index < table->length(); index +=3) {
       if ((prototype == table->get(index)) &&
diff --git a/src/top.h b/src/top.h
index 8780844..ddc73ba 100644
--- a/src/top.h
+++ b/src/top.h
@@ -342,6 +342,7 @@
     return Handle<JSBuiltinsObject>(thread_local_.context_->builtins());
   }
 
+  static bool CanHaveSpecialFunctions(JSObject* object);
   static Object* LookupSpecialFunction(JSObject* receiver,
                                        JSObject* prototype,
                                        JSFunction* value);
diff --git a/src/utils.cc b/src/utils.cc
index 374385b..45a4cd6 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -51,43 +51,6 @@
 }
 
 
-byte* EncodeInt(byte* p, int x) {
-  while (x < -64 || x >= 64) {
-    *p++ = static_cast<byte>(x & 127);
-    x = ArithmeticShiftRight(x, 7);
-  }
-  // -64 <= x && x < 64
-  *p++ = static_cast<byte>(x + 192);
-  return p;
-}
-
-
-byte* DecodeInt(byte* p, int* x) {
-  int r = 0;
-  unsigned int s = 0;
-  byte b = *p++;
-  while (b < 128) {
-    r |= static_cast<int>(b) << s;
-    s += 7;
-    b = *p++;
-  }
-  // b >= 128
-  *x = r | ((static_cast<int>(b) - 192) << s);
-  return p;
-}
-
-
-byte* EncodeUnsignedIntBackward(byte* p, unsigned int x) {
-  while (x >= 128) {
-    *--p = static_cast<byte>(x & 127);
-    x = x >> 7;
-  }
-  // x < 128
-  *--p = static_cast<byte>(x + 128);
-  return p;
-}
-
-
 // Thomas Wang, Integer Hash Functions.
 // http://www.concentric.net/~Ttwang/tech/inthash.htm
 uint32_t ComputeIntegerHash(uint32_t key) {
diff --git a/src/utils.h b/src/utils.h
index 0fd24ec..2fcd241 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -157,7 +157,9 @@
 
   // Returns a uint32_t mask of bit field.
   static uint32_t mask() {
-    return (1U << (size + shift)) - (1U << shift);
+    // To use all bits of a uint32 in a bitfield without compiler warnings we
+    // have to compute 2^32 without using a shift count of 32.
+    return ((1U << shift) << size) - (1U << shift);
   }
 
   // Returns a uint32_t with the bit field value encoded.
@@ -168,54 +170,12 @@
 
   // Extracts the bit field from the value.
   static T decode(uint32_t value) {
-    return static_cast<T>((value >> shift) & ((1U << (size)) - 1));
+    return static_cast<T>((value & mask()) >> shift);
   }
 };
 
 
 // ----------------------------------------------------------------------------
-// Support for compressed, machine-independent encoding
-// and decoding of integer values of arbitrary size.
-
-// Encoding and decoding from/to a buffer at position p;
-// the result is the position after the encoded integer.
-// Small signed integers in the range -64 <= x && x < 64
-// are encoded in 1 byte; larger values are encoded in 2
-// or more bytes. At most sizeof(int) + 1 bytes are used
-// in the worst case.
-byte* EncodeInt(byte* p, int x);
-byte* DecodeInt(byte* p, int* x);
-
-
-// Encoding and decoding from/to a buffer at position p - 1
-// moving backward; the result is the position of the last
-// byte written. These routines are useful to read/write
-// into a buffer starting at the end of the buffer.
-byte* EncodeUnsignedIntBackward(byte* p, unsigned int x);
-
-// The decoding function is inlined since its performance is
-// important to mark-sweep garbage collection.
-inline byte* DecodeUnsignedIntBackward(byte* p, unsigned int* x) {
-  byte b = *--p;
-  if (b >= 128) {
-    *x = static_cast<unsigned int>(b) - 128;
-    return p;
-  }
-  unsigned int r = static_cast<unsigned int>(b);
-  unsigned int s = 7;
-  b = *--p;
-  while (b < 128) {
-    r |= static_cast<unsigned int>(b) << s;
-    s += 7;
-    b = *--p;
-  }
-  // b >= 128
-  *x = r | ((static_cast<unsigned int>(b) - 128) << s);
-  return p;
-}
-
-
-// ----------------------------------------------------------------------------
 // Hash function.
 
 uint32_t ComputeIntegerHash(uint32_t key);
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 2d24765..1ba2003 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -104,71 +104,94 @@
   SC(contexts_created_by_snapshot, V8.ContextsCreatedBySnapshot)
 
 
+#define STATS_COUNTER_LIST_2(SC)                                      \
+  /* Number of code stubs. */                                         \
+  SC(code_stubs, V8.CodeStubs)                                        \
+  /* Amount of stub code. */                                          \
+  SC(total_stubs_code_size, V8.TotalStubsCodeSize)                    \
+  /* Amount of (JS) compiled code. */                                 \
+  SC(total_compiled_code_size, V8.TotalCompiledCodeSize)              \
+  SC(gc_compactor_caused_by_request, V8.GCCompactorCausedByRequest)   \
+  SC(gc_compactor_caused_by_promoted_data,                            \
+     V8.GCCompactorCausedByPromotedData)                              \
+  SC(gc_compactor_caused_by_oldspace_exhaustion,                      \
+     V8.GCCompactorCausedByOldspaceExhaustion)                        \
+  SC(gc_compactor_caused_by_weak_handles,                             \
+     V8.GCCompactorCausedByWeakHandles)                               \
+  SC(gc_last_resort_from_js, V8.GCLastResortFromJS)                   \
+  SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles)         \
+  /* How is the generic keyed-load stub used? */                      \
+  SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi)                  \
+  SC(keyed_load_generic_symbol, V8.KeyedLoadGenericSymbol)            \
+  SC(keyed_load_generic_slow, V8.KeyedLoadGenericSlow)                \
+  SC(keyed_load_external_array_slow, V8.KeyedLoadExternalArraySlow)   \
+  /* Count how much the monomorphic keyed-load stubs are hit. */      \
+  SC(keyed_load_function_prototype, V8.KeyedLoadFunctionPrototype)    \
+  SC(keyed_load_string_length, V8.KeyedLoadStringLength)              \
+  SC(keyed_load_array_length, V8.KeyedLoadArrayLength)                \
+  SC(keyed_load_constant_function, V8.KeyedLoadConstantFunction)      \
+  SC(keyed_load_field, V8.KeyedLoadField)                             \
+  SC(keyed_load_callback, V8.KeyedLoadCallback)                       \
+  SC(keyed_load_interceptor, V8.KeyedLoadInterceptor)                 \
+  SC(keyed_load_inline, V8.KeyedLoadInline)                           \
+  SC(keyed_load_inline_miss, V8.KeyedLoadInlineMiss)                  \
+  SC(named_load_inline, V8.NamedLoadInline)                           \
+  SC(named_load_inline_miss, V8.NamedLoadInlineMiss)                  \
+  SC(named_load_global_inline, V8.NamedLoadGlobalInline)              \
+  SC(named_load_global_inline_miss, V8.NamedLoadGlobalInlineMiss)     \
+  SC(keyed_store_field, V8.KeyedStoreField)                           \
+  SC(keyed_store_inline, V8.KeyedStoreInline)                         \
+  SC(keyed_store_inline_miss, V8.KeyedStoreInlineMiss)                \
+  SC(named_store_global_inline, V8.NamedStoreGlobalInline)            \
+  SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss)   \
+  SC(call_const, V8.CallConst)                                        \
+  SC(call_const_fast_api, V8.CallConstFastApi)                        \
+  SC(call_const_interceptor, V8.CallConstInterceptor)                 \
+  SC(call_const_interceptor_fast_api, V8.CallConstInterceptorFastApi) \
+  SC(call_global_inline, V8.CallGlobalInline)                         \
+  SC(call_global_inline_miss, V8.CallGlobalInlineMiss)                \
+  SC(constructed_objects, V8.ConstructedObjects)                      \
+  SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime)       \
+  SC(constructed_objects_stub, V8.ConstructedObjectsStub)             \
+  SC(array_function_runtime, V8.ArrayFunctionRuntime)                 \
+  SC(array_function_native, V8.ArrayFunctionNative)                   \
+  SC(for_in, V8.ForIn)                                                \
+  SC(enum_cache_hits, V8.EnumCacheHits)                               \
+  SC(enum_cache_misses, V8.EnumCacheMisses)                           \
+  SC(reloc_info_count, V8.RelocInfoCount)                             \
+  SC(reloc_info_size, V8.RelocInfoSize)                               \
+  SC(zone_segment_bytes, V8.ZoneSegmentBytes)                         \
+  SC(compute_entry_frame, V8.ComputeEntryFrame)                       \
+  SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls)            \
+  SC(generic_binary_stub_calls_regs, V8.GenericBinaryStubCallsRegs)   \
+  SC(string_add_runtime, V8.StringAddRuntime)                         \
+  SC(string_add_native, V8.StringAddNative)                           \
+  SC(sub_string_runtime, V8.SubStringRuntime)                         \
+  SC(sub_string_native, V8.SubStringNative)                           \
+  SC(string_compare_native, V8.StringCompareNative)                   \
+  SC(string_compare_runtime, V8.StringCompareRuntime)                 \
+  SC(regexp_entry_runtime, V8.RegExpEntryRuntime)                     \
+  SC(regexp_entry_native, V8.RegExpEntryNative)                       \
+  SC(number_to_string_native, V8.NumberToStringNative)                \
+  SC(number_to_string_runtime, V8.NumberToStringRuntime)              \
+  SC(math_abs, V8.MathAbs)                                            \
+  SC(math_acos, V8.MathAcos)                                          \
+  SC(math_asin, V8.MathAsin)                                          \
+  SC(math_atan, V8.MathAtan)                                          \
+  SC(math_atan2, V8.MathAtan2)                                        \
+  SC(math_ceil, V8.MathCeil)                                          \
+  SC(math_cos, V8.MathCos)                                            \
+  SC(math_exp, V8.MathExp)                                            \
+  SC(math_floor, V8.MathFloor)                                        \
+  SC(math_log, V8.MathLog)                                            \
+  SC(math_pow, V8.MathPow)                                            \
+  SC(math_round, V8.MathRound)                                        \
+  SC(math_sin, V8.MathSin)                                            \
+  SC(math_sqrt, V8.MathSqrt)                                          \
+  SC(math_tan, V8.MathTan)                                            \
+  SC(transcendental_cache_hit, V8.TranscendentalCacheHit)             \
+  SC(transcendental_cache_miss, V8.TranscendentalCacheMiss)
 
-#define STATS_COUNTER_LIST_2(SC)                                    \
-  /* Number of code stubs. */                                       \
-  SC(code_stubs, V8.CodeStubs)                                      \
-  /* Amount of stub code. */                                        \
-  SC(total_stubs_code_size, V8.TotalStubsCodeSize)                  \
-  /* Amount of (JS) compiled code. */                               \
-  SC(total_compiled_code_size, V8.TotalCompiledCodeSize)            \
-  SC(gc_compactor_caused_by_request, V8.GCCompactorCausedByRequest) \
-  SC(gc_compactor_caused_by_promoted_data,                          \
-     V8.GCCompactorCausedByPromotedData)                            \
-  SC(gc_compactor_caused_by_oldspace_exhaustion,                    \
-     V8.GCCompactorCausedByOldspaceExhaustion)                      \
-  SC(gc_compactor_caused_by_weak_handles,                           \
-     V8.GCCompactorCausedByWeakHandles)                             \
-  SC(gc_last_resort_from_js, V8.GCLastResortFromJS)                 \
-  SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles)       \
-  /* How is the generic keyed-load stub used? */                    \
-  SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi)                \
-  SC(keyed_load_generic_symbol, V8.KeyedLoadGenericSymbol)          \
-  SC(keyed_load_generic_slow, V8.KeyedLoadGenericSlow)              \
-  SC(keyed_load_external_array_slow, V8.KeyedLoadExternalArraySlow) \
-  /* Count how much the monomorphic keyed-load stubs are hit. */    \
-  SC(keyed_load_function_prototype, V8.KeyedLoadFunctionPrototype)  \
-  SC(keyed_load_string_length, V8.KeyedLoadStringLength)            \
-  SC(keyed_load_array_length, V8.KeyedLoadArrayLength)              \
-  SC(keyed_load_constant_function, V8.KeyedLoadConstantFunction)    \
-  SC(keyed_load_field, V8.KeyedLoadField)                           \
-  SC(keyed_load_callback, V8.KeyedLoadCallback)                     \
-  SC(keyed_load_interceptor, V8.KeyedLoadInterceptor)               \
-  SC(keyed_load_inline, V8.KeyedLoadInline)                         \
-  SC(keyed_load_inline_miss, V8.KeyedLoadInlineMiss)                \
-  SC(named_load_inline, V8.NamedLoadInline)                         \
-  SC(named_load_inline_miss, V8.NamedLoadInlineMiss)                \
-  SC(named_load_global_inline, V8.NamedLoadGlobalInline)            \
-  SC(named_load_global_inline_miss, V8.NamedLoadGlobalInlineMiss)   \
-  SC(keyed_store_field, V8.KeyedStoreField)                         \
-  SC(keyed_store_inline, V8.KeyedStoreInline)                       \
-  SC(keyed_store_inline_miss, V8.KeyedStoreInlineMiss)              \
-  SC(named_store_global_inline, V8.NamedStoreGlobalInline)          \
-  SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \
-  SC(call_global_inline, V8.CallGlobalInline)                       \
-  SC(call_global_inline_miss, V8.CallGlobalInlineMiss)              \
-  SC(constructed_objects, V8.ConstructedObjects)                    \
-  SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime)     \
-  SC(constructed_objects_stub, V8.ConstructedObjectsStub)           \
-  SC(array_function_runtime, V8.ArrayFunctionRuntime)               \
-  SC(array_function_native, V8.ArrayFunctionNative)                 \
-  SC(for_in, V8.ForIn)                                              \
-  SC(enum_cache_hits, V8.EnumCacheHits)                             \
-  SC(enum_cache_misses, V8.EnumCacheMisses)                         \
-  SC(reloc_info_count, V8.RelocInfoCount)                           \
-  SC(reloc_info_size, V8.RelocInfoSize)                             \
-  SC(zone_segment_bytes, V8.ZoneSegmentBytes)                       \
-  SC(compute_entry_frame, V8.ComputeEntryFrame)                     \
-  SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls)          \
-  SC(generic_binary_stub_calls_regs, V8.GenericBinaryStubCallsRegs) \
-  SC(string_add_runtime, V8.StringAddRuntime)                       \
-  SC(string_add_native, V8.StringAddNative)                         \
-  SC(sub_string_runtime, V8.SubStringRuntime)                       \
-  SC(sub_string_native, V8.SubStringNative)                         \
-  SC(string_compare_native, V8.StringCompareNative)                 \
-  SC(string_compare_runtime, V8.StringCompareRuntime)               \
-  SC(regexp_entry_runtime, V8.RegExpEntryRuntime)                   \
-  SC(regexp_entry_native, V8.RegExpEntryNative)
 
 // This file contains all the v8 counters that are in use.
 class Counters : AllStatic {
diff --git a/src/v8natives.js b/src/v8natives.js
index 5a47211..6a32d7b 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -56,7 +56,7 @@
     %FunctionSetName(f, key);
     %SetProperty(object, key, f, attributes);
   }
-  %TransformToFastProperties(object);
+  %ToFastProperties(object);
 }
 
 // Emulates JSC by installing functions on a hidden prototype that
@@ -623,9 +623,8 @@
   if (%GetInterceptorInfo(obj) & 1) {
     var indexedInterceptorNames =
         %GetIndexedInterceptorElementNames(obj);
-    if (indexedInterceptorNames) {
+    if (indexedInterceptorNames)
       propertyNames = propertyNames.concat(indexedInterceptorNames);
-    }
   }
 
   // Find all the named properties.
@@ -643,6 +642,10 @@
     }
   }
 
+  // Property names are expected to be strings.
+  for (var i = 0; i < propertyNames.length; ++i)
+    propertyNames[i] = ToString(propertyNames[i]);
+
   return propertyNames;
 }
 
@@ -911,7 +914,7 @@
                "POSITIVE_INFINITY",
                1/0,
                DONT_ENUM | DONT_DELETE | READ_ONLY);
-  %TransformToFastProperties($Number);
+  %ToFastProperties($Number);
 
   // Setup non-enumerable functions on the Number prototype object.
   InstallFunctions($Number.prototype, DONT_ENUM, $Array(
diff --git a/src/version.cc b/src/version.cc
index a200861..f6d84f3 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     2
 #define MINOR_VERSION     1
-#define BUILD_NUMBER      1
+#define BUILD_NUMBER      3
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION true
 
diff --git a/src/virtual-frame.cc b/src/virtual-frame.cc
index 44e5fae..3624e25 100644
--- a/src/virtual-frame.cc
+++ b/src/virtual-frame.cc
@@ -48,7 +48,13 @@
 }
 
 
-FrameElement VirtualFrame::CopyElementAt(int index) {
+// Create a duplicate of an existing valid frame element.
+// We can pass an optional number type information that will override the
+// existing information about the backing element. The new information must
+// not conflict with the existing type information and must be equally or
+// more precise. The default parameter value kUninitialized means that there
+// is no additional information.
+FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo::Type info) {
   ASSERT(index >= 0);
   ASSERT(index < element_count());
 
@@ -71,15 +77,26 @@
       // Fall through.
 
     case FrameElement::MEMORY:  // Fall through.
-    case FrameElement::REGISTER:
+    case FrameElement::REGISTER: {
       // All copies are backed by memory or register locations.
       result.set_type(FrameElement::COPY);
       result.clear_copied();
       result.clear_sync();
       result.set_index(index);
       elements_[index].set_copied();
+      // Update backing element's number information.
+      NumberInfo::Type existing = elements_[index].number_info();
+      ASSERT(existing != NumberInfo::kUninitialized);
+      // Assert that the new type information (a) does not conflict with the
+      // existing one and (b) is equally or more precise.
+      ASSERT((info == NumberInfo::kUninitialized) ||
+             (existing | info) != NumberInfo::kUninitialized);
+      ASSERT(existing <= info);
+      elements_[index].set_number_info(info != NumberInfo::kUninitialized
+                                       ? info
+                                       : existing);
       break;
-
+    }
     case FrameElement::INVALID:
       // We should not try to copy invalid elements.
       UNREACHABLE();
@@ -98,7 +115,7 @@
   ASSERT(stack_pointer_ == element_count() - 1);
 
   for (int i = 0; i < count; i++) {
-    elements_.Add(FrameElement::MemoryElement());
+    elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
   }
   stack_pointer_ += count;
 }
@@ -144,8 +161,16 @@
   if (!elements_[index].is_valid()) return;
 
   SyncElementAt(index);
+  // Number type information is preserved.
+  // Copies get their number information from their backing element.
+  NumberInfo::Type info;
+  if (!elements_[index].is_copy()) {
+    info = elements_[index].number_info();
+  } else {
+    info = elements_[elements_[index].index()].number_info();
+  }
   // The element is now in memory.  Its copied flag is preserved.
-  FrameElement new_element = FrameElement::MemoryElement();
+  FrameElement new_element = FrameElement::MemoryElement(info);
   if (elements_[index].is_copied()) {
     new_element.set_copied();
   }
@@ -268,7 +293,6 @@
 
   InvalidateFrameSlotAt(frame_index);
 
-  FrameElement new_element;
   if (value->is_register()) {
     if (is_used(value->reg())) {
       // The register already appears on the frame.  Either the existing
@@ -301,7 +325,8 @@
       Use(value->reg(), frame_index);
       elements_[frame_index] =
           FrameElement::RegisterElement(value->reg(),
-                                        FrameElement::NOT_SYNCED);
+                                        FrameElement::NOT_SYNCED,
+                                        value->number_info());
     }
   } else {
     ASSERT(value->is_constant());
@@ -318,16 +343,15 @@
 }
 
 
-void VirtualFrame::Push(Register reg) {
+void VirtualFrame::Push(Register reg, NumberInfo::Type info) {
   if (is_used(reg)) {
     int index = register_location(reg);
-    FrameElement element = CopyElementAt(index);
+    FrameElement element = CopyElementAt(index, info);
     elements_.Add(element);
   } else {
     Use(reg, element_count());
     FrameElement element =
-        FrameElement::RegisterElement(reg,
-                                      FrameElement::NOT_SYNCED);
+        FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, info);
     elements_.Add(element);
   }
 }
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 1b6874e..a994f45 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -34,46 +34,6 @@
 namespace internal {
 
 // -----------------------------------------------------------------------------
-// Implementation of Register
-
-Register rax = { 0 };
-Register rcx = { 1 };
-Register rdx = { 2 };
-Register rbx = { 3 };
-Register rsp = { 4 };
-Register rbp = { 5 };
-Register rsi = { 6 };
-Register rdi = { 7 };
-Register r8 = { 8 };
-Register r9 = { 9 };
-Register r10 = { 10 };
-Register r11 = { 11 };
-Register r12 = { 12 };
-Register r13 = { 13 };
-Register r14 = { 14 };
-Register r15 = { 15 };
-
-Register no_reg = { -1 };
-
-XMMRegister xmm0 = { 0 };
-XMMRegister xmm1 = { 1 };
-XMMRegister xmm2 = { 2 };
-XMMRegister xmm3 = { 3 };
-XMMRegister xmm4 = { 4 };
-XMMRegister xmm5 = { 5 };
-XMMRegister xmm6 = { 6 };
-XMMRegister xmm7 = { 7 };
-XMMRegister xmm8 = { 8 };
-XMMRegister xmm9 = { 9 };
-XMMRegister xmm10 = { 10 };
-XMMRegister xmm11 = { 11 };
-XMMRegister xmm12 = { 12 };
-XMMRegister xmm13 = { 13 };
-XMMRegister xmm14 = { 14 };
-XMMRegister xmm15 = { 15 };
-
-
-// -----------------------------------------------------------------------------
 // Implementation of CpuFeatures
 
 // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
@@ -224,7 +184,7 @@
 // -----------------------------------------------------------------------------
 // Implementation of Operand
 
-Operand::Operand(Register base, int32_t disp): rex_(0) {
+Operand::Operand(Register base, int32_t disp) : rex_(0) {
   len_ = 1;
   if (base.is(rsp) || base.is(r12)) {
     // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
@@ -246,7 +206,7 @@
 Operand::Operand(Register base,
                  Register index,
                  ScaleFactor scale,
-                 int32_t disp): rex_(0) {
+                 int32_t disp) : rex_(0) {
   ASSERT(!index.is(rsp));
   len_ = 1;
   set_sib(scale, index, base);
@@ -264,6 +224,17 @@
 }
 
 
+Operand::Operand(Register index,
+                 ScaleFactor scale,
+                 int32_t disp) : rex_(0) {
+  ASSERT(!index.is(rsp));
+  len_ = 1;
+  set_modrm(0, rsp);
+  set_sib(scale, index, rbp);
+  set_disp32(disp);
+}
+
+
 // -----------------------------------------------------------------------------
 // Implementation of Assembler.
 
@@ -2508,6 +2479,38 @@
 }
 
 
+void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x57);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::comisd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x2f);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x2e);
+  emit_sse_operand(dst, src);
+}
+
 
 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
   Register ireg = { reg.code() };
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 64fbd88..5019525 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -118,51 +118,23 @@
   int code_;
 };
 
-extern Register rax;
-extern Register rcx;
-extern Register rdx;
-extern Register rbx;
-extern Register rsp;
-extern Register rbp;
-extern Register rsi;
-extern Register rdi;
-extern Register r8;
-extern Register r9;
-extern Register r10;
-extern Register r11;
-extern Register r12;
-extern Register r13;
-extern Register r14;
-extern Register r15;
-extern Register no_reg;
-
-
-struct MMXRegister {
-  bool is_valid() const  { return 0 <= code_ && code_ < 2; }
-  int code() const  {
-    ASSERT(is_valid());
-    return code_;
-  }
-
-  int code_;
-};
-
-extern MMXRegister mm0;
-extern MMXRegister mm1;
-extern MMXRegister mm2;
-extern MMXRegister mm3;
-extern MMXRegister mm4;
-extern MMXRegister mm5;
-extern MMXRegister mm6;
-extern MMXRegister mm7;
-extern MMXRegister mm8;
-extern MMXRegister mm9;
-extern MMXRegister mm10;
-extern MMXRegister mm11;
-extern MMXRegister mm12;
-extern MMXRegister mm13;
-extern MMXRegister mm14;
-extern MMXRegister mm15;
+const Register rax = { 0 };
+const Register rcx = { 1 };
+const Register rdx = { 2 };
+const Register rbx = { 3 };
+const Register rsp = { 4 };
+const Register rbp = { 5 };
+const Register rsi = { 6 };
+const Register rdi = { 7 };
+const Register r8 = { 8 };
+const Register r9 = { 9 };
+const Register r10 = { 10 };
+const Register r11 = { 11 };
+const Register r12 = { 12 };
+const Register r13 = { 13 };
+const Register r14 = { 14 };
+const Register r15 = { 15 };
+const Register no_reg = { -1 };
 
 
 struct XMMRegister {
@@ -186,22 +158,22 @@
   int code_;
 };
 
-extern XMMRegister xmm0;
-extern XMMRegister xmm1;
-extern XMMRegister xmm2;
-extern XMMRegister xmm3;
-extern XMMRegister xmm4;
-extern XMMRegister xmm5;
-extern XMMRegister xmm6;
-extern XMMRegister xmm7;
-extern XMMRegister xmm8;
-extern XMMRegister xmm9;
-extern XMMRegister xmm10;
-extern XMMRegister xmm11;
-extern XMMRegister xmm12;
-extern XMMRegister xmm13;
-extern XMMRegister xmm14;
-extern XMMRegister xmm15;
+const XMMRegister xmm0 = { 0 };
+const XMMRegister xmm1 = { 1 };
+const XMMRegister xmm2 = { 2 };
+const XMMRegister xmm3 = { 3 };
+const XMMRegister xmm4 = { 4 };
+const XMMRegister xmm5 = { 5 };
+const XMMRegister xmm6 = { 6 };
+const XMMRegister xmm7 = { 7 };
+const XMMRegister xmm8 = { 8 };
+const XMMRegister xmm9 = { 9 };
+const XMMRegister xmm10 = { 10 };
+const XMMRegister xmm11 = { 11 };
+const XMMRegister xmm12 = { 12 };
+const XMMRegister xmm13 = { 13 };
+const XMMRegister xmm14 = { 14 };
+const XMMRegister xmm15 = { 15 };
 
 enum Condition {
   // any value < 0 is considered no_condition
@@ -308,7 +280,6 @@
   times_4 = 2,
   times_8 = 3,
   times_int_size = times_4,
-  times_half_pointer_size = times_4,
   times_pointer_size = times_8
 };
 
@@ -1122,6 +1093,10 @@
   void mulsd(XMMRegister dst, XMMRegister src);
   void divsd(XMMRegister dst, XMMRegister src);
 
+  void xorpd(XMMRegister dst, XMMRegister src);
+
+  void comisd(XMMRegister dst, XMMRegister src);
+  void ucomisd(XMMRegister dst, XMMRegister src);
 
   void emit_sse_operand(XMMRegister dst, XMMRegister src);
   void emit_sse_operand(XMMRegister reg, const Operand& adr);
@@ -1168,14 +1143,6 @@
   static const int kMaximalBufferSize = 512*MB;
   static const int kMinimalBufferSize = 4*KB;
 
- protected:
-  // void movsd(XMMRegister dst, const Operand& src);
-  // void movsd(const Operand& dst, XMMRegister src);
-
-  // void emit_sse_operand(XMMRegister reg, const Operand& adr);
-  // void emit_sse_operand(XMMRegister dst, XMMRegister src);
-
-
  private:
   byte* addr_at(int pos)  { return buffer_ + pos; }
   byte byte_at(int pos)  { return buffer_[pos]; }
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 0b95bba..b3c5e33 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -185,14 +185,14 @@
 
 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
   // Stack Layout:
-  // rsp: return address
-  //  +1: Argument n
-  //  +2: Argument n-1
+  // rsp[0]:   Return address
+  // rsp[1]:   Argument n
+  // rsp[2]:   Argument n-1
   //  ...
-  //  +n: Argument 1 = receiver
-  //  +n+1: Argument 0 = function to call
+  // rsp[n]:   Argument 1
+  // rsp[n+1]: Receiver (function to call)
   //
-  // rax contains the number of arguments, n, not counting the function.
+  // rax contains the number of arguments, n, not counting the receiver.
   //
   // 1. Make sure we have at least one argument.
   { Label done;
@@ -205,31 +205,23 @@
     __ bind(&done);
   }
 
-  // 2. Get the function to call from the stack.
-  { Label done, non_function, function;
-    // The function to call is at position n+1 on the stack.
-    __ movq(rdi, Operand(rsp, rax, times_pointer_size, +1 * kPointerSize));
-    __ JumpIfSmi(rdi, &non_function);
-    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
-    __ j(equal, &function);
+  // 2. Get the function to call (passed as receiver) from the stack, check
+  //    if it is a function.
+  Label non_function;
+  // The function to call is at position n+1 on the stack.
+  __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
+  __ JumpIfSmi(rdi, &non_function);
+  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+  __ j(not_equal, &non_function);
 
-    // Non-function called: Clear the function to force exception.
-    __ bind(&non_function);
-    __ xor_(rdi, rdi);
-    __ jmp(&done);
-
-    // Function called: Change context eagerly to get the right global object.
-    __ bind(&function);
+  // 3a. Patch the first argument if necessary when calling a function.
+  Label shift_arguments;
+  { Label convert_to_object, use_global_receiver, patch_receiver;
+    // Change context eagerly in case we need the global receiver.
     __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
 
-    __ bind(&done);
-  }
-
-  // 3. Make sure first argument is an object; convert if necessary.
-  { Label call_to_object, use_global_receiver, patch_receiver, done;
     __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
-
-    __ JumpIfSmi(rbx, &call_to_object);
+    __ JumpIfSmi(rbx, &convert_to_object);
 
     __ CompareRoot(rbx, Heap::kNullValueRootIndex);
     __ j(equal, &use_global_receiver);
@@ -237,31 +229,28 @@
     __ j(equal, &use_global_receiver);
 
     __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
-    __ j(below, &call_to_object);
+    __ j(below, &convert_to_object);
     __ CmpInstanceType(rcx, LAST_JS_OBJECT_TYPE);
-    __ j(below_equal, &done);
+    __ j(below_equal, &shift_arguments);
 
-    __ bind(&call_to_object);
-    __ EnterInternalFrame();  // preserves rax, rbx, rdi
-
-    // Store the arguments count on the stack (smi tagged).
+    __ bind(&convert_to_object);
+    __ EnterInternalFrame();  // In order to preserve argument count.
     __ Integer32ToSmi(rax, rax);
     __ push(rax);
 
-    __ push(rdi);  // save edi across the call
     __ push(rbx);
     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
     __ movq(rbx, rax);
-    __ pop(rdi);  // restore edi after the call
 
-    // Get the arguments count and untag it.
     __ pop(rax);
     __ SmiToInteger32(rax, rax);
-
     __ LeaveInternalFrame();
+    // Restore the function to rdi.
+    __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
     __ jmp(&patch_receiver);
 
-    // Use the global receiver object from the called function as the receiver.
+    // Use the global receiver object from the called function as the
+    // receiver.
     __ bind(&use_global_receiver);
     const int kGlobalIndex =
         Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
@@ -273,48 +262,57 @@
     __ bind(&patch_receiver);
     __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx);
 
-    __ bind(&done);
+    __ jmp(&shift_arguments);
   }
 
-  // 4. Shift stuff one slot down the stack.
+
+  // 3b. Patch the first argument when calling a non-function.  The
+  //     CALL_NON_FUNCTION builtin expects the non-function callee as
+  //     receiver, so overwrite the first argument which will ultimately
+  //     become the receiver.
+  __ bind(&non_function);
+  __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
+  __ xor_(rdi, rdi);
+
+  // 4. Shift arguments and return address one slot down on the stack
+  //    (overwriting the original receiver).  Adjust argument count to make
+  //    the original first argument the new receiver.
+  __ bind(&shift_arguments);
   { Label loop;
-    __ lea(rcx, Operand(rax, +1));  // +1 ~ copy receiver too
+    __ movq(rcx, rax);
     __ bind(&loop);
     __ movq(rbx, Operand(rsp, rcx, times_pointer_size, 0));
     __ movq(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx);
     __ decq(rcx);
-    __ j(not_zero, &loop);
+    __ j(not_sign, &loop);  // While non-negative (to copy return address).
+    __ pop(rbx);  // Discard copy of return address.
+    __ decq(rax);  // One fewer argument (first argument is new receiver).
   }
 
-  // 5. Remove TOS (copy of last arguments), but keep return address.
-  __ pop(rbx);
-  __ pop(rcx);
-  __ push(rbx);
-  __ decq(rax);
-
-  // 6. Check that function really was a function and get the code to
-  //    call from the function and check that the number of expected
-  //    arguments matches what we're providing.
-  { Label invoke, trampoline;
+  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
+  { Label function;
     __ testq(rdi, rdi);
-    __ j(not_zero, &invoke);
+    __ j(not_zero, &function);
     __ xor_(rbx, rbx);
     __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
-    __ bind(&trampoline);
     __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
             RelocInfo::CODE_TARGET);
-
-    __ bind(&invoke);
-    __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
-    __ movsxlq(rbx,
-           FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
-    __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
-    __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
-    __ cmpq(rax, rbx);
-    __ j(not_equal, &trampoline);
+    __ bind(&function);
   }
 
-  // 7. Jump (tail-call) to the code in register edx without checking arguments.
+  // 5b. Get the code to call from the function and check that the number of
+  //     expected arguments matches what we're providing.  If so, jump
+  //     (tail-call) to the code in register edx without checking arguments.
+  __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+  __ movsxlq(rbx,
+         FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
+  __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
+  __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+  __ cmpq(rax, rbx);
+  __ j(not_equal,
+       Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
+       RelocInfo::CODE_TARGET);
+
   ParameterCount expected(0);
   __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
 }
@@ -586,6 +584,7 @@
                        JSFunction::kPrototypeOrInitialMapOffset));
 
   // Check whether an empty sized array is requested.
+  __ SmiToInteger64(array_size, array_size);
   __ testq(array_size, array_size);
   __ j(not_zero, &not_empty);
 
@@ -605,7 +604,7 @@
   __ bind(&not_empty);
   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
   __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
-                        times_half_pointer_size,  // array_size is a smi.
+                        times_pointer_size,
                         array_size,
                         result,
                         elements_array_end,
@@ -618,19 +617,20 @@
   // result: JSObject
   // elements_array: initial map
   // elements_array_end: start of next object
-  // array_size: size of array (smi)
+  // array_size: size of array
   __ bind(&allocated);
   __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array);
   __ Move(elements_array, Factory::empty_fixed_array());
   __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
   // Field JSArray::kElementsOffset is initialized later.
-  __ movq(FieldOperand(result, JSArray::kLengthOffset), array_size);
+  __ Integer32ToSmi(scratch, array_size);
+  __ movq(FieldOperand(result, JSArray::kLengthOffset), scratch);
 
   // Calculate the location of the elements array and set elements array member
   // of the JSArray.
   // result: JSObject
   // elements_array_end: start of next object
-  // array_size: size of array (smi)
+  // array_size: size of array
   __ lea(elements_array, Operand(result, JSArray::kSize));
   __ movq(FieldOperand(result, JSArray::kElementsOffset), elements_array);
 
@@ -638,9 +638,8 @@
   // result: JSObject
   // elements_array: elements array
   // elements_array_end: start of next object
-  // array_size: size of array (smi)
+  // array_size: size of array
   ASSERT(kSmiTag == 0);
-  __ SmiToInteger64(array_size, array_size);
   __ Move(FieldOperand(elements_array, JSObject::kMapOffset),
           Factory::fixed_array_map());
   Label not_empty_2, fill_array;
@@ -900,7 +899,11 @@
   // edi: called object
   // eax: number of arguments
   __ bind(&non_function_call);
-  // Set expected number of arguments to zero (not changing eax).
+  // CALL_NON_FUNCTION expects the non-function constructor as receiver
+  // (instead of the original receiver from the call site).  The receiver is
+  // stack element argc+1.
+  __ movq(Operand(rsp, rax, times_pointer_size, kPointerSize), rdi);
+  // Set expected number of arguments to zero (not changing rax).
   __ movq(rbx, Immediate(0));
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
   __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index ee8f251..e418883 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -277,7 +277,7 @@
 }
 
 
-void CodeGenerator::Generate(CompilationInfo* info, Mode mode) {
+void CodeGenerator::Generate(CompilationInfo* info) {
   // Record the position for debugging purposes.
   CodeForFunctionPosition(info->function());
 
@@ -316,7 +316,7 @@
     // rsi: callee's context
     allocator_->Initialize();
 
-    if (mode == PRIMARY) {
+    if (info->mode() == CompilationInfo::PRIMARY) {
       frame_->Enter();
 
       // Allocate space for locals and initialize them.
@@ -407,6 +407,12 @@
       // frame to match this state.
       frame_->Adjust(3);
       allocator_->Unuse(rdi);
+
+      // Bind all the bailout labels to the beginning of the function.
+      List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
+      for (int i = 0; i < bailouts->length(); i++) {
+        __ bind(bailouts->at(i)->label());
+      }
     }
 
     // Initialize the function return target after the locals are set
@@ -1221,7 +1227,7 @@
     // Compare and branch to the body if true or the next test if
     // false.  Prefer the next test as a fall through.
     ControlDestination dest(clause->body_target(), &next_test, false);
-    Comparison(equal, true, &dest);
+    Comparison(node, equal, true, &dest);
 
     // If the comparison fell through to the true target, jump to the
     // actual body.
@@ -2218,8 +2224,7 @@
   // Spill everything, even constants, to the frame.
   frame_->SpillAll();
 
-  DebuggerStatementStub ces;
-  frame_->CallStub(&ces, 0);
+  frame_->DebugBreak();
   // Ignore the return value.
 #endif
 }
@@ -2496,17 +2501,19 @@
   // Load the literals array of the function.
   __ movq(literals.reg(),
           FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
-  // Literal array.
+
   frame_->Push(&literals);
-  // Literal index.
   frame_->Push(Smi::FromInt(node->literal_index()));
-  // Constant elements.
   frame_->Push(node->constant_elements());
+  int length = node->values()->length();
   Result clone;
   if (node->depth() > 1) {
     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
-  } else {
+  } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
+  } else {
+    FastCloneShallowArrayStub stub(length);
+    clone = frame_->CallStub(&stub, 3);
   }
   frame_->Push(&clone);
 
@@ -2756,9 +2763,6 @@
     // JavaScript example: 'foo(1, 2, 3)'  // foo is global
     // ----------------------------------
 
-    // Push the name of the function and the receiver onto the stack.
-    frame_->Push(var->name());
-
     // Pass the global object as the receiver and let the IC stub
     // patch the stack to use the global proxy as 'this' in the
     // invoked function.
@@ -2770,6 +2774,9 @@
       Load(args->at(i));
     }
 
+    // Push the name of the function on the frame.
+    frame_->Push(var->name());
+
     // Call the IC initialization code.
     CodeForSourcePosition(node->position());
     Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT,
@@ -2777,7 +2784,7 @@
                                        loop_nesting());
     frame_->RestoreContextRegister();
     // Replace the function on the stack with the result.
-    frame_->SetElementAt(0, &result);
+    frame_->Push(&result);
 
   } else if (var != NULL && var->slot() != NULL &&
              var->slot()->type() == Slot::LOOKUP) {
@@ -2830,8 +2837,7 @@
                       node->position());
 
       } else {
-        // Push the name of the function and the receiver onto the stack.
-        frame_->Push(name);
+        // Push the receiver onto the frame.
         Load(property->obj());
 
         // Load the arguments.
@@ -2840,14 +2846,16 @@
           Load(args->at(i));
         }
 
+        // Push the name of the function onto the frame.
+        frame_->Push(name);
+
         // Call the IC initialization code.
         CodeForSourcePosition(node->position());
         Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET,
                                            arg_count,
                                            loop_nesting());
         frame_->RestoreContextRegister();
-        // Replace the function on the stack with the result.
-        frame_->SetElementAt(0, &result);
+        frame_->Push(&result);
       }
 
     } else {
@@ -2938,8 +2946,6 @@
   Runtime::Function* function = node->function();
 
   if (function == NULL) {
-    // Prepare stack for calling JS runtime function.
-    frame_->Push(node->name());
     // Push the builtins object found in the current global object.
     Result temp = allocator()->Allocate();
     ASSERT(temp.is_valid());
@@ -2957,11 +2963,12 @@
 
   if (function == NULL) {
     // Call the JS runtime function.
+    frame_->Push(node->name());
     Result answer = frame_->CallCallIC(RelocInfo::CODE_TARGET,
                                        arg_count,
                                        loop_nesting_);
     frame_->RestoreContextRegister();
-    frame_->SetElementAt(0, &answer);
+    frame_->Push(&answer);
   } else {
     // Call the C runtime function.
     Result answer = frame_->CallRuntime(function, arg_count);
@@ -3070,7 +3077,6 @@
 
       case Token::SUB: {
         GenericUnaryOpStub stub(Token::SUB, overwrite);
-        // TODO(1222589): remove dependency of TOS being cached inside stub
         Result operand = frame_->Pop();
         Result answer = frame_->CallStub(&stub, &operand);
         frame_->Push(&answer);
@@ -3586,7 +3592,7 @@
   }
   Load(left);
   Load(right);
-  Comparison(cc, strict, destination());
+  Comparison(node, cc, strict, destination());
 }
 
 
@@ -3627,6 +3633,22 @@
 }
 
 
+void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+  Load(args->at(0));
+  Result value = frame_->Pop();
+  value.ToRegister();
+  ASSERT(value.is_valid());
+  Condition is_smi = masm_->CheckSmi(value.reg());
+  destination()->false_target()->Branch(is_smi);
+  // It is a heap object - get map.
+  // Check if the object is a regexp.
+  __ CmpObjectType(value.reg(), JS_REGEXP_TYPE, kScratchRegister);
+  value.Unuse();
+  destination()->Split(equal);
+}
+
+
 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
   // This generates a fast version of:
   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
@@ -3971,6 +3993,35 @@
 }
 
 
+void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+
+  Result answer = frame_->CallRuntime(Runtime::kNumberToString, 1);
+  frame_->Push(&answer);
+}
+
+
+void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+  Result answer = frame_->CallRuntime(Runtime::kMath_sin, 1);
+  frame_->Push(&answer);
+}
+
+
+void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
+  ASSERT_EQ(args->length(), 1);
+  // Load the argument on the stack and jump to the runtime.
+  Load(args->at(0));
+  Result answer = frame_->CallRuntime(Runtime::kMath_cos, 1);
+  frame_->Push(&answer);
+}
+
+
 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
   ASSERT_EQ(2, args->length());
 
@@ -4260,34 +4311,52 @@
   // The value to convert should be popped from the frame.
   Result value = frame_->Pop();
   value.ToRegister();
-  // Fast case checks.
 
-  // 'false' => false.
-  __ CompareRoot(value.reg(), Heap::kFalseValueRootIndex);
-  dest->false_target()->Branch(equal);
+  if (value.is_number()) {
+    Comment cmnt(masm_, "ONLY_NUMBER");
+    // Fast case if NumberInfo indicates only numbers.
+    if (FLAG_debug_code) {
+      __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
+    }
+    // Smi => false iff zero.
+    __ SmiCompare(value.reg(), Smi::FromInt(0));
+    dest->false_target()->Branch(equal);
+    Condition is_smi = masm_->CheckSmi(value.reg());
+    dest->true_target()->Branch(is_smi);
+    __ fldz();
+    __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset));
+    __ FCmp();
+    value.Unuse();
+    dest->Split(not_zero);
+  } else {
+    // Fast case checks.
+    // 'false' => false.
+    __ CompareRoot(value.reg(), Heap::kFalseValueRootIndex);
+    dest->false_target()->Branch(equal);
 
-  // 'true' => true.
-  __ CompareRoot(value.reg(), Heap::kTrueValueRootIndex);
-  dest->true_target()->Branch(equal);
+    // 'true' => true.
+    __ CompareRoot(value.reg(), Heap::kTrueValueRootIndex);
+    dest->true_target()->Branch(equal);
 
-  // 'undefined' => false.
-  __ CompareRoot(value.reg(), Heap::kUndefinedValueRootIndex);
-  dest->false_target()->Branch(equal);
+    // 'undefined' => false.
+    __ CompareRoot(value.reg(), Heap::kUndefinedValueRootIndex);
+    dest->false_target()->Branch(equal);
 
-  // Smi => false iff zero.
-  __ SmiCompare(value.reg(), Smi::FromInt(0));
-  dest->false_target()->Branch(equal);
-  Condition is_smi = masm_->CheckSmi(value.reg());
-  dest->true_target()->Branch(is_smi);
+    // Smi => false iff zero.
+    __ SmiCompare(value.reg(), Smi::FromInt(0));
+    dest->false_target()->Branch(equal);
+    Condition is_smi = masm_->CheckSmi(value.reg());
+    dest->true_target()->Branch(is_smi);
 
-  // Call the stub for all other cases.
-  frame_->Push(&value);  // Undo the Pop() from above.
-  ToBooleanStub stub;
-  Result temp = frame_->CallStub(&stub, 1);
-  // Convert the result to a condition code.
-  __ testq(temp.reg(), temp.reg());
-  temp.Unuse();
-  dest->Split(not_equal);
+    // Call the stub for all other cases.
+    frame_->Push(&value);  // Undo the Pop() from above.
+    ToBooleanStub stub;
+    Result temp = frame_->CallStub(&stub, 1);
+    // Convert the result to a condition code.
+    __ testq(temp.reg(), temp.reg());
+    temp.Unuse();
+    dest->Split(not_equal);
+  }
 }
 
 
@@ -4868,7 +4937,8 @@
 }
 
 
-void CodeGenerator::Comparison(Condition cc,
+void CodeGenerator::Comparison(AstNode* node,
+                               Condition cc,
                                bool strict,
                                ControlDestination* dest) {
   // Strict only makes sense for equality comparisons.
@@ -4915,7 +4985,8 @@
         default:
           UNREACHABLE();
       }
-    } else {  // Only one side is a constant Smi.
+    } else {
+      // Only one side is a constant Smi.
       // If left side is a constant Smi, reverse the operands.
       // Since one side is a constant Smi, conversion order does not matter.
       if (left_side_constant_smi) {
@@ -4929,6 +5000,8 @@
       // Implement comparison against a constant Smi, inlining the case
       // where both sides are Smis.
       left_side.ToRegister();
+      Register left_reg = left_side.reg();
+      Handle<Object> right_val = right_side.handle();
 
       // Here we split control flow to the stub call and inlined cases
       // before finally splitting it to the control destination.  We use
@@ -4936,12 +5009,48 @@
       // the first split.  We manually handle the off-frame references
       // by reconstituting them on the non-fall-through path.
       JumpTarget is_smi;
-      Register left_reg = left_side.reg();
-      Handle<Object> right_val = right_side.handle();
 
       Condition left_is_smi = masm_->CheckSmi(left_side.reg());
       is_smi.Branch(left_is_smi);
 
+      bool is_for_loop_compare = (node->AsCompareOperation() != NULL)
+          && node->AsCompareOperation()->is_for_loop_condition();
+      if (!is_for_loop_compare && right_val->IsSmi()) {
+        // Right side is a constant smi and left side has been checked
+        // not to be a smi.
+        JumpTarget not_number;
+        __ Cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
+               Factory::heap_number_map());
+        not_number.Branch(not_equal, &left_side);
+        __ movsd(xmm1,
+                 FieldOperand(left_reg, HeapNumber::kValueOffset));
+        int value = Smi::cast(*right_val)->value();
+        if (value == 0) {
+          __ xorpd(xmm0, xmm0);
+        } else {
+          Result temp = allocator()->Allocate();
+          __ movl(temp.reg(), Immediate(value));
+          __ cvtlsi2sd(xmm0, temp.reg());
+          temp.Unuse();
+        }
+        __ ucomisd(xmm1, xmm0);
+        // Jump to builtin for NaN.
+        not_number.Branch(parity_even, &left_side);
+        left_side.Unuse();
+        Condition double_cc = cc;
+        switch (cc) {
+          case less:          double_cc = below;       break;
+          case equal:         double_cc = equal;       break;
+          case less_equal:    double_cc = below_equal; break;
+          case greater:       double_cc = above;       break;
+          case greater_equal: double_cc = above_equal; break;
+          default: UNREACHABLE();
+        }
+        dest->true_target()->Branch(double_cc);
+        dest->false_target()->Jump();
+        not_number.Bind(&left_side);
+      }
+
       // Setup and call the compare stub.
       CompareStub stub(cc, strict);
       Result result = frame_->CallStub(&stub, &left_side, &right_side);
@@ -5114,26 +5223,34 @@
     // Neither operand is known to be a string.
   }
 
-  bool left_is_smi = left.is_constant() && left.handle()->IsSmi();
-  bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi();
-  bool right_is_smi = right.is_constant() && right.handle()->IsSmi();
-  bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi();
+  bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi();
+  bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi();
+  bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi();
+  bool right_is_non_smi_constant =
+      right.is_constant() && !right.handle()->IsSmi();
 
-  if (left_is_smi && right_is_smi) {
+  if (left_is_smi_constant && right_is_smi_constant) {
     // Compute the constant result at compile time, and leave it on the frame.
     int left_int = Smi::cast(*left.handle())->value();
     int right_int = Smi::cast(*right.handle())->value();
     if (FoldConstantSmis(op, left_int, right_int)) return;
   }
 
+  // Get number type of left and right sub-expressions.
+  NumberInfo::Type operands_type =
+      NumberInfo::Combine(left.number_info(), right.number_info());
+
   Result answer;
-  if (left_is_non_smi || right_is_non_smi) {
-    GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB);
+  if (left_is_non_smi_constant || right_is_non_smi_constant) {
+    GenericBinaryOpStub stub(op,
+                             overwrite_mode,
+                             NO_SMI_CODE_IN_STUB,
+                             operands_type);
     answer = stub.GenerateCall(masm_, frame_, &left, &right);
-  } else if (right_is_smi) {
+  } else if (right_is_smi_constant) {
     answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
                                         type, false, overwrite_mode);
-  } else if (left_is_smi) {
+  } else if (left_is_smi_constant) {
     answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
                                         type, true, overwrite_mode);
   } else {
@@ -5145,10 +5262,62 @@
     if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
       answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
     } else {
-      GenericBinaryOpStub stub(op, overwrite_mode, NO_GENERIC_BINARY_FLAGS);
+      GenericBinaryOpStub stub(op,
+                               overwrite_mode,
+                               NO_GENERIC_BINARY_FLAGS,
+                               operands_type);
       answer = stub.GenerateCall(masm_, frame_, &left, &right);
     }
   }
+
+  // Set NumberInfo of result according to the operation performed.
+  // We rely on the fact that smis have a 32 bit payload on x64.
+  ASSERT(kSmiValueSize == 32);
+  NumberInfo::Type result_type = NumberInfo::kUnknown;
+  switch (op) {
+    case Token::COMMA:
+      result_type = right.number_info();
+      break;
+    case Token::OR:
+    case Token::AND:
+      // Result type can be either of the two input types.
+      result_type = operands_type;
+      break;
+    case Token::BIT_OR:
+    case Token::BIT_XOR:
+    case Token::BIT_AND:
+      // Result is always a smi.
+      result_type = NumberInfo::kSmi;
+      break;
+    case Token::SAR:
+    case Token::SHL:
+      // Result is always a smi.
+      result_type = NumberInfo::kSmi;
+      break;
+    case Token::SHR:
+      // Result of x >>> y is always a smi if y >= 1, otherwise a number.
+      result_type = (right.is_constant() && right.handle()->IsSmi()
+                     && Smi::cast(*right.handle())->value() >= 1)
+          ? NumberInfo::kSmi
+          : NumberInfo::kNumber;
+      break;
+    case Token::ADD:
+      // Result could be a string or a number. Check types of inputs.
+      result_type = NumberInfo::IsNumber(operands_type)
+          ? NumberInfo::kNumber
+          : NumberInfo::kUnknown;
+      break;
+    case Token::SUB:
+    case Token::MUL:
+    case Token::DIV:
+    case Token::MOD:
+      // Result is always a number.
+      result_type = NumberInfo::kNumber;
+      break;
+    default:
+      UNREACHABLE();
+  }
+  answer.set_number_info(result_type);
   frame_->Push(&answer);
 }
 
@@ -6221,6 +6390,63 @@
 }
 
 
+void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
+  // Stack layout on entry:
+  //
+  // [rsp + kPointerSize]: constant elements.
+  // [rsp + (2 * kPointerSize)]: literal index.
+  // [rsp + (3 * kPointerSize)]: literals array.
+
+  // All sizes here are multiples of kPointerSize.
+  int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
+  int size = JSArray::kSize + elements_size;
+
+  // Load boilerplate object into rcx and check if we need to create a
+  // boilerplate.
+  Label slow_case;
+  __ movq(rcx, Operand(rsp, 3 * kPointerSize));
+  __ movq(rax, Operand(rsp, 2 * kPointerSize));
+  SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
+  __ movq(rcx,
+          FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize));
+  __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
+  __ j(equal, &slow_case);
+
+  // Allocate both the JS array and the elements array in one big
+  // allocation. This avoids multiple limit checks.
+  __ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT);
+
+  // Copy the JS array part.
+  for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
+    if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
+      __ movq(rbx, FieldOperand(rcx, i));
+      __ movq(FieldOperand(rax, i), rbx);
+    }
+  }
+
+  if (length_ > 0) {
+    // Get hold of the elements array of the boilerplate and setup the
+    // elements pointer in the resulting object.
+    __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
+    __ lea(rdx, Operand(rax, JSArray::kSize));
+    __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);
+
+    // Copy the elements array.
+    for (int i = 0; i < elements_size; i += kPointerSize) {
+      __ movq(rbx, FieldOperand(rcx, i));
+      __ movq(FieldOperand(rdx, i), rbx);
+    }
+  }
+
+  // Return and remove the on-stack parameters.
+  __ ret(3 * kPointerSize);
+
+  __ bind(&slow_case);
+  ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
+  __ TailCallRuntime(runtime, 3, 1);
+}
+
+
 void ToBooleanStub::Generate(MacroAssembler* masm) {
   Label false_result, true_result, not_string;
   __ movq(rax, Operand(rsp, 1 * kPointerSize));
@@ -7234,30 +7460,107 @@
 
 
 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+  // rsp[0] : return address
+  // rsp[8] : number of parameters
+  // rsp[16] : receiver displacement
+  // rsp[24] : function
+
   // The displacement is used for skipping the return address and the
   // frame pointer on the stack. It is the offset of the last
   // parameter (if any) relative to the frame pointer.
   static const int kDisplacement = 2 * kPointerSize;
 
   // Check if the calling frame is an arguments adaptor frame.
-  Label runtime;
+  Label adaptor_frame, try_allocate, runtime;
   __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
   __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
                 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
-  __ j(not_equal, &runtime);
-  // Value in rcx is Smi encoded.
+  __ j(equal, &adaptor_frame);
+
+  // Get the length from the frame.
+  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  __ jmp(&try_allocate);
 
   // Patch the arguments.length and the parameters pointer.
+  __ bind(&adaptor_frame);
   __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   __ movq(Operand(rsp, 1 * kPointerSize), rcx);
-  SmiIndex index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2);
+  // Do not clobber the length index for the indexing operation since
+  // it is used compute the size for allocation later.
+  SmiIndex index = masm->SmiToIndex(rbx, rcx, kPointerSizeLog2);
   __ lea(rdx, Operand(rdx, index.reg, index.scale, kDisplacement));
   __ movq(Operand(rsp, 2 * kPointerSize), rdx);
 
+  // Try the new space allocation. Start out with computing the size of
+  // the arguments object and the elements array.
+  Label add_arguments_object;
+  __ bind(&try_allocate);
+  __ testq(rcx, rcx);
+  __ j(zero, &add_arguments_object);
+  index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2);
+  __ lea(rcx, Operand(index.reg, index.scale, FixedArray::kHeaderSize));
+  __ bind(&add_arguments_object);
+  __ addq(rcx, Immediate(Heap::kArgumentsObjectSize));
+
+  // Do the allocation of both objects in one go.
+  __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
+
+  // Get the arguments boilerplate from the current (global) context.
+  int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+  __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
+  __ movq(rdi, Operand(rdi, offset));
+
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ movq(kScratchRegister, FieldOperand(rdi, i));
+    __ movq(FieldOperand(rax, i), kScratchRegister);
+  }
+
+  // Setup the callee in-object property.
+  ASSERT(Heap::arguments_callee_index == 0);
+  __ movq(kScratchRegister, Operand(rsp, 3 * kPointerSize));
+  __ movq(FieldOperand(rax, JSObject::kHeaderSize), kScratchRegister);
+
+  // Get the length (smi tagged) and set that as an in-object property too.
+  ASSERT(Heap::arguments_length_index == 1);
+  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  __ movq(FieldOperand(rax, JSObject::kHeaderSize + kPointerSize), rcx);
+
+  // If there are no actual arguments, we're done.
+  Label done;
+  __ testq(rcx, rcx);
+  __ j(zero, &done);
+
+  // Get the parameters pointer from the stack and untag the length.
+  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+  __ SmiToInteger32(rcx, rcx);
+
+  // Setup the elements pointer in the allocated arguments object and
+  // initialize the header in the elements fixed array.
+  __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
+  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
+  __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
+  __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
+  __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
+
+  // Copy the fixed array slots.
+  Label loop;
+  __ bind(&loop);
+  __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize));  // Skip receiver.
+  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
+  __ addq(rdi, Immediate(kPointerSize));
+  __ subq(rdx, Immediate(kPointerSize));
+  __ decq(rcx);
+  __ j(not_zero, &loop);
+
+  // Return and remove the on-stack parameters.
+  __ bind(&done);
+  __ ret(3 * kPointerSize);
+
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast);
-  __ TailCallRuntime(ExternalReference(f), 3, f->result_size);
+  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
 }
 
 
@@ -7592,6 +7895,9 @@
 
   // Slow-case: Non-function called.
   __ bind(&slow);
+  // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+  // of the original receiver from the call site).
+  __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
   __ Set(rax, argc_);
   __ Set(rbx, 0);
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
@@ -7980,13 +8286,14 @@
   }
 
   OS::SNPrintF(Vector<char>(name_, len),
-               "GenericBinaryOpStub_%s_%s%s_%s%s_%s",
+               "GenericBinaryOpStub_%s_%s%s_%s%s_%s%s",
                op_name,
                overwrite_name,
                (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
                args_in_registers_ ? "RegArgs" : "StackArgs",
                args_reversed_ ? "_R" : "",
-               use_sse3_ ? "SSE3" : "SSE2");
+               use_sse3_ ? "SSE3" : "SSE2",
+               NumberInfo::ToString(operands_type_));
   return name_;
 }
 
@@ -8012,6 +8319,8 @@
         }
       } else if (left.is(left_arg)) {
         __ movq(right_arg, right);
+      } else if (right.is(right_arg)) {
+        __ movq(left_arg, left);
       } else if (left.is(right_arg)) {
         if (IsOperationCommutative()) {
           __ movq(left_arg, right);
@@ -8030,8 +8339,6 @@
           __ movq(right_arg, right);
           __ movq(left_arg, left);
         }
-      } else if (right.is(right_arg)) {
-        __ movq(left_arg, left);
       } else {
         // Order of moves is not important.
         __ movq(left_arg, left);
@@ -8067,6 +8374,10 @@
       __ Move(left_arg, right);
       SetArgsReversed();
     } else {
+      // For non-commutative operations, left and right_arg might be
+      // the same register.  Therefore, the order of the moves is
+      // important here in order to not overwrite left before moving
+      // it to left_arg.
       __ movq(left_arg, left);
       __ Move(right_arg, right);
     }
@@ -8099,8 +8410,12 @@
       __ Move(right_arg, left);
       SetArgsReversed();
     } else {
-      __ Move(left_arg, left);
+      // For non-commutative operations, right and left_arg might be
+      // the same register.  Therefore, the order of the moves is
+      // important here in order to not overwrite right before moving
+      // it to right_arg.
       __ movq(right_arg, right);
+      __ Move(left_arg, left);
     }
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
@@ -8302,7 +8617,15 @@
     case Token::DIV: {
       // rax: y
       // rdx: x
-      FloatingPointHelper::CheckNumberOperands(masm, &call_runtime);
+      if (NumberInfo::IsNumber(operands_type_)) {
+        if (FLAG_debug_code) {
+          // Assert at runtime that inputs are only numbers.
+          __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
+          __ AbortIfNotNumber(rax, "GenericBinaryOpStub operand not a number.");
+        }
+      } else {
+        FloatingPointHelper::CheckNumberOperands(masm, &call_runtime);
+      }
       // Fast-case: Both operands are numbers.
       // xmm4 and xmm5 are volatile XMM registers.
       FloatingPointHelper::LoadFloatOperands(masm, xmm4, xmm5);
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 8fbbe5a..4b0c77d 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -294,15 +294,6 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Compilation mode.  Either the compiler is used as the primary
-  // compiler and needs to setup everything or the compiler is used as
-  // the secondary compiler for split compilation and has to handle
-  // bailouts.
-  enum Mode {
-    PRIMARY,
-    SECONDARY
-  };
-
   // Takes a function literal, generates code for it. This function should only
   // be called by compiler.cc.
   static Handle<Code> MakeCode(CompilationInfo* info);
@@ -385,7 +376,7 @@
   void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
 
   // Main code generation function
-  void Generate(CompilationInfo* info, Mode mode);
+  void Generate(CompilationInfo* info);
 
   // Generate the return sequence code.  Should be called no more than
   // once per compiled function, immediately after binding the return
@@ -484,7 +475,8 @@
                                   Result* right,
                                   OverwriteMode overwrite_mode);
 
-  void Comparison(Condition cc,
+  void Comparison(AstNode* node,
+                  Condition cc,
                   bool strict,
                   ControlDestination* destination);
 
@@ -535,6 +527,7 @@
   void GenerateIsSmi(ZoneList<Expression*>* args);
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
+  void GenerateIsRegExp(ZoneList<Expression*>* args);
   void GenerateIsObject(ZoneList<Expression*>* args);
   void GenerateIsFunction(ZoneList<Expression*>* args);
   void GenerateIsUndetectableObject(ZoneList<Expression*>* args);
@@ -576,7 +569,14 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
-  // Simple condition analysis.
+  // Fast support for number to string.
+  void GenerateNumberToString(ZoneList<Expression*>* args);
+
+  // Fast call to math functions.
+  void GenerateMathSin(ZoneList<Expression*>* args);
+  void GenerateMathCos(ZoneList<Expression*>* args);
+
+// Simple condition analysis.
   enum ConditionAnalysis {
     ALWAYS_TRUE,
     ALWAYS_FALSE,
@@ -654,13 +654,15 @@
  public:
   GenericBinaryOpStub(Token::Value op,
                       OverwriteMode mode,
-                      GenericBinaryFlags flags)
+                      GenericBinaryFlags flags,
+                      NumberInfo::Type operands_type = NumberInfo::kUnknown)
       : op_(op),
         mode_(mode),
         flags_(flags),
         args_in_registers_(false),
         args_reversed_(false),
-        name_(NULL) {
+        name_(NULL),
+        operands_type_(operands_type) {
     use_sse3_ = CpuFeatures::IsSupported(SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -685,28 +687,32 @@
   bool args_reversed_;  // Left and right argument are swapped.
   bool use_sse3_;
   char* name_;
+  NumberInfo::Type operands_type_;
 
   const char* GetName();
 
 #ifdef DEBUG
   void Print() {
-    PrintF("GenericBinaryOpStub (op %s), "
-           "(mode %d, flags %d, registers %d, reversed %d)\n",
+    PrintF("GenericBinaryOpStub %d (op %s), "
+           "(mode %d, flags %d, registers %d, reversed %d, only_numbers %s)\n",
+           MinorKey(),
            Token::String(op_),
            static_cast<int>(mode_),
            static_cast<int>(flags_),
            static_cast<int>(args_in_registers_),
-           static_cast<int>(args_reversed_));
+           static_cast<int>(args_reversed_),
+           NumberInfo::ToString(operands_type_));
   }
 #endif
 
-  // Minor key encoding in 16 bits FRASOOOOOOOOOOMM.
+  // Minor key encoding in 16 bits NNNFRASOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
-  class OpBits: public BitField<Token::Value, 2, 10> {};
-  class SSE3Bits: public BitField<bool, 12, 1> {};
-  class ArgsInRegistersBits: public BitField<bool, 13, 1> {};
-  class ArgsReversedBits: public BitField<bool, 14, 1> {};
-  class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
+  class OpBits: public BitField<Token::Value, 2, 7> {};
+  class SSE3Bits: public BitField<bool, 9, 1> {};
+  class ArgsInRegistersBits: public BitField<bool, 10, 1> {};
+  class ArgsReversedBits: public BitField<bool, 11, 1> {};
+  class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
+  class NumberInfoBits: public BitField<NumberInfo::Type, 13, 3> {};
 
   Major MajorKey() { return GenericBinaryOp; }
   int MinorKey() {
@@ -716,7 +722,8 @@
            | FlagBits::encode(flags_)
            | SSE3Bits::encode(use_sse3_)
            | ArgsInRegistersBits::encode(args_in_registers_)
-           | ArgsReversedBits::encode(args_reversed_);
+           | ArgsReversedBits::encode(args_reversed_)
+           | NumberInfoBits::encode(operands_type_);
   }
 
   void Generate(MacroAssembler* masm);
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index ce3aae8..547daee 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -993,56 +993,22 @@
   byte* current = data + 2;
   // At return, "current" points to the start of the next instruction.
   const char* mnemonic = TwoByteMnemonic(opcode);
-  if (opcode == 0x1F) {
-    // NOP
+  if (operand_size_ == 0x66) {
+    // 0x66 0x0F prefix.
     int mod, regop, rm;
     get_modrm(*current, &mod, &regop, &rm);
-    current++;
-    if (regop == 4) {  // SIB byte present.
-      current++;
-    }
-    if (mod == 1) {  // Byte displacement.
-      current += 1;
-    } else if (mod == 2) {  // 32-bit displacement.
-      current += 4;
-    }  // else no immediate displacement.
-    AppendToBuffer("nop");
-
-  } else  if (opcode == 0xA2 || opcode == 0x31) {
-    // RDTSC or CPUID
-    AppendToBuffer("%s", mnemonic);
-
-  } else if ((opcode & 0xF0) == 0x40) {
-    // CMOVcc: conditional move.
-    int condition = opcode & 0x0F;
-    const InstructionDesc& idesc = cmov_instructions[condition];
-    byte_size_operand_ = idesc.byte_size_operation;
-    current += PrintOperands(idesc.mnem, idesc.op_order_, current);
-
-  } else if ((opcode & 0xF0) == 0x80) {
-    // Jcc: Conditional jump (branch).
-    current = data + JumpConditional(data);
-
-  } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
-             opcode == 0xB7 || opcode == 0xAF) {
-    // Size-extending moves, IMUL.
-    current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
-
-  } else if ((opcode & 0xF0) == 0x90) {
-    // SETcc: Set byte on condition. Needs pointer to beginning of instruction.
-    current = data + SetCC(data);
-
-  } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) {
-    // SHLD, SHRD (double-precision shift), BTS (bit set).
-    AppendToBuffer("%s ", mnemonic);
-    int mod, regop, rm;
-    get_modrm(*current, &mod, &regop, &rm);
-    current += PrintRightOperand(current);
-    if (opcode == 0xAB) {
-      AppendToBuffer(",%s", NameOfCPURegister(regop));
+    const char* mnemonic = "?";
+    if (opcode == 0x57) {
+      mnemonic = "xorpd";
+    } else if (opcode == 0x2E) {
+      mnemonic = "comisd";
+    } else if (opcode == 0x2F) {
+      mnemonic = "ucomisd";
     } else {
-      AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
+      UnimplementedInstruction();
     }
+    AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
+    current += PrintRightXMMOperand(current);
   } else if (group_1_prefix_ == 0xF2) {
     // Beginning of instructions with prefix 0xF2.
 
@@ -1080,6 +1046,55 @@
     // Assert that mod is not 3, so source is memory, not an XMM register.
     ASSERT_NE(0xC0, *current & 0xC0);
     current += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, current);
+  } else if (opcode == 0x1F) {
+    // NOP
+    int mod, regop, rm;
+    get_modrm(*current, &mod, &regop, &rm);
+    current++;
+    if (regop == 4) {  // SIB byte present.
+      current++;
+    }
+    if (mod == 1) {  // Byte displacement.
+      current += 1;
+    } else if (mod == 2) {  // 32-bit displacement.
+      current += 4;
+    }  // else no immediate displacement.
+    AppendToBuffer("nop");
+  } else if (opcode == 0xA2 || opcode == 0x31) {
+    // RDTSC or CPUID
+    AppendToBuffer("%s", mnemonic);
+
+  } else if ((opcode & 0xF0) == 0x40) {
+    // CMOVcc: conditional move.
+    int condition = opcode & 0x0F;
+    const InstructionDesc& idesc = cmov_instructions[condition];
+    byte_size_operand_ = idesc.byte_size_operation;
+    current += PrintOperands(idesc.mnem, idesc.op_order_, current);
+
+  } else if ((opcode & 0xF0) == 0x80) {
+    // Jcc: Conditional jump (branch).
+    current = data + JumpConditional(data);
+
+  } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
+             opcode == 0xB7 || opcode == 0xAF) {
+    // Size-extending moves, IMUL.
+    current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
+
+  } else if ((opcode & 0xF0) == 0x90) {
+    // SETcc: Set byte on condition. Needs pointer to beginning of instruction.
+    current = data + SetCC(data);
+
+  } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) {
+    // SHLD, SHRD (double-precision shift), BTS (bit set).
+    AppendToBuffer("%s ", mnemonic);
+    int mod, regop, rm;
+    get_modrm(*current, &mod, &regop, &rm);
+    current += PrintRightOperand(current);
+    if (opcode == 0xAB) {
+      AppendToBuffer(",%s", NameOfCPURegister(regop));
+    } else {
+      AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
+    }
   } else {
     UnimplementedInstruction();
   }
diff --git a/src/x64/fast-codegen-x64.cc b/src/x64/fast-codegen-x64.cc
index c6e7be2..4dbf26a 100644
--- a/src/x64/fast-codegen-x64.cc
+++ b/src/x64/fast-codegen-x64.cc
@@ -35,50 +35,35 @@
 
 #define __ ACCESS_MASM(masm())
 
-void FastCodeGenerator::EmitLoadReceiver(Register reg) {
+Register FastCodeGenerator::accumulator0() { return rax; }
+Register FastCodeGenerator::accumulator1() { return rdx; }
+Register FastCodeGenerator::scratch0() { return rcx; }
+Register FastCodeGenerator::scratch1() { return rdi; }
+Register FastCodeGenerator::receiver_reg() { return rbx; }
+Register FastCodeGenerator::context_reg() { return rsi; }
+
+
+void FastCodeGenerator::EmitLoadReceiver() {
   // Offset 2 is due to return address and saved frame pointer.
   int index = 2 + scope()->num_parameters();
-  __ movq(reg, Operand(rbp, index * kPointerSize));
-}
-
-
-void FastCodeGenerator::EmitReceiverMapCheck() {
-  Comment cmnt(masm(), ";; MapCheck(this)");
-  if (FLAG_print_ir) {
-    PrintF("MapCheck(this)\n");
-  }
-
-  ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
-  Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
-  Handle<Map> map(object->map());
-
-  EmitLoadReceiver(rdx);
-  __ CheckMap(rdx, map, bailout(), false);
-}
-
-
-void FastCodeGenerator::EmitGlobalMapCheck() {
-  Comment cmnt(masm(), ";; GlobalMapCheck");
-  if (FLAG_print_ir) {
-    PrintF(";; GlobalMapCheck()");
-  }
-
-  ASSERT(info()->has_global_object());
-  Handle<Map> map(info()->global_object()->map());
-
-  __ movq(rbx, CodeGenerator::GlobalObject());
-  __ CheckMap(rbx, map, bailout(), true);
+  __ movq(receiver_reg(), Operand(rbp, index * kPointerSize));
 }
 
 
 void FastCodeGenerator::EmitGlobalVariableLoad(Handle<Object> cell) {
+  ASSERT(!destination().is(no_reg));
   ASSERT(cell->IsJSGlobalPropertyCell());
-  __ Move(rax, cell);
-  __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset));
+
+  __ Move(destination(), cell);
+  __ movq(destination(),
+          FieldOperand(destination(), JSGlobalPropertyCell::kValueOffset));
   if (FLAG_debug_code) {
-    __ Cmp(rax, Factory::the_hole_value());
+    __ Cmp(destination(), Factory::the_hole_value());
     __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
 }
 
 
@@ -92,19 +77,111 @@
   int index = lookup.GetFieldIndex() - map->inobject_properties();
   int offset = index * kPointerSize;
 
-  // Negative offsets are inobject properties.
+  // We will emit the write barrier unless the stored value is statically
+  // known to be a smi.
+  bool needs_write_barrier = !is_smi(accumulator0());
+
+  // Perform the store.  Negative offsets are inobject properties.
   if (offset < 0) {
     offset += map->instance_size();
-    __ movq(rcx, rdx);  // Copy receiver for write barrier.
+    __ movq(FieldOperand(receiver_reg(), offset), accumulator0());
+    if (needs_write_barrier) {
+      // Preserve receiver from write barrier.
+      __ movq(scratch0(), receiver_reg());
+    }
   } else {
     offset += FixedArray::kHeaderSize;
-    __ movq(rcx, FieldOperand(rdx, JSObject::kPropertiesOffset));
+    __ movq(scratch0(),
+            FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ movq(FieldOperand(scratch0(), offset), accumulator0());
   }
-  // Perform the store.
-  __ movq(FieldOperand(rcx, offset), rax);
-  // Preserve value from write barrier in case it's needed.
-  __ movq(rbx, rax);
-  __ RecordWrite(rcx, offset, rbx, rdi);
+
+  if (needs_write_barrier) {
+    if (destination().is(no_reg)) {
+      // After RecordWrite accumulator0 is only accidently a smi, but it is
+      // already marked as not known to be one.
+      __ RecordWrite(scratch0(), offset, accumulator0(), scratch1());
+    } else {
+      // Copy the value to the other accumulator to preserve a copy from the
+      // write barrier. One of the accumulators is available as a scratch
+      // register.  Neither is a smi.
+      __ movq(accumulator1(), accumulator0());
+      clear_as_smi(accumulator1());
+      Register value_scratch = other_accumulator(destination());
+      __ RecordWrite(scratch0(), offset, value_scratch, scratch1());
+    }
+  } else if (destination().is(accumulator1())) {
+    __ movq(accumulator1(), accumulator0());
+    // Is a smi because we do not need the write barrier.
+    set_as_smi(accumulator1());
+  }
+}
+
+
+void FastCodeGenerator::EmitThisPropertyLoad(Handle<String> name) {
+  ASSERT(!destination().is(no_reg));
+  LookupResult lookup;
+  info()->receiver()->Lookup(*name, &lookup);
+
+  ASSERT(lookup.holder() == *info()->receiver());
+  ASSERT(lookup.type() == FIELD);
+  Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map());
+  int index = lookup.GetFieldIndex() - map->inobject_properties();
+  int offset = index * kPointerSize;
+
+  // Perform the load.  Negative offsets are inobject properties.
+  if (offset < 0) {
+    offset += map->instance_size();
+    __ movq(destination(), FieldOperand(receiver_reg(), offset));
+  } else {
+    offset += FixedArray::kHeaderSize;
+    __ movq(scratch0(),
+            FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
+    __ movq(destination(), FieldOperand(scratch0(), offset));
+  }
+
+  // The loaded value is not known to be a smi.
+  clear_as_smi(destination());
+}
+
+
+void FastCodeGenerator::EmitBitOr() {
+  if (is_smi(accumulator0()) && is_smi(accumulator1())) {
+    // If both operands are known to be a smi then there is no need to check
+    // the operands or result.
+    if (destination().is(no_reg)) {
+      __ or_(accumulator1(), accumulator0());
+    } else {
+      // Leave the result in the destination register.  Bitwise or is
+      // commutative.
+      __ or_(destination(), other_accumulator(destination()));
+    }
+  } else {
+    // Left is in accumulator1, right in accumulator0.
+    if (destination().is(accumulator0())) {
+      __ movq(scratch0(), accumulator0());
+      __ or_(destination(), accumulator1());  // Or is commutative.
+      Label* bailout =
+          info()->AddBailout(accumulator1(), scratch0());  // Left, right.
+      __ JumpIfNotSmi(destination(), bailout);
+    } else if (destination().is(accumulator1())) {
+      __ movq(scratch0(), accumulator1());
+      __ or_(destination(), accumulator0());
+      Label* bailout = info()->AddBailout(scratch0(), accumulator0());
+      __ JumpIfNotSmi(destination(), bailout);
+    } else {
+      ASSERT(destination().is(no_reg));
+      __ movq(scratch0(), accumulator1());
+      __ or_(scratch0(), accumulator0());
+      Label* bailout = info()->AddBailout(accumulator1(), accumulator0());
+      __ JumpIfNotSmi(scratch0(), bailout);
+    }
+  }
+
+  // If we didn't bailout, the result (in fact, both inputs too) is known to
+  // be a smi.
+  set_as_smi(accumulator0());
+  set_as_smi(accumulator1());
 }
 
 
@@ -121,24 +198,43 @@
   // Note that we keep a live register reference to esi (context) at this
   // point.
 
-  // Receiver (this) is allocated to rdx if there are this properties.
-  if (info()->has_this_properties()) EmitReceiverMapCheck();
+  Label* bailout_to_beginning = info()->AddBailout();
+  // Receiver (this) is allocated to a fixed register.
+  if (info()->has_this_properties()) {
+    Comment cmnt(masm(), ";; MapCheck(this)");
+    if (FLAG_print_ir) {
+      PrintF("MapCheck(this)\n");
+    }
+    ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
+    Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
+    Handle<Map> map(object->map());
+    EmitLoadReceiver();
+    __ CheckMap(receiver_reg(), map, bailout_to_beginning, false);
+  }
 
-  // If there is a global variable access check if the global object
-  // is the same as at lazy-compilation time.
-  if (info()->has_globals()) EmitGlobalMapCheck();
+  // If there is a global variable access check if the global object is the
+  // same as at lazy-compilation time.
+  if (info()->has_globals()) {
+    Comment cmnt(masm(), ";; MapCheck(GLOBAL)");
+    if (FLAG_print_ir) {
+      PrintF("MapCheck(GLOBAL)\n");
+    }
+    ASSERT(info()->has_global_object());
+    Handle<Map> map(info()->global_object()->map());
+    __ movq(scratch0(), CodeGenerator::GlobalObject());
+    __ CheckMap(scratch0(), map, bailout_to_beginning, true);
+  }
 
   VisitStatements(info()->function()->body());
 
   Comment return_cmnt(masm(), ";; Return(<undefined>)");
+  if (FLAG_print_ir) {
+    PrintF("Return(<undefined>)\n");
+  }
   __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
-
-  Comment epilogue_cmnt(masm(), ";; Epilogue");
   __ movq(rsp, rbp);
   __ pop(rbp);
   __ ret((scope()->num_parameters() + 1) * kPointerSize);
-
-  __ bind(&bailout_);
 }
 
 
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 2e95c68..30db660 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1015,6 +1015,92 @@
 }
 
 
+void FullCodeGenerator::VisitAssignment(Assignment* expr) {
+  Comment cmnt(masm_, "[ Assignment");
+  ASSERT(expr->op() != Token::INIT_CONST);
+  // Left-hand side can only be a property, a global or a (parameter or local)
+  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
+  LhsKind assign_type = VARIABLE;
+  Property* prop = expr->target()->AsProperty();
+  if (prop != NULL) {
+    assign_type =
+        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
+  }
+
+  // Evaluate LHS expression.
+  switch (assign_type) {
+    case VARIABLE:
+      // Nothing to do here.
+      break;
+    case NAMED_PROPERTY:
+      if (expr->is_compound()) {
+        // We need the receiver both on the stack and in the accumulator.
+        VisitForValue(prop->obj(), kAccumulator);
+        __ push(result_register());
+      } else {
+        VisitForValue(prop->obj(), kStack);
+      }
+      break;
+    case KEYED_PROPERTY:
+      VisitForValue(prop->obj(), kStack);
+      VisitForValue(prop->key(), kStack);
+      break;
+  }
+
+  // If we have a compound assignment: Get value of LHS expression and
+  // store in on top of the stack.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kStack;
+    switch (assign_type) {
+      case VARIABLE:
+        EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
+                         Expression::kValue);
+        break;
+      case NAMED_PROPERTY:
+        EmitNamedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+      case KEYED_PROPERTY:
+        EmitKeyedPropertyLoad(prop);
+        __ push(result_register());
+        break;
+    }
+    location_ = saved_location;
+  }
+
+  // Evaluate RHS expression.
+  Expression* rhs = expr->value();
+  VisitForValue(rhs, kAccumulator);
+
+  // If we have a compound assignment: Apply operator.
+  if (expr->is_compound()) {
+    Location saved_location = location_;
+    location_ = kAccumulator;
+    EmitBinaryOp(expr->binary_op(), Expression::kValue);
+    location_ = saved_location;
+  }
+
+  // Record source position before possible IC call.
+  SetSourcePosition(expr->position());
+
+  // Store the value.
+  switch (assign_type) {
+    case VARIABLE:
+      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
+                             context_);
+      break;
+    case NAMED_PROPERTY:
+      EmitNamedPropertyAssignment(expr);
+      break;
+    case KEYED_PROPERTY:
+      EmitKeyedPropertyAssignment(expr);
+      break;
+  }
+}
+
+
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
@@ -1200,7 +1286,7 @@
 
 
 void FullCodeGenerator::EmitCallWithIC(Call* expr,
-                                       Handle<Object> ignored,
+                                       Handle<Object> name,
                                        RelocInfo::Mode mode) {
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
@@ -1208,6 +1294,7 @@
   for (int i = 0; i < arg_count; i++) {
     VisitForValue(args->at(i), kStack);
   }
+  __ Move(rcx, name);
   // Record source position for debugger.
   SetSourcePosition(expr->position());
   // Call the IC initialization code.
@@ -1217,8 +1304,7 @@
   __ Call(ic, mode);
   // Restore context register.
   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-  // Discard the function left on TOS.
-  DropAndApply(1, context_, rax);
+  Apply(context_, rax);
 }
 
 
@@ -1250,7 +1336,6 @@
     UNREACHABLE();
   } else if (var != NULL && !var->is_this() && var->is_global()) {
     // Call to a global variable.
-    __ Push(var->name());
     // Push global object as receiver for the call IC lookup.
     __ push(CodeGenerator::GlobalObject());
     EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
@@ -1264,7 +1349,6 @@
     Literal* key = prop->key()->AsLiteral();
     if (key != NULL && key->handle()->IsSymbol()) {
       // Call to a named property, use call IC.
-      __ Push(key->handle());
       VisitForValue(prop->obj(), kStack);
       EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
     } else {
@@ -1355,7 +1439,6 @@
 
   if (expr->is_jsruntime()) {
     // Prepare for calling JS runtime function.
-    __ Push(expr->name());
     __ movq(rax, CodeGenerator::GlobalObject());
     __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
   }
@@ -1367,18 +1450,17 @@
   }
 
   if (expr->is_jsruntime()) {
-    // Call the JS runtime function.
-    Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
-                                                           NOT_IN_LOOP);
+    // Call the JS runtime function using a call IC.
+    __ Move(rcx, expr->name());
+    InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
+    Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
     __ call(ic, RelocInfo::CODE_TARGET);
     // Restore context register.
     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-    // Discard the function left on TOS.
-    DropAndApply(1, context_, rax);
   } else {
     __ CallRuntime(expr->function(), arg_count);
-    Apply(context_, rax);
   }
+  Apply(context_, rax);
 }
 
 
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 99a8c7d..8d43332 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -212,23 +212,37 @@
 }
 
 
-void KeyedLoadIC::Generate(MacroAssembler* masm,
-                           ExternalReference const& f) {
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rsp[0]  : return address
   //  -- rsp[8]  : name
   //  -- rsp[16] : receiver
   // -----------------------------------
 
-  __ movq(rax, Operand(rsp, kPointerSize));
-  __ movq(rcx, Operand(rsp, 2 * kPointerSize));
   __ pop(rbx);
-  __ push(rcx);  // receiver
-  __ push(rax);  // name
+  __ push(Operand(rsp, 1 * kPointerSize));  // receiver
+  __ push(Operand(rsp, 1 * kPointerSize));  // name
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rsp[0]  : return address
+  //  -- rsp[8]  : name
+  //  -- rsp[16] : receiver
+  // -----------------------------------
+
+  __ pop(rbx);
+  __ push(Operand(rsp, 1 * kPointerSize));  // receiver
+  __ push(Operand(rsp, 1 * kPointerSize));  // name
+  __ push(rbx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1);
 }
 
 
@@ -301,7 +315,7 @@
   // Slow case: Load name and receiver from stack and jump to runtime.
   __ bind(&slow);
   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
-  Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
+  GenerateRuntimeGetProperty(masm);
   __ bind(&check_string);
   // The key is not a smi.
   // Is it a string?
@@ -538,21 +552,54 @@
   // Slow case: Load name and receiver from stack and jump to runtime.
   __ bind(&slow);
   __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
-  Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
+  GenerateRuntimeGetProperty(masm);
 }
 
 
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rsp[0] : return address
-  //  -- rsp[8] : name
+  //  -- rsp[8] : key
   //  -- rsp[16] : receiver
   // -----------------------------------
-  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
+  Label slow;
+
+  // Load key and receiver.
+  __ movq(rax, Operand(rsp, kPointerSize));
+  __ movq(rcx, Operand(rsp, 2 * kPointerSize));
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(rcx, &slow);
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(rax, &slow);
+
+  // Get the map of the receiver.
+  __ movq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
+
+  // Check that it has indexed interceptor and access checks
+  // are not enabled for this object.
+  __ movb(rdx, FieldOperand(rdx, Map::kBitFieldOffset));
+  __ andb(rdx, Immediate(kSlowCaseBitFieldMask));
+  __ cmpb(rdx, Immediate(1 << Map::kHasIndexedInterceptor));
+  __ j(not_zero, &slow);
+
+  // Everything is fine, call runtime.
+  __ pop(rdx);
+  __ push(rcx);  // receiver
+  __ push(rax);  // key
+  __ push(rdx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(ExternalReference(
+        IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
+
+  __ bind(&slow);
+  GenerateMiss(masm);
 }
 
 
-void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax     : value
   //  -- rsp[0]  : return address
@@ -567,28 +614,26 @@
   __ push(rcx);  // return address
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(f, 3, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
 }
 
 
-void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax     : value
-  //  -- rcx     : transition map
   //  -- rsp[0]  : return address
   //  -- rsp[8]  : key
   //  -- rsp[16] : receiver
   // -----------------------------------
 
-  __ pop(rbx);
+  __ pop(rcx);
   __ push(Operand(rsp, 1 * kPointerSize));  // receiver
-  __ push(rcx);  // transition map
+  __ push(Operand(rsp, 1 * kPointerSize));  // key
   __ push(rax);  // value
-  __ push(rbx);  // return address
+  __ push(rcx);  // return address
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 }
 
 
@@ -642,7 +687,7 @@
 
   // Slow case: call runtime.
   __ bind(&slow);
-  Generate(masm, ExternalReference(Runtime::kSetProperty));
+  GenerateRuntimeSetProperty(masm);
 
   // Check whether the elements is a pixel array.
   // rax: value
@@ -906,23 +951,29 @@
 
   // Slow case: call runtime.
   __ bind(&slow);
-  Generate(masm, ExternalReference(Runtime::kSetProperty));
+  GenerateRuntimeSetProperty(masm);
 }
 
 
 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
+  // ----------- S t a t e -------------
+  // rcx                      : function name
+  // rsp[0]                   : return address
+  // rsp[8]                   : argument argc
+  // rsp[16]                  : argument argc - 1
+  // ...
+  // rsp[argc * 8]            : argument 1
+  // rsp[(argc + 1) * 8]      : argument 0 = receiver
+  // -----------------------------------
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
-  // Get the name of the function to call from the stack.
-  // 2 ~ receiver, return address.
-  __ movq(rbx, Operand(rsp, (argc + 2) * kPointerSize));
 
   // Enter an internal frame.
   __ EnterInternalFrame();
 
   // Push the receiver and the name of the function.
   __ push(rdx);
-  __ push(rbx);
+  __ push(rcx);
 
   // Call the entry.
   CEntryStub stub(1);
@@ -960,20 +1011,18 @@
 
 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  // rsp[0] return address
-  // rsp[8] argument argc
-  // rsp[16] argument argc - 1
+  // rcx                      : function name
+  // rsp[0]                   : return address
+  // rsp[8]                   : argument argc
+  // rsp[16]                  : argument argc - 1
   // ...
-  // rsp[argc * 8] argument 1
-  // rsp[(argc + 1) * 8] argument 0 = receiver
-  // rsp[(argc + 2) * 8] function name
+  // rsp[argc * 8]            : argument 1
+  // rsp[(argc + 1) * 8]      : argument 0 = receiver
   // -----------------------------------
   Label number, non_number, non_string, boolean, probe, miss;
 
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
-  // Get the name of the function from the stack; 2 ~ return address, receiver
-  __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
 
   // Probe the stub cache.
   Code::Flags flags =
@@ -1026,6 +1075,16 @@
                                  int argc,
                                  bool is_global_object,
                                  Label* miss) {
+  // ----------- S t a t e -------------
+  // rcx                    : function name
+  // rdx                    : receiver
+  // rsp[0]                 : return address
+  // rsp[8]                 : argument argc
+  // rsp[16]                : argument argc - 1
+  // ...
+  // rsp[argc * 8]          : argument 1
+  // rsp[(argc + 1) * 8]    : argument 0 = receiver
+  // -----------------------------------
   // Search dictionary - put result in register rdx.
   GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, CHECK_DICTIONARY);
 
@@ -1052,20 +1111,18 @@
 
 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  // rsp[0] return address
-  // rsp[8] argument argc
-  // rsp[16] argument argc - 1
+  // rcx                    : function name
+  // rsp[0]                 : return address
+  // rsp[8]                 : argument argc
+  // rsp[16]                : argument argc - 1
   // ...
-  // rsp[argc * 8] argument 1
-  // rsp[(argc + 1) * 8] argument 0 = receiver
-  // rsp[(argc + 2) * 8] function name
+  // rsp[argc * 8]          : argument 1
+  // rsp[(argc + 1) * 8]    : argument 0 = receiver
   // -----------------------------------
   Label miss, global_object, non_global_object;
 
   // Get the receiver of the function from the stack.
   __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
-  // Get the name of the function from the stack.
-  __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
 
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss);
@@ -1132,22 +1189,20 @@
 }
 
 
-void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
+void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rcx    : name
   //  -- rsp[0] : return address
   //  -- rsp[8] : receiver
   // -----------------------------------
 
-  __ movq(rax, Operand(rsp, kPointerSize));
-
   __ pop(rbx);
-  __ push(rax);  // receiver
+  __ push(Operand(rsp, 0));  // receiver
   __ push(rcx);  // name
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2, 1);
+  __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
 }
 
 
@@ -1203,17 +1258,6 @@
 }
 
 
-void LoadIC::GenerateMiss(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  //  -- rsp[8] : receiver
-  // -----------------------------------
-
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
-}
-
-
 void LoadIC::GenerateNormal(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rcx    : name
@@ -1256,7 +1300,7 @@
   // Cache miss: Restore receiver from stack and jump to runtime.
   __ bind(&miss);
   __ movq(rax, Operand(rsp, 1 * kPointerSize));
-  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
+  GenerateMiss(masm);
 }
 
 
@@ -1270,13 +1314,12 @@
 
   __ movq(rax, Operand(rsp, kPointerSize));
 
-  StubCompiler::GenerateLoadStringLength(masm, rax, rdx, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
 }
 
 
-
 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
   // The address of the instruction following the call.
   Address test_instruction_address =
@@ -1304,6 +1347,7 @@
   return true;
 }
 
+
 void StoreIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : value
@@ -1322,24 +1366,6 @@
   __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
 }
 
-void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : Map (target of map transition)
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-
-  __ pop(rbx);
-  __ push(rdx);  // receiver
-  __ push(rcx);  // transition map
-  __ push(rax);  // value
-  __ push(rbx);  // return address
-
-  // Perform tail call to the entry.
-  __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
-}
 
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 56bbc20..90a9c75 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -39,7 +39,6 @@
 
 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -387,6 +386,16 @@
 }
 
 
+void MacroAssembler::CallExternalReference(const ExternalReference& ext,
+                                           int num_arguments) {
+  movq(rax, Immediate(num_arguments));
+  movq(rbx, ext);
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
                                      int num_arguments,
                                      int result_size) {
@@ -415,38 +424,30 @@
 }
 
 
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
+  // Calls are not allowed in some stubs.
+  ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
 
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  movq(target, code, RelocInfo::EMBEDDED_OBJECT);
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - sizeof(intptr_t), flags, name };
-    unresolved_.Add(entry);
-  }
-  addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+  // Rely on the assertion to check that the number of provided
+  // arguments match the expected number of arguments. Fake a
+  // parameter count to avoid emitting code to do the check.
+  ParameterCount expected(0);
+  GetBuiltinEntry(rdx, id);
+  InvokeCode(rdx, expected, expected, flag);
 }
 
-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Move the builtin function into the temporary function slot by
-  // reading it from the builtins object. NOTE: We should be able to
-  // reduce this to two instructions by putting the function table in
-  // the global object instead of the "builtins" object and by using a
-  // real register for the function.
-  movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  movq(rdx, FieldOperand(rdx, GlobalObject::kBuiltinsOffset));
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+  // Load the JavaScript builtin function from the builtins object.
+  movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset));
   int builtins_offset =
       JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
-  movq(rdi, FieldOperand(rdx, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
+  movq(rdi, FieldOperand(rdi, builtins_offset));
+  // Load the code entry point from the function into the target register.
+  movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+  movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
+  addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
 }
 
 
@@ -1597,6 +1598,17 @@
 }
 
 
+void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
+  Label ok;
+  Condition is_smi = CheckSmi(object);
+  j(is_smi, &ok);
+  Cmp(FieldOperand(object, HeapObject::kMapOffset),
+      Factory::heap_number_map());
+  Assert(equal, msg);
+  bind(&ok);
+}
+
+
 Condition MacroAssembler::IsObjectStringType(Register heap_object,
                                              Register map,
                                              Register instance_type) {
@@ -1774,39 +1786,14 @@
   }
 }
 
-#endif  // ENABLE_DEBUGGER_SUPPORT
-
-
-void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  // Calls are not allowed in some stubs.
-  ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
-
-  // Rely on the assertion to check that the number of provided
-  // arguments match the expected number of arguments. Fake a
-  // parameter count to avoid emitting code to do the check.
-  ParameterCount expected(0);
-  InvokeCode(Handle<Code>(code),
-             expected,
-             expected,
-             RelocInfo::CODE_TARGET,
-             flag);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-  // The target address for the jump is stored as an immediate at offset
-  // kInvokeCodeAddressOffset.
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry =
-        { pc_offset() - kCallTargetAddressOffset, flags, name };
-    unresolved_.Add(entry);
-  }
+void MacroAssembler::DebugBreak() {
+  ASSERT(allow_stub_calls());
+  xor_(rax, rax);  // no arguments
+  movq(rbx, ExternalReference(Runtime::kDebugBreak));
+  CEntryStub ces(1);
+  Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
 }
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 
 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
@@ -1926,6 +1913,21 @@
 }
 
 
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+  // Get the function and setup the context.
+  Move(rdi, Handle<JSFunction>(function));
+  movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   push(rbp);
   movq(rbp, rsp);
@@ -1965,13 +1967,9 @@
 
   // Reserve room for entry stack pointer and push the debug marker.
   ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
-  push(Immediate(0));  // saved entry sp, patched before call
-  if (mode == ExitFrame::MODE_DEBUG) {
-    push(Immediate(0));
-  } else {
-    movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
-    push(kScratchRegister);
-  }
+  push(Immediate(0));  // Saved entry sp, patched before call.
+  movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
+  push(kScratchRegister);  // Accessed from EditFrame::code_slot.
 
   // Save the frame pointer and the context in top.
   ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index a975dca..2673086 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -36,7 +36,7 @@
 // Default scratch register used by MacroAssembler (and other code that needs
 // a spare register). The register isn't callee save, and not used by the
 // function calling convention.
-static const Register kScratchRegister = r10;
+static const Register kScratchRegister = { 10 };  // r10.
 
 // Convenience for platform-independent signatures.
 typedef Operand MemOperand;
@@ -98,6 +98,7 @@
   void CopyRegistersFromStackToMemory(Register base,
                                       Register scratch,
                                       RegList regs);
+  void DebugBreak();
 #endif
 
   // ---------------------------------------------------------------------------
@@ -148,6 +149,10 @@
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
   void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
@@ -481,6 +486,9 @@
   // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
   void FCmp();
 
+  // Abort execution if argument is not a number. Used in debug code.
+  void AbortIfNotNumber(Register object, const char* msg);
+
   // ---------------------------------------------------------------------------
   // Exception handling
 
@@ -643,6 +651,10 @@
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId id, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(const ExternalReference& ext,
+                             int num_arguments);
+
   // Tail call of a runtime routine (jump).
   // Like JumpToRuntime, but also takes care of passing the number
   // of arguments.
@@ -679,13 +691,6 @@
 
   void Ret();
 
-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }
 
 
@@ -717,7 +722,6 @@
   bool allow_stub_calls() { return allow_stub_calls_; }
 
  private:
-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
@@ -731,18 +735,6 @@
                       Label* done,
                       InvokeFlag flag);
 
-  // Prepares for a call or jump to a builtin by doing two things:
-  // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
-  //    compile time, so that later code can emit instructions to jump or call
-  //    the builtin directly.  If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
-  //    output parameter "resolved" to false.  Code that uses the return value
-  //    should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 693447b..9c8b4f7 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -133,11 +133,10 @@
 }
 
 
-template <typename Pushable>
 static void PushInterceptorArguments(MacroAssembler* masm,
                                      Register receiver,
                                      Register holder,
-                                     Pushable name,
+                                     Register name,
                                      JSObject* holder_obj) {
   __ push(receiver);
   __ push(holder);
@@ -201,8 +200,9 @@
 }
 
 
+// Both name_reg and receiver_reg are preserved on jumps to miss_label,
+// but may be destroyed if store is successful.
 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
-                                      Builtins::Name storage_extend,
                                       JSObject* object,
                                       int index,
                                       Map* transition,
@@ -231,9 +231,13 @@
   if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
     // The properties must be extended before we can store the value.
     // We jump to a runtime call that extends the properties array.
-    __ Move(rcx, Handle<Map>(transition));
-    Handle<Code> ic(Builtins::builtin(storage_extend));
-    __ Jump(ic, RelocInfo::CODE_TARGET);
+    __ pop(scratch);  // Return address.
+    __ push(receiver_reg);
+    __ Push(Handle<Map>(transition));
+    __ push(rax);
+    __ push(scratch);
+    __ TailCallRuntime(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
     return;
   }
 
@@ -314,38 +318,39 @@
 
 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
                                             Register receiver,
-                                            Register scratch,
+                                            Register scratch1,
+                                            Register scratch2,
                                             Label* miss) {
-  Label load_length, check_wrapper;
+  Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch register.
-  GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
 
   // Load length directly from the string.
-  __ bind(&load_length);
   __ movl(rax, FieldOperand(receiver, String::kLengthOffset));
   __ Integer32ToSmi(rax, rax);
   __ ret(0);
 
   // Check if the object is a JSValue wrapper.
   __ bind(&check_wrapper);
-  __ cmpl(scratch, Immediate(JS_VALUE_TYPE));
+  __ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
   __ j(not_equal, miss);
 
   // Check if the wrapped value is a string and load the length
   // directly if it is.
-  __ movq(receiver, FieldOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, receiver, scratch, miss, miss);
-  __ jmp(&load_length);
+  __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
+  GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
+  __ movl(rax, FieldOperand(scratch2, String::kLengthOffset));
+  __ Integer32ToSmi(rax, rax);
+  __ ret(0);
 }
 
 
-template <class Pushable>
 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
                                                    Register receiver,
                                                    Register holder,
-                                                   Pushable name,
+                                                   Register name,
                                                    JSObject* holder_obj) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
 
@@ -394,7 +399,7 @@
       stub_compiler->CheckPrototypes(object, receiver, holder,
                                      scratch1, scratch2, name, miss);
 
-  if (lookup->IsValid() && lookup->IsCacheable()) {
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
     compiler->CompileCacheable(masm,
                                stub_compiler,
                                receiver,
@@ -430,7 +435,7 @@
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -553,8 +558,8 @@
 
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
-  explicit CallInterceptorCompiler(const ParameterCount& arguments)
-      : arguments_(arguments), argc_(arguments.immediate()) {}
+  CallInterceptorCompiler(const ParameterCount& arguments, Register name)
+      : arguments_(arguments), name_(name) {}
 
   void CompileCacheable(MacroAssembler* masm,
                         StubCompiler* stub_compiler,
@@ -584,18 +589,20 @@
       return;
     }
 
+    ASSERT(!lookup->holder()->IsGlobalObject());
+
     __ EnterInternalFrame();
-    __ push(holder);  // save the holder
+    __ push(holder);  // Save the holder.
+    __ push(name_);  // Save the name.
 
-    CompileCallLoadPropertyWithInterceptor(
-        masm,
-        receiver,
-        holder,
-        // Under EnterInternalFrame this refers to name.
-        Operand(rbp, (argc_ + 3) * kPointerSize),
-        holder_obj);
+    CompileCallLoadPropertyWithInterceptor(masm,
+                                           receiver,
+                                           holder,
+                                           name_,
+                                           holder_obj);
 
-    __ pop(receiver);  // restore holder
+    __ pop(name_);  // Restore the name.
+    __ pop(receiver);  // Restore the holder.
     __ LeaveInternalFrame();
 
     __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
@@ -607,22 +614,8 @@
                                    scratch2,
                                    name,
                                    miss_label);
-    if (lookup->holder()->IsGlobalObject()) {
-      __ movq(rdx, Operand(rsp, (argc_ + 1) * kPointerSize));
-      __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-      __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdx);
-    }
 
-    ASSERT(function->is_compiled());
-    // Get the function and setup the context.
-    __ Move(rdi, Handle<JSFunction>(function));
-    __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-
-    // Jump to the cached code (tail call).
-    Handle<Code> code(function->code());
-    ParameterCount expected(function->shared()->formal_parameter_count());
-    __ InvokeCode(code, expected, arguments_,
-                  RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+    __ InvokeFunction(function, arguments_, JUMP_FUNCTION);
 
     __ bind(&invoke);
   }
@@ -634,27 +627,26 @@
                       JSObject* holder_obj,
                       Label* miss_label) {
     __ EnterInternalFrame();
+    // Save the name_ register across the call.
+    __ push(name_);
 
     PushInterceptorArguments(masm,
                              receiver,
                              holder,
-                             Operand(rbp, (argc_ + 3) * kPointerSize),
+                             name_,
                              holder_obj);
 
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ movq(rax, Immediate(5));
-    __ movq(rbx, ref);
+    __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+        5);
 
-    CEntryStub stub(1);
-    __ CallStub(&stub);
-
+    __ pop(name_);
     __ LeaveInternalFrame();
   }
 
  private:
   const ParameterCount& arguments_;
-  int argc_;
+  Register name_;
 };
 
 
@@ -669,14 +661,14 @@
                                               String* name,
                                               StubCompiler::CheckType check) {
   // ----------- S t a t e -------------
-  // -----------------------------------
-  // rsp[0] return address
-  // rsp[8] argument argc
-  // rsp[16] argument argc - 1
+  // rcx                 : function name
+  // rsp[0]              : return address
+  // rsp[8]              : argument argc
+  // rsp[16]             : argument argc - 1
   // ...
-  // rsp[argc * 8] argument 1
-  // rsp[(argc + 1) * 8] argument 0 = receiver
-  // rsp[(argc + 2) * 8] function name
+  // rsp[argc * 8]       : argument 1
+  // rsp[(argc + 1) * 8] : argument 0 = receiver
+  // -----------------------------------
 
   Label miss;
 
@@ -697,7 +689,7 @@
     case RECEIVER_MAP_CHECK:
       // Check that the maps haven't changed.
       CheckPrototypes(JSObject::cast(object), rdx, holder,
-                      rbx, rcx, name, &miss);
+                      rbx, rax, name, &miss);
 
       // Patch the receiver on the stack with the global proxy if
       // necessary.
@@ -713,13 +705,13 @@
         __ jmp(&miss);
       } else {
         // Check that the object is a two-byte string or a symbol.
-        __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rcx);
+        __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
         __ j(above_equal, &miss);
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::STRING_FUNCTION_INDEX,
-                                            rcx);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
+                                            rax);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
                         rbx, rdx, name, &miss);
       }
       break;
@@ -732,14 +724,14 @@
         Label fast;
         // Check that the object is a smi or a heap number.
         __ JumpIfSmi(rdx, &fast);
-        __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
+        __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
         __ j(not_equal, &miss);
         __ bind(&fast);
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::NUMBER_FUNCTION_INDEX,
-                                            rcx);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
+                                            rax);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
                         rbx, rdx, name, &miss);
       }
       break;
@@ -760,8 +752,8 @@
         // Check that the maps starting from the prototype haven't changed.
         GenerateLoadGlobalFunctionPrototype(masm(),
                                             Context::BOOLEAN_FUNCTION_INDEX,
-                                            rcx);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
+                                            rax);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
                         rbx, rdx, name, &miss);
       }
       break;
@@ -769,7 +761,7 @@
 
     case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
       CheckPrototypes(JSObject::cast(object), rdx, holder,
-                      rbx, rcx, name, &miss);
+                      rbx, rax, name, &miss);
       // Make sure object->HasFastElements().
       // Get the elements array of the object.
       __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -783,16 +775,7 @@
       UNREACHABLE();
   }
 
-  // Get the function and setup the context.
-  __ Move(rdi, Handle<JSFunction>(function));
-  __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-
-  // Jump to the cached code (tail call).
-  ASSERT(function->is_compiled());
-  Handle<Code> code(function->code());
-  ParameterCount expected(function->shared()->formal_parameter_count());
-  __ InvokeCode(code, expected, arguments(),
-                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -808,19 +791,19 @@
 }
 
 
-Object* CallStubCompiler::CompileCallField(Object* object,
+Object* CallStubCompiler::CompileCallField(JSObject* object,
                                            JSObject* holder,
                                            int index,
                                            String* name) {
   // ----------- S t a t e -------------
-  // -----------------------------------
-  // rsp[0] return address
-  // rsp[8] argument argc
-  // rsp[16] argument argc - 1
+  // rcx                 : function name
+  // rsp[0]              : return address
+  // rsp[8]              : argument argc
+  // rsp[16]             : argument argc - 1
   // ...
-  // rsp[argc * 8] argument 1
-  // rsp[(argc + 1) * 8] argument 0 = receiver
-  // rsp[(argc + 2) * 8] function name
+  // rsp[argc * 8]       : argument 1
+  // rsp[(argc + 1) * 8] : argument 0 = receiver
+  // -----------------------------------
   Label miss;
 
   // Get the receiver from the stack.
@@ -831,9 +814,7 @@
   __ JumpIfSmi(rdx, &miss);
 
   // Do the right check and compute the holder register.
-  Register reg =
-      CheckPrototypes(JSObject::cast(object), rdx, holder,
-                      rbx, rcx, name, &miss);
+  Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss);
 
   GenerateFastPropertyLoad(masm(), rdi, reg, holder, index);
 
@@ -862,10 +843,17 @@
 }
 
 
-Object* CallStubCompiler::CompileCallInterceptor(Object* object,
+Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
+  // rcx                 : function name
+  // rsp[0]              : return address
+  // rsp[8]              : argument argc
+  // rsp[16]             : argument argc - 1
+  // ...
+  // rsp[argc * 8]       : argument 1
+  // rsp[(argc + 1) * 8] : argument 0 = receiver
   // -----------------------------------
   Label miss;
 
@@ -878,17 +866,17 @@
   // Get the receiver from the stack.
   __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
 
-  CallInterceptorCompiler compiler(arguments());
+  CallInterceptorCompiler compiler(arguments(), rcx);
   CompileLoadInterceptor(&compiler,
                          this,
                          masm(),
-                         JSObject::cast(object),
+                         object,
                          holder,
                          name,
                          &lookup,
                          rdx,
                          rbx,
-                         rcx,
+                         rdi,
                          &miss);
 
   // Restore receiver.
@@ -920,7 +908,6 @@
 }
 
 
-
 Object* CallStubCompiler::CompileCallGlobal(JSObject* object,
                                             GlobalObject* holder,
                                             JSGlobalPropertyCell* cell,
@@ -928,13 +915,13 @@
                                             String* name) {
   // ----------- S t a t e -------------
   // -----------------------------------
-  // rsp[0] return address
-  // rsp[8] argument argc
-  // rsp[16] argument argc - 1
+  // rcx                 : function name
+  // rsp[0]              : return address
+  // rsp[8]              : argument argc
+  // rsp[16]             : argument argc - 1
   // ...
-  // rsp[argc * 8] argument 1
-  // rsp[(argc + 1) * 8] argument 0 = receiver
-  // rsp[(argc + 2) * 8] function name
+  // rsp[argc * 8]       : argument 1
+  // rsp[(argc + 1) * 8] : argument 0 = receiver
   Label miss;
 
   // Get the number of arguments.
@@ -951,7 +938,7 @@
   }
 
   // Check that the maps haven't changed.
-  CheckPrototypes(object, rdx, holder, rbx, rcx, name, &miss);
+  CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss);
 
   // Get the value from the cell.
   __ Move(rdi, Handle<JSGlobalPropertyCell>(cell));
@@ -965,12 +952,12 @@
     // function can all use this call IC. Before we load through the
     // function, we have to verify that it still is a function.
     __ JumpIfSmi(rdi, &miss);
-    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
     __ j(not_equal, &miss);
 
     // Check the shared function info. Make sure it hasn't changed.
-    __ Move(rcx, Handle<SharedFunctionInfo>(function->shared()));
-    __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rcx);
+    __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
+    __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
     __ j(not_equal, &miss);
   } else {
     __ Cmp(rdi, Handle<JSFunction>(function));
@@ -1325,7 +1312,7 @@
   __ Cmp(rax, Handle<String>(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadStringLength(masm(), rcx, rdx, &miss);
+  GenerateLoadStringLength(masm(), rcx, rdx, rbx, &miss);
   __ bind(&miss);
   __ DecrementCounter(&Counters::keyed_load_string_length, 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -1397,9 +1384,8 @@
   // -----------------------------------
   Label miss;
 
-  // Generate store field code.  Trashes the name register.
+  // Generate store field code.  Preserves receiver and name on jump to miss.
   GenerateStoreField(masm(),
-                     Builtins::StoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
@@ -1408,7 +1394,6 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ Move(rcx, Handle<String>(name));  // restore name
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
@@ -1550,16 +1535,15 @@
   __ Cmp(rcx, Handle<String>(name));
   __ j(not_equal, &miss);
 
-  // Get the object from the stack.
-  __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+  // Get the receiver from the stack.
+  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
 
-  // Generate store field code.  Trashes the name register.
+  // Generate store field code.  Preserves receiver and name on jump to miss.
   GenerateStoreField(masm(),
-                     Builtins::KeyedStoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
-                     rbx, rcx, rdx,
+                     rdx, rcx, rbx,
                      &miss);
 
   // Handle store cache miss.
@@ -1665,7 +1649,11 @@
                                        Register holder_reg,
                                        Register scratch,
                                        String* name,
+                                       int save_at_depth,
                                        Label* miss) {
+  // TODO(602): support object saving.
+  ASSERT(save_at_depth == kInvalidProtoDepth);
+
   // Check that the maps haven't changed.
   Register result =
       __ CheckMaps(object, object_reg, holder, holder_reg, scratch, miss);
diff --git a/src/x64/virtual-frame-x64.cc b/src/x64/virtual-frame-x64.cc
index cb93d5d..a0e883c 100644
--- a/src/x64/virtual-frame-x64.cc
+++ b/src/x64/virtual-frame-x64.cc
@@ -45,7 +45,7 @@
     : elements_(parameter_count() + local_count() + kPreallocatedElements),
       stack_pointer_(parameter_count() + 1) {  // 0-based index of TOS.
   for (int i = 0; i <= stack_pointer_; i++) {
-    elements_.Add(FrameElement::MemoryElement());
+    elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
   }
   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
     register_locations_[i] = kIllegalIndex;
@@ -193,25 +193,25 @@
 }
 
 
-void VirtualFrame::EmitPush(Register reg) {
+void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(reg);
 }
 
 
-void VirtualFrame::EmitPush(const Operand& operand) {
+void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(operand);
 }
 
 
-void VirtualFrame::EmitPush(Immediate immediate) {
+void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ push(immediate);
 }
@@ -219,7 +219,7 @@
 
 void VirtualFrame::EmitPush(Smi* smi_value) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(NumberInfo::kSmi));
   stack_pointer_++;
   __ Push(smi_value);
 }
@@ -227,15 +227,21 @@
 
 void VirtualFrame::EmitPush(Handle<Object> value) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  NumberInfo::Type info = NumberInfo::kUnknown;
+  if (value->IsSmi()) {
+    info = NumberInfo::kSmi;
+  } else if (value->IsHeapNumber()) {
+    info = NumberInfo::kHeapNumber;
+  }
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ Push(value);
 }
 
 
-void VirtualFrame::EmitPush(Heap::RootListIndex index) {
+void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo::Type info) {
   ASSERT(stack_pointer_ == element_count() - 1);
-  elements_.Add(FrameElement::MemoryElement());
+  elements_.Add(FrameElement::MemoryElement(info));
   stack_pointer_++;
   __ PushRoot(index);
 }
@@ -305,10 +311,14 @@
   // Set the new backing element.
   if (elements_[new_backing_index].is_synced()) {
     elements_[new_backing_index] =
-        FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED);
+        FrameElement::RegisterElement(backing_reg,
+                                      FrameElement::SYNCED,
+                                      original.number_info());
   } else {
     elements_[new_backing_index] =
-        FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED);
+        FrameElement::RegisterElement(backing_reg,
+                                      FrameElement::NOT_SYNCED,
+                                      original.number_info());
   }
   // Update the other copies.
   for (int i = new_backing_index + 1; i < element_count(); i++) {
@@ -339,7 +349,8 @@
       ASSERT(fresh.is_valid());
       FrameElement new_element =
           FrameElement::RegisterElement(fresh.reg(),
-                                        FrameElement::NOT_SYNCED);
+                                        FrameElement::NOT_SYNCED,
+                                        original.number_info());
       Use(fresh.reg(), element_count());
       elements_.Add(new_element);
       __ movq(fresh.reg(), Operand(rbp, fp_relative(index)));
@@ -480,10 +491,12 @@
   for (int i = 0; i < element_count(); i++) {
     FrameElement element = elements_[i];
 
+    // In all cases we have to reset the number type information
+    // to unknown for a mergable frame because of incoming back edges.
     if (element.is_constant() || element.is_copy()) {
       if (element.is_synced()) {
         // Just spill.
-        elements_[i] = FrameElement::MemoryElement();
+        elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
       } else {
         // Allocate to a register.
         FrameElement backing_element;  // Invalid if not a copy.
@@ -494,7 +507,8 @@
         ASSERT(fresh.is_valid());  // A register was spilled if all were in use.
         elements_[i] =
             FrameElement::RegisterElement(fresh.reg(),
-                                          FrameElement::NOT_SYNCED);
+                                          FrameElement::NOT_SYNCED,
+                                          NumberInfo::kUnknown);
         Use(fresh.reg(), i);
 
         // Emit a move.
@@ -523,6 +537,7 @@
       // The copy flag is not relied on before the end of this loop,
       // including when registers are spilled.
       elements_[i].clear_copied();
+      elements_[i].set_number_info(NumberInfo::kUnknown);
     }
   }
 }
@@ -728,6 +743,14 @@
   int index = element_count();
   ASSERT(element.is_valid());
 
+  // Get number type information of the result.
+  NumberInfo::Type info;
+  if (!element.is_copy()) {
+    info = element.number_info();
+  } else {
+    info = elements_[element.index()].number_info();
+  }
+
   bool pop_needed = (stack_pointer_ == index);
   if (pop_needed) {
     stack_pointer_--;
@@ -735,6 +758,7 @@
       Result temp = cgen()->allocator()->Allocate();
       ASSERT(temp.is_valid());
       __ pop(temp.reg());
+      temp.set_number_info(info);
       return temp;
     }
 
@@ -762,14 +786,16 @@
     ASSERT(temp.is_valid());
     Use(temp.reg(), index);
     FrameElement new_element =
-        FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED);
+        FrameElement::RegisterElement(temp.reg(),
+                                      FrameElement::SYNCED,
+                                      element.number_info());
     // Preserve the copy flag on the element.
     if (element.is_copied()) new_element.set_copied();
     elements_[index] = new_element;
     __ movq(temp.reg(), Operand(rbp, fp_relative(index)));
-    return Result(temp.reg());
+    return Result(temp.reg(), info);
   } else if (element.is_register()) {
-    return Result(element.reg());
+    return Result(element.reg(), info);
   } else {
     ASSERT(element.is_constant());
     return Result(element.handle());
@@ -969,6 +995,17 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+  PrepareForCall(0, 0);
+  ASSERT(cgen()->HasValidEntryRegisters());
+  __ DebugBreak();
+  Result result = cgen()->allocator()->Allocate(rax);
+  ASSERT(result.is_valid());
+}
+#endif
+
+
 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
   // Name and receiver are on the top of the frame.  The IC expects
   // name in rcx and receiver on the stack.  It does not drop the
@@ -996,7 +1033,6 @@
   // expects value in rax and key and receiver on the stack.  It does
   // not drop the key and receiver.
   Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
-  // TODO(1222589): Make the IC grab the values from the stack.
   Result value = Pop();
   PrepareForCall(2, 0);  // Two stack args, neither callee-dropped.
   value.ToRegister(rax);
@@ -1008,14 +1044,17 @@
 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
                                 int arg_count,
                                 int loop_nesting) {
-  // Arguments, receiver, and function name are on top of the frame.
-  // The IC expects them on the stack.  It does not drop the function
-  // name slot (but it does drop the rest).
+  // Function name, arguments, and receiver are found on top of the frame
+  // and dropped by the call.  The IC expects the name in rcx and the rest
+  // on the stack, and drops them all.
   InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop);
+  Result name = Pop();
   // Spill args, receiver, and function.  The call will drop args and
   // receiver.
-  PrepareForCall(arg_count + 2, arg_count + 1);
+  PrepareForCall(arg_count + 1, arg_count + 1);
+  name.ToRegister(rcx);
+  name.Unuse();
   return RawCallCodeObject(ic, mode);
 }
 
diff --git a/src/x64/virtual-frame-x64.h b/src/x64/virtual-frame-x64.h
index 8e3e40f..c9aa799 100644
--- a/src/x64/virtual-frame-x64.h
+++ b/src/x64/virtual-frame-x64.h
@@ -28,6 +28,7 @@
 #ifndef V8_X64_VIRTUAL_FRAME_X64_H_
 #define V8_X64_VIRTUAL_FRAME_X64_H_
 
+#include "number-info.h"
 #include "register-allocator.h"
 #include "scopes.h"
 
@@ -81,7 +82,8 @@
   MacroAssembler* masm() { return cgen()->masm(); }
 
   // Create a duplicate of an existing valid frame element.
-  FrameElement CopyElementAt(int index);
+  FrameElement CopyElementAt(int index,
+    NumberInfo::Type info = NumberInfo::kUninitialized);
 
   // The number of elements on the virtual frame.
   int element_count() { return elements_.length(); }
@@ -321,6 +323,10 @@
   Result CallRuntime(Runtime::Function* f, int arg_count);
   Result CallRuntime(Runtime::FunctionId id, int arg_count);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  void DebugBreak();
+#endif
+
   // Invoke builtin given the number of arguments it expects on (and
   // removes from) the stack.
   Result InvokeBuiltin(Builtins::JavaScript id,
@@ -343,9 +349,9 @@
   // of the frame.  Key and receiver are not dropped.
   Result CallKeyedStoreIC();
 
-  // Call call IC.  Arguments, receiver, and function name are found
-  // on top of the frame.  Function name slot is not dropped.  The
-  // argument count does not include the receiver.
+  // Call call IC.  Function name, arguments, and receiver are found on top
+  // of the frame and dropped by the call.
+  // The argument count does not include the receiver.
   Result CallCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);
 
   // Allocate and call JS function as constructor.  Arguments,
@@ -376,16 +382,20 @@
 
   // Push an element on top of the expression stack and emit a
   // corresponding push instruction.
-  void EmitPush(Register reg);
-  void EmitPush(const Operand& operand);
-  void EmitPush(Heap::RootListIndex index);
-  void EmitPush(Immediate immediate);
+  void EmitPush(Register reg,
+                NumberInfo::Type info = NumberInfo::kUnknown);
+  void EmitPush(const Operand& operand,
+                NumberInfo::Type info = NumberInfo::kUnknown);
+  void EmitPush(Heap::RootListIndex index,
+                NumberInfo::Type info = NumberInfo::kUnknown);
+  void EmitPush(Immediate immediate,
+                NumberInfo::Type info = NumberInfo::kUnknown);
   void EmitPush(Smi* value);
   // Uses kScratchRegister, emits appropriate relocation info.
   void EmitPush(Handle<Object> value);
 
   // Push an element on the virtual frame.
-  void Push(Register reg);
+  void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
   void Push(Handle<Object> value);
   void Push(Smi* value) { Push(Handle<Object>(value)); }
 
@@ -393,7 +403,7 @@
   // frame).
   void Push(Result* result) {
     if (result->is_register()) {
-      Push(result->reg());
+      Push(result->reg(), result->number_info());
     } else {
       ASSERT(result->is_constant());
       Push(result->handle());
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 0a392eb..db16bfc 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -394,6 +394,9 @@
     v8::HandleScope scope;
     LocalContext env;
     Local<String> source = String::New(two_byte_source);
+    // Trigger GCs so that the newly allocated string moves to old gen.
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(new TestResource(two_byte_source));
     CHECK(success);
     Local<Script> script = Script::Compile(source);
@@ -416,6 +419,9 @@
     v8::HandleScope scope;
     LocalContext env;
     Local<String> source = v8_str(c_source);
+    // Trigger GCs so that the newly allocated string moves to old gen.
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(
         new TestAsciiResource(i::StrDup(c_source)));
     CHECK(success);
@@ -432,6 +438,80 @@
 }
 
 
+TEST(MakingExternalStringConditions) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  // Free some space in the new space so that we can check freshness.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+
+  Local<String> small_string = String::New(AsciiToTwoByteString("small"));
+  // We should refuse to externalize newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  // Trigger GCs so that the newly allocated string moves to old gen.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  // Old space strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  small_string = String::New(AsciiToTwoByteString("small 2"));
+  // We should refuse externalizing newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  for (int i = 0; i < 100; i++) {
+    String::Value value(small_string);
+  }
+  // Frequently used strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  const int buf_size = 10 * 1024;
+  char* buf = i::NewArray<char>(buf_size);
+  memset(buf, 'a', buf_size);
+  buf[buf_size - 1] = '\0';
+  Local<String> large_string = String::New(AsciiToTwoByteString(buf));
+  i::DeleteArray(buf);
+  // Large strings should be immediately accepted.
+  CHECK(large_string->CanMakeExternal());
+}
+
+
+TEST(MakingExternalAsciiStringConditions) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  // Free some space in the new space so that we can check freshness.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+
+  Local<String> small_string = String::New("small");
+  // We should refuse to externalize newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  // Trigger GCs so that the newly allocated string moves to old gen.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  // Old space strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  small_string = String::New("small 2");
+  // We should refuse externalizing newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  for (int i = 0; i < 100; i++) {
+    String::Value value(small_string);
+  }
+  // Frequently used strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  const int buf_size = 10 * 1024;
+  char* buf = i::NewArray<char>(buf_size);
+  memset(buf, 'a', buf_size);
+  buf[buf_size - 1] = '\0';
+  Local<String> large_string = String::New(buf);
+  i::DeleteArray(buf);
+  // Large strings should be immediately accepted.
+  CHECK(large_string->CanMakeExternal());
+}
+
+
 THREADED_TEST(UsingExternalString) {
   {
     v8::HandleScope scope;
@@ -2448,6 +2528,33 @@
 }
 
 
+static v8::Handle<Value> SetXOnPrototypeGetter(Local<String> property,
+                                               const AccessorInfo& info) {
+  // Set x on the prototype object and do not handle the get request.
+  v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
+  v8::Handle<v8::Object>::Cast(proto)->Set(v8_str("x"), v8::Integer::New(23));
+  return v8::Handle<Value>();
+}
+
+
+// This is a regression test for http://crbug.com/20104. Map
+// transitions should not interfere with post interceptor lookup.
+THREADED_TEST(NamedInterceptorMapTransitionRead) {
+  v8::HandleScope scope;
+  Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New();
+  Local<v8::ObjectTemplate> instance_template
+      = function_template->InstanceTemplate();
+  instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
+  LocalContext context;
+  context->Global()->Set(v8_str("F"), function_template->GetFunction());
+  // Create an instance of F and introduce a map transition for x.
+  CompileRun("var o = new F(); o.x = 23;");
+  // Create an instance of F and invoke the getter. The result should be 23.
+  Local<Value> result = CompileRun("o = new F(); o.x");
+  CHECK_EQ(result->Int32Value(), 23);
+}
+
+
 static v8::Handle<Value> IndexedPropertyGetter(uint32_t index,
                                                const AccessorInfo& info) {
   ApiTestFuzzer::Fuzz();
@@ -2529,6 +2636,195 @@
 }
 
 
+THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  obj->TurnOnAccessCheck();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = obj[0];"
+      "    if (v != undefined) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 5) {"
+      "      %EnableAccessChecks(obj);"
+      "      expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 5) %DisableAccessChecks(obj);"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = obj[i];"
+      "    if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 50) {"
+      "       i = 'foobar';"
+      "       expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorGoingMegamorphic) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var original = obj;"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 50) {"
+      "       obj = {50: 'foobar'};"
+      "       expected = 'foobar';"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 50) obj = original;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorReceiverTurningSmi) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var original = obj;"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 5) {"
+      "       obj = 239;"
+      "       expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 5) obj = original;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorOnProto) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var o = {__proto__: obj};"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = o[i];"
+      "    if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
 THREADED_TEST(MultiContexts) {
   v8::HandleScope scope;
   v8::Handle<ObjectTemplate> templ = ObjectTemplate::New();
@@ -4844,6 +5140,84 @@
 }
 
 
+THREADED_TEST(SetPrototype) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
+  t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->SetHiddenPrototype(true);
+  t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1));
+  Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+  t2->SetHiddenPrototype(true);
+  t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2));
+  Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+  t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3));
+
+  Local<v8::Object> o0 = t0->GetFunction()->NewInstance();
+  Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
+  Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
+  Local<v8::Object> o3 = t3->GetFunction()->NewInstance();
+
+  // Setting the prototype on an object does not skip hidden prototypes.
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK(o0->SetPrototype(o1));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK(o1->SetPrototype(o2));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
+  CHECK(o2->SetPrototype(o3));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
+  CHECK_EQ(3, o0->Get(v8_str("u"))->Int32Value());
+
+  // Getting the prototype of o0 should get the first visible one
+  // which is o3.  Therefore, z should not be defined on the prototype
+  // object.
+  Local<Value> proto = o0->Get(v8_str("__proto__"));
+  CHECK(proto->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto), o3);
+
+  // However, Object::GetPrototype ignores hidden prototype.
+  Local<Value> proto0 = o0->GetPrototype();
+  CHECK(proto0->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto0), o1);
+
+  Local<Value> proto1 = o1->GetPrototype();
+  CHECK(proto1->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto1), o2);
+
+  Local<Value> proto2 = o2->GetPrototype();
+  CHECK(proto2->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto2), o3);
+}
+
+
+THREADED_TEST(SetPrototypeThrows) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+
+  Local<v8::Object> o0 = t->GetFunction()->NewInstance();
+  Local<v8::Object> o1 = t->GetFunction()->NewInstance();
+
+  CHECK(o0->SetPrototype(o1));
+  // If setting the prototype leads to the cycle, SetPrototype should
+  // return false and keep VM in sane state.
+  v8::TryCatch try_catch;
+  CHECK(!o1->SetPrototype(o0));
+  CHECK(!try_catch.HasCaught());
+  ASSERT(!i::Top::has_pending_exception());
+
+  CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
+}
+
+
 THREADED_TEST(GetterSetterExceptions) {
   v8::HandleScope handle_scope;
   LocalContext context;
@@ -5078,7 +5452,7 @@
 
 
 static v8::Handle<Value> call_as_function(const v8::Arguments& args) {
-  //ApiTestFuzzer::Fuzz();
+  ApiTestFuzzer::Fuzz();
   if (args.IsConstructCall()) {
     if (args[0]->IsInt32()) {
        return v8_num(-args[0]->Int32Value());
@@ -5891,6 +6265,294 @@
   CHECK_EQ(239 * 10, value->Int32Value());
 }
 
+static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
+                                                  const AccessorInfo& info) {
+  ApiTestFuzzer::Fuzz();
+  int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
+  ++(*call_count);
+  if ((*call_count) % 20 == 0) {
+    v8::internal::Heap::CollectAllGarbage(true);
+  }
+  return v8::Handle<Value>();
+}
+
+static v8::Handle<Value> FastApiCallback_TrivialSignature(
+    const v8::Arguments& args) {
+  ApiTestFuzzer::Fuzz();
+  CHECK_EQ(args.This(), args.Holder());
+  CHECK(args.Data()->Equals(v8_str("method_data")));
+  return v8::Integer::New(args[0]->Int32Value() + 1);
+}
+
+static v8::Handle<Value> FastApiCallback_SimpleSignature(
+    const v8::Arguments& args) {
+  ApiTestFuzzer::Fuzz();
+  CHECK_EQ(args.This()->GetPrototype(), args.Holder());
+  CHECK(args.Data()->Equals(v8_str("method_data")));
+  // Note, we're using HasRealNamedProperty instead of Has to avoid
+  // invoking the interceptor again.
+  CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo")));
+  return v8::Integer::New(args[0]->Int32Value() + 1);
+}
+
+// Helper to maximize the odds of object moving.
+static void GenerateSomeGarbage() {
+  CompileRun(
+      "var garbage;"
+      "for (var i = 0; i < 1000; i++) {"
+      "  garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];"
+      "}"
+      "garbage = undefined;");
+}
+
+THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+                                v8_str("method_data"),
+                                v8::Handle<v8::Signature>());
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = o.method(41);"
+      "}");
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(100, interceptor_call_count);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "}");
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(100, interceptor_call_count);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: function(x) { return x - 1 }};"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    o.method = function(x) { return x - 1 };"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::TryCatch try_catch;
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: receiver.method};"
+      "  }"
+      "}");
+  CHECK(try_catch.HasCaught());
+  CHECK_EQ(v8_str("TypeError: Illegal invocation"),
+           try_catch.Exception()->ToString());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(CallICFastApi_TrivialSignature) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+                                v8_str("method_data"),
+                                v8::Handle<v8::Signature>());
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = o.method(41);"
+      "}");
+
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+}
+
+THREADED_TEST(CallICFastApi_SimpleSignature) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "}");
+
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+}
+
+THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: function(x) { return x - 1 }};"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+}
+
 
 static int interceptor_call_count = 0;
 
@@ -8927,3 +9589,138 @@
 
   other_context.Dispose();
 }
+
+
+THREADED_TEST(ScriptOrigin) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  v8::Handle<v8::String> script = v8::String::New(
+      "function f() {}\n\nfunction g() {}");
+  v8::Script::Compile(script, &origin)->Run();
+  v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("f")));
+  v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("g")));
+
+  v8::ScriptOrigin script_origin_f = f->GetScriptOrigin();
+  CHECK_EQ("test", *v8::String::AsciiValue(script_origin_f.ResourceName()));
+  CHECK_EQ(0, script_origin_f.ResourceLineOffset()->Int32Value());
+
+  v8::ScriptOrigin script_origin_g = g->GetScriptOrigin();
+  CHECK_EQ("test", *v8::String::AsciiValue(script_origin_g.ResourceName()));
+  CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value());
+}
+
+
+THREADED_TEST(ScriptLineNumber) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  v8::Handle<v8::String> script = v8::String::New(
+      "function f() {}\n\nfunction g() {}");
+  v8::Script::Compile(script, &origin)->Run();
+  v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("f")));
+  v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("g")));
+  CHECK_EQ(0, f->GetScriptLineNumber());
+  CHECK_EQ(2, g->GetScriptLineNumber());
+}
+
+
+static v8::Handle<Value> GetterWhichReturns42(Local<String> name,
+                                              const AccessorInfo& info) {
+  return v8_num(42);
+}
+
+
+static void SetterWhichSetsYOnThisTo23(Local<String> name,
+                                       Local<Value> value,
+                                       const AccessorInfo& info) {
+  info.This()->Set(v8_str("y"), v8_num(23));
+}
+
+
+THREADED_TEST(SetterOnConstructorPrototype) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetAccessor(v8_str("x"),
+                     GetterWhichReturns42,
+                     SetterWhichSetsYOnThisTo23);
+  LocalContext context;
+  context->Global()->Set(v8_str("P"), templ->NewInstance());
+  CompileRun("function C1() {"
+             "  this.x = 23;"
+             "};"
+             "C1.prototype = P;"
+             "function C2() {"
+             "  this.x = 23"
+             "};"
+             "C2.prototype = { };"
+             "C2.prototype.__proto__ = P;");
+
+  v8::Local<v8::Script> script;
+  script = v8::Script::Compile(v8_str("new C1();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value());
+  }
+
+  script = v8::Script::Compile(v8_str("new C2();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(42, c2->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(23, c2->Get(v8_str("y"))->Int32Value());
+  }
+}
+
+
+static v8::Handle<Value> NamedPropertyGetterWhichReturns42(
+    Local<String> name, const AccessorInfo& info) {
+  return v8_num(42);
+}
+
+
+static v8::Handle<Value> NamedPropertySetterWhichSetsYOnThisTo23(
+    Local<String> name, Local<Value> value, const AccessorInfo& info) {
+  if (name->Equals(v8_str("x"))) {
+    info.This()->Set(v8_str("y"), v8_num(23));
+  }
+  return v8::Handle<Value>();
+}
+
+
+THREADED_TEST(InterceptorOnConstructorPrototype) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
+                                 NamedPropertySetterWhichSetsYOnThisTo23);
+  LocalContext context;
+  context->Global()->Set(v8_str("P"), templ->NewInstance());
+  CompileRun("function C1() {"
+             "  this.x = 23;"
+             "};"
+             "C1.prototype = P;"
+             "function C2() {"
+             "  this.x = 23"
+             "};"
+             "C2.prototype = { };"
+             "C2.prototype.__proto__ = P;");
+
+  v8::Local<v8::Script> script;
+  script = v8::Script::Compile(v8_str("new C1();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value());
+  }
+
+  script = v8::Script::Compile(v8_str("new C2();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(23, c2->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(42, c2->Get(v8_str("y"))->Int32Value());
+  }
+}
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
new file mode 100644
index 0000000..ab011a7
--- /dev/null
+++ b/test/cctest/test-assembler-mips.cc
@@ -0,0 +1,257 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "disassembler.h"
+#include "factory.h"
+#include "macro-assembler.h"
+#include "mips/macro-assembler-mips.h"
+#include "mips/simulator-mips.h"
+
+#include "cctest.h"
+
+using namespace v8::internal;
+
+
+// Define these function prototypes to match JSEntryFunction in execution.cc.
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
+typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+
+
+static v8::Persistent<v8::Context> env;
+
+
+// The test framework does not accept flags on the command line, so we set them.
+static void InitializeVM() {
+  // Disable compilation of natives by specifying an empty natives file.
+  FLAG_natives_file = "";
+
+  // Enable generation of comments.
+  FLAG_debug_code = true;
+
+  if (env.IsEmpty()) {
+    env = v8::Context::New();
+  }
+}
+
+
+#define __ assm.
+
+TEST(MIPS0) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+
+  // Addition.
+  __ addu(v0, a0, a1);
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(0xabc, res);
+}
+
+
+TEST(MIPS1) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+  Label L, C;
+
+  __ mov(a1, a0);
+  __ li(v0, 0);
+  __ b(&C);
+  __ nop();
+
+  __ bind(&L);
+  __ add(v0, v0, a1);
+  __ addiu(a1, a1, -1);
+
+  __ bind(&C);
+  __ xori(v1, a1, 0);
+  __ Branch(ne, &L, v1, Operand(0));
+  __ nop();
+
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(1275, res);
+}
+
+
+TEST(MIPS2) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+
+  Label exit, error;
+
+  // ----- Test all instructions.
+
+  // Test lui, ori, and addiu, used in the li pseudo-instruction.
+  // This way we can then safely load registers with chosen values.
+
+  __ ori(t0, zero_reg, 0);
+  __ lui(t0, 0x1234);
+  __ ori(t0, t0, 0);
+  __ ori(t0, t0, 0x0f0f);
+  __ ori(t0, t0, 0xf0f0);
+  __ addiu(t1, t0, 1);
+  __ addiu(t2, t1, -0x10);
+
+  // Load values in temporary registers.
+  __ li(t0, 0x00000004);
+  __ li(t1, 0x00001234);
+  __ li(t2, 0x12345678);
+  __ li(t3, 0x7fffffff);
+  __ li(t4, 0xfffffffc);
+  __ li(t5, 0xffffedcc);
+  __ li(t6, 0xedcba988);
+  __ li(t7, 0x80000000);
+
+  // SPECIAL class.
+  __ srl(v0, t2, 8);    // 0x00123456
+  __ sll(v0, v0, 11);   // 0x91a2b000
+  __ sra(v0, v0, 3);    // 0xf2345600
+  __ srav(v0, v0, t0);  // 0xff234560
+  __ sllv(v0, v0, t0);  // 0xf2345600
+  __ srlv(v0, v0, t0);  // 0x0f234560
+  __ Branch(ne, &error, v0, Operand(0x0f234560));
+  __ nop();
+
+  __ add(v0, t0, t1);   // 0x00001238
+  __ sub(v0, v0, t0);   // 0x00001234
+  __ Branch(ne, &error, v0, Operand(0x00001234));
+  __ nop();
+  __ addu(v1, t3, t0);
+  __ Branch(ne, &error, v1, Operand(0x80000003));
+  __ nop();
+  __ subu(v1, t7, t0);  // 0x7ffffffc
+  __ Branch(ne, &error, v1, Operand(0x7ffffffc));
+  __ nop();
+
+  __ and_(v0, t1, t2);  // 0x00001230
+  __ or_(v0, v0, t1);   // 0x00001234
+  __ xor_(v0, v0, t2);  // 0x1234444c
+  __ nor(v0, v0, t2);   // 0xedcba987
+  __ Branch(ne, &error, v0, Operand(0xedcba983));
+  __ nop();
+
+  __ slt(v0, t7, t3);
+  __ Branch(ne, &error, v0, Operand(0x1));
+  __ nop();
+  __ sltu(v0, t7, t3);
+  __ Branch(ne, &error, v0, Operand(0x0));
+  __ nop();
+  // End of SPECIAL class.
+
+  __ addi(v0, zero_reg, 0x7421);  // 0x00007421
+  __ addi(v0, v0, -0x1);  // 0x00007420
+  __ addiu(v0, v0, -0x20);  // 0x00007400
+  __ Branch(ne, &error, v0, Operand(0x00007400));
+  __ nop();
+  __ addiu(v1, t3, 0x1);  // 0x80000000
+  __ Branch(ne, &error, v1, Operand(0x80000000));
+  __ nop();
+
+  __ slti(v0, t1, 0x00002000);  // 0x1
+  __ slti(v0, v0, 0xffff8000);  // 0x0
+  __ Branch(ne, &error, v0, Operand(0x0));
+  __ nop();
+  __ sltiu(v0, t1, 0x00002000);  // 0x1
+  __ sltiu(v0, v0, 0x00008000);  // 0x1
+  __ Branch(ne, &error, v0, Operand(0x1));
+  __ nop();
+
+  __ andi(v0, t1, 0xf0f0);  // 0x00001030
+  __ ori(v0, v0, 0x8a00);  // 0x00009a30
+  __ xori(v0, v0, 0x83cc);  // 0x000019fc
+  __ Branch(ne, &error, v0, Operand(0x000019fc));
+  __ nop();
+  __ lui(v1, 0x8123);  // 0x81230000
+  __ Branch(ne, &error, v1, Operand(0x81230000));
+  __ nop();
+
+  // Everything was correctly executed. Load the expected result.
+  __ li(v0, 0x31415926);
+  __ b(&exit);
+  __ nop();
+
+  __ bind(&error);
+  // Got an error. Return a wrong result.
+
+  __ bind(&exit);
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(0x31415926, res);
+}
+
+#undef __
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index b5f12b9..471753c 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -120,6 +120,7 @@
                                                      0,
                                                      NULL,
                                                      NULL,
+                                                     Handle<String>::null(),
                                                      NOT_NATIVES_CODE);
   return Factory::NewFunctionFromBoilerplate(boilerplate,
                                              Top::global_context());
@@ -322,3 +323,27 @@
   CHECK_EQ(-1, GetScriptLineNumber(script, 100));
   CHECK_EQ(-1, GetScriptLineNumber(script, -1));
 }
+
+
+TEST(GetScriptLineNumber) {
+  LocalContext env;
+  v8::HandleScope scope;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  const char function_f[] = "function f() {}";
+  const int max_rows = 1000;
+  const int buffer_size = max_rows + sizeof(function_f);
+  ScopedVector<char> buffer(buffer_size);
+  memset(buffer.start(), '\n', buffer_size - 1);
+  buffer[buffer_size - 1] = '\0';
+
+  for (int i = 0; i < max_rows; ++i) {
+    if (i > 0)
+      buffer[i - 1] = '\n';
+    memcpy(&buffer[i], function_f, sizeof(function_f) - 1);
+    v8::Handle<v8::String> script_body = v8::String::New(buffer.start());
+    v8::Script::Compile(script_body, &origin)->Run();
+    v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+        env->Global()->Get(v8::String::New("f")));
+    CHECK_EQ(i, f->GetScriptLineNumber());
+  }
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 92e18e0..b7c39b2 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -550,6 +550,15 @@
 v8::Local<v8::Function> frame_script_data;
 
 
+// Source for The JavaScript function which picks out the script data from
+// AfterCompile event
+const char* compiled_script_data_source =
+    "function compiled_script_data(event_data) {"
+    "  return event_data.script().data();"
+    "}";
+v8::Local<v8::Function> compiled_script_data;
+
+
 // Source for The JavaScript function which returns the number of frames.
 static const char* frame_count_source =
     "function frame_count(exec_state) {"
@@ -647,6 +656,19 @@
         script_data->WriteAscii(last_script_data_hit);
       }
     }
+  } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) {
+    const int argc = 1;
+    v8::Handle<v8::Value> argv[argc] = { event_data };
+    v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state,
+                                                              argc, argv);
+    if (result->IsUndefined()) {
+      last_script_data_hit[0] = '\0';
+    } else {
+      result = result->ToString();
+      CHECK(result->IsString());
+      v8::Handle<v8::String> script_data(result->ToString());
+      script_data->WriteAscii(last_script_data_hit);
+    }
   }
 }
 
@@ -3884,6 +3906,11 @@
 }
 
 
+static int StringToInt(const char* s) {
+  return atoi(s);  // NOLINT
+}
+
+
 // We match parts of the message to get evaluate result int value.
 int GetEvaluateIntResult(char *message) {
   const char* value = "\"value\":";
@@ -3892,7 +3919,7 @@
     return -1;
   }
   int res = -1;
-  res = atoi(pos + strlen(value));
+  res = StringToInt(pos + strlen(value));
   return res;
 }
 
@@ -3905,7 +3932,7 @@
     return -1;
   }
   int res = -1;
-  res = atoi(pos + strlen(breakpoints));
+  res = StringToInt(pos + strlen(breakpoints));
   return res;
 }
 
@@ -3918,11 +3945,7 @@
     return -1;
   }
   pos += strlen(prefix);
-  char* pos_end = pos;
-  int res = static_cast<int>(strtol(pos, &pos_end, 10));
-  if (pos_end == pos) {
-    return -1;
-  }
+  int res = StringToInt(pos);
   return res;
 }
 
@@ -5231,6 +5254,9 @@
   frame_script_data = CompileFunction(&env,
                                       frame_script_data_source,
                                       "frame_script_data");
+  compiled_script_data = CompileFunction(&env,
+                                         compiled_script_data_source,
+                                         "compiled_script_data");
 
   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
                                    v8::Undefined());
@@ -5277,6 +5303,16 @@
   CHECK_EQ(3, break_point_hit_count);
   CHECK_EQ("new name", last_script_name_hit);
   CHECK_EQ("abc 123", last_script_data_hit);
+
+  v8::Handle<v8::Script> script3 =
+      v8::Script::Compile(script, &origin2, NULL,
+                          v8::String::New("in compile"));
+  CHECK_EQ("in compile", last_script_data_hit);
+  script3->Run();
+  f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
+  f->Call(env->Global(), 0, NULL);
+  CHECK_EQ(4, break_point_hit_count);
+  CHECK_EQ("in compile", last_script_data_hit);
 }
 
 
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index eca2c2b..9853af3 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -170,21 +170,110 @@
 #endif  // __linux__
 
 
-static int CheckThatProfilerWorks(int log_pos) {
-  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU);
+namespace {
+
+class ScopedLoggerInitializer {
+ public:
+  explicit ScopedLoggerInitializer(bool log, bool prof_lazy)
+      : saved_log_(i::FLAG_log),
+        saved_prof_lazy_(i::FLAG_prof_lazy),
+        saved_prof_(i::FLAG_prof),
+        saved_prof_auto_(i::FLAG_prof_auto),
+        trick_to_run_init_flags_(init_flags_(log, prof_lazy)),
+        need_to_set_up_logger_(i::V8::IsRunning()),
+        scope_(),
+        env_(v8::Context::New()) {
+    if (need_to_set_up_logger_) Logger::Setup();
+    env_->Enter();
+  }
+
+  ~ScopedLoggerInitializer() {
+    env_->Exit();
+    Logger::TearDown();
+    i::FLAG_prof_lazy = saved_prof_lazy_;
+    i::FLAG_prof = saved_prof_;
+    i::FLAG_prof_auto = saved_prof_auto_;
+    i::FLAG_log = saved_log_;
+  }
+
+  v8::Handle<v8::Context>& env() { return env_; }
+
+ private:
+  static bool init_flags_(bool log, bool prof_lazy) {
+    i::FLAG_log = log;
+    i::FLAG_prof = true;
+    i::FLAG_prof_lazy = prof_lazy;
+    i::FLAG_prof_auto = false;
+    i::FLAG_logfile = "*";
+    return prof_lazy;
+  }
+
+  const bool saved_log_;
+  const bool saved_prof_lazy_;
+  const bool saved_prof_;
+  const bool saved_prof_auto_;
+  const bool trick_to_run_init_flags_;
+  const bool need_to_set_up_logger_;
+  v8::HandleScope scope_;
+  v8::Handle<v8::Context> env_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer);
+};
+
+
+class LogBufferMatcher {
+ public:
+  LogBufferMatcher() {
+    // Skip all initially logged stuff.
+    log_pos_ = GetLogLines(0, &buffer_);
+  }
+
+  int log_pos() { return log_pos_; }
+
+  int GetNextChunk() {
+    int chunk_size = GetLogLines(log_pos_, &buffer_);
+    CHECK_GT(buffer_.length(), chunk_size);
+    buffer_[chunk_size] = '\0';
+    log_pos_ += chunk_size;
+    return chunk_size;
+  }
+
+  const char* Find(const char* substr) {
+    return strstr(buffer_.start(), substr);
+  }
+
+  const char* Find(const i::Vector<char>& substr) {
+    return Find(substr.start());
+  }
+
+  bool IsInSequence(const char* s1, const char* s2) {
+    const char* s1_pos = Find(s1);
+    const char* s2_pos = Find(s2);
+    CHECK_NE(NULL, s1_pos);
+    CHECK_NE(NULL, s2_pos);
+    return s1_pos < s2_pos;
+  }
+
+  void PrintBuffer() {
+    puts(buffer_.start());
+  }
+
+ private:
+  EmbeddedVector<char, 102400> buffer_;
+  int log_pos_;
+};
+
+}  // namespace
+
+
+static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
   CHECK(LoggerTestHelper::IsSamplerActive());
 
   // Verify that the current map of compiled functions has been logged.
-  EmbeddedVector<char, 102400> buffer;
-  int map_log_size = GetLogLines(log_pos, &buffer);
-  printf("map_log_size: %d\n", map_log_size);
-  CHECK_GT(map_log_size, 0);
-  CHECK_GT(buffer.length(), map_log_size);
-  log_pos += map_log_size;
-  // Check buffer contents.
-  buffer[map_log_size] = '\0';
+  CHECK_GT(matcher->GetNextChunk(), 0);
   const char* code_creation = "\ncode-creation,";  // eq. to /^code-creation,/
-  CHECK_NE(NULL, strstr(buffer.start(), code_creation));
+  CHECK_NE(NULL, matcher->Find(code_creation));
 
 #ifdef __linux__
   // Intercept SIGPROF handler to make sure that the test process
@@ -204,7 +293,7 @@
   i::OS::SNPrintF(script_src,
                   "function f%d(x) { return %d * x; }"
                   "for (var i = 0; i < 10000; ++i) { f%d(i); }",
-                  log_pos, log_pos, log_pos);
+                  matcher->log_pos(), matcher->log_pos(), matcher->log_pos());
   // Run code for 200 msecs to get some ticks.
   const double end_time = i::OS::TimeCurrentMillis() + 200;
   while (i::OS::TimeCurrentMillis() < end_time) {
@@ -213,7 +302,7 @@
     i::OS::Sleep(1);
   }
 
-  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU);
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
   CHECK(!LoggerTestHelper::IsSamplerActive());
 
   // Wait 50 msecs to allow Profiler thread to process the last
@@ -221,68 +310,39 @@
   i::OS::Sleep(50);
 
   // Now we must have compiler and tick records.
-  int log_size = GetLogLines(log_pos, &buffer);
-  printf("log_size: %d\n", log_size);
-  CHECK_GT(log_size, 0);
-  CHECK_GT(buffer.length(), log_size);
-  log_pos += log_size;
-  // Check buffer contents.
-  buffer[log_size] = '\0';
-  printf("%s", buffer.start());
+  CHECK_GT(matcher->GetNextChunk(), 0);
+  matcher->PrintBuffer();
+  CHECK_NE(NULL, matcher->Find(code_creation));
   const char* tick = "\ntick,";
-  CHECK_NE(NULL, strstr(buffer.start(), code_creation));
-  const bool ticks_found = strstr(buffer.start(), tick) != NULL;
+  const bool ticks_found = matcher->Find(tick) != NULL;
   CHECK_EQ(was_sigprof_received, ticks_found);
-
-  return log_pos;
 }
 
 
 TEST(ProfLazyMode) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = true;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
+  ScopedLoggerInitializer initialize_logger(false, true);
 
   // No sampling should happen prior to resuming profiler.
   CHECK(!LoggerTestHelper::IsSamplerActive());
 
-  EmbeddedVector<char, 102400> buffer;
+  LogBufferMatcher matcher;
   // Nothing must be logged until profiling is resumed.
-  int log_pos = GetLogLines(0, &buffer);
-  CHECK_EQ(0, log_pos);
+  CHECK_EQ(0, matcher.log_pos());
 
   CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
 
   // Nothing must be logged while profiling is suspended.
-  CHECK_EQ(0, GetLogLines(log_pos, &buffer));
+  CHECK_EQ(0, matcher.GetNextChunk());
 
-  log_pos = CheckThatProfilerWorks(log_pos);
+  CheckThatProfilerWorks(&matcher);
 
   CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
 
   // No new data beyond last retrieved position.
-  CHECK_EQ(0, GetLogLines(log_pos, &buffer));
+  CHECK_EQ(0, matcher.GetNextChunk());
 
   // Check that profiling can be resumed again.
-  CheckThatProfilerWorks(log_pos);
-
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
+  CheckThatProfilerWorks(&matcher);
 }
 
 
@@ -480,25 +540,8 @@
 }
 
 TEST(LogCallbacks) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = false;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
-
-  // Skip all initially logged stuff.
-  EmbeddedVector<char, 102400> buffer;
-  int log_pos = GetLogLines(0, &buffer);
+  ScopedLoggerInitializer initialize_logger(false, false);
+  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
@@ -511,16 +554,14 @@
                                        signature),
              static_cast<v8::PropertyAttribute>(v8::DontDelete));
 
-  env->Global()->Set(v8_str("Obj"), obj->GetFunction());
+  initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
   CompileAndRunScript("Obj.prototype.method1.toString();");
 
   i::Logger::LogCompiledFunctions();
-  log_pos = GetLogLines(log_pos, &buffer);
-  CHECK_GT(log_pos, 0);
-  buffer[log_pos] = 0;
+  CHECK_GT(matcher.GetNextChunk(), 0);
 
   const char* callback_rec = "code-creation,Callback,";
-  char* pos = strstr(buffer.start(), callback_rec);
+  char* pos = const_cast<char*>(matcher.Find(callback_rec));
   CHECK_NE(NULL, pos);
   pos += strlen(callback_rec);
   EmbeddedVector<char, 100> ref_data;
@@ -530,12 +571,6 @@
   CHECK_EQ(ref_data.start(), pos);
 
   obj.Dispose();
-
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
 }
 
 
@@ -555,25 +590,8 @@
 }
 
 TEST(LogAccessorCallbacks) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = false;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
-
-  // Skip all initially logged stuff.
-  EmbeddedVector<char, 102400> buffer;
-  int log_pos = GetLogLines(0, &buffer);
+  ScopedLoggerInitializer initialize_logger(false, false);
+  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
@@ -583,34 +601,112 @@
   inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
 
   i::Logger::LogAccessorCallbacks();
-  log_pos = GetLogLines(log_pos, &buffer);
-  CHECK_GT(log_pos, 0);
-  buffer[log_pos] = 0;
-  printf("%s", buffer.start());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  matcher.PrintBuffer();
 
   EmbeddedVector<char, 100> prop1_getter_record;
   i::OS::SNPrintF(prop1_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
                   Prop1Getter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop1_getter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop1_getter_record));
   EmbeddedVector<char, 100> prop1_setter_record;
   i::OS::SNPrintF(prop1_setter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
                   Prop1Setter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop1_setter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop1_setter_record));
   EmbeddedVector<char, 100> prop2_getter_record;
   i::OS::SNPrintF(prop2_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
                   Prop2Getter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop2_getter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop2_getter_record));
 
   obj.Dispose();
+}
 
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
+
+TEST(LogTags) {
+  ScopedLoggerInitializer initialize_logger(true, false);
+  LogBufferMatcher matcher;
+
+  const char* open_tag = "open-tag,";
+  const char* close_tag = "close-tag,";
+
+  // Check compatibility with the old style behavior.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_EQ(NULL, matcher.Find(open_tag));
+  CHECK_EQ(NULL, matcher.Find(close_tag));
+
+  const char* open_tag1 = "open-tag,1\n";
+  const char* close_tag1 = "close-tag,1\n";
+
+  // Check non-nested tag case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  CHECK(matcher.IsInSequence(open_tag1, close_tag1));
+
+  const char* open_tag2 = "open-tag,2\n";
+  const char* close_tag2 = "close-tag,2\n";
+
+  // Check nested tags case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  // open_tag1 < open_tag2 < close_tag2 < close_tag1
+  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
+  CHECK(matcher.IsInSequence(open_tag2, close_tag2));
+  CHECK(matcher.IsInSequence(close_tag2, close_tag1));
+
+  // Check overlapped tags case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  // open_tag1 < open_tag2 < close_tag1 < close_tag2
+  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
+  CHECK(matcher.IsInSequence(open_tag2, close_tag1));
+  CHECK(matcher.IsInSequence(close_tag1, close_tag2));
+
+  const char* open_tag3 = "open-tag,3\n";
+  const char* close_tag3 = "close-tag,3\n";
+
+  // Check pausing overflow case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  // Must be no tags, because logging must be disabled.
+  CHECK_EQ(NULL, matcher.Find(open_tag3));
+  CHECK_EQ(NULL, matcher.Find(close_tag3));
 }
 
 
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 18f6988..5335e9b 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -131,7 +131,7 @@
       ExternalReference::address_of_real_stack_limit();
   CHECK_EQ(make_code(UNCLASSIFIED, 5),
            encoder.Encode(real_stack_limit_address.address()));
-  CHECK_EQ(make_code(UNCLASSIFIED, 11),
+  CHECK_EQ(make_code(UNCLASSIFIED, 12),
            encoder.Encode(ExternalReference::debug_break().address()));
   CHECK_EQ(make_code(UNCLASSIFIED, 7),
            encoder.Encode(ExternalReference::new_space_start().address()));
@@ -165,7 +165,7 @@
   CHECK_EQ(ExternalReference::address_of_real_stack_limit().address(),
            decoder.Decode(make_code(UNCLASSIFIED, 5)));
   CHECK_EQ(ExternalReference::debug_break().address(),
-           decoder.Decode(make_code(UNCLASSIFIED, 11)));
+           decoder.Decode(make_code(UNCLASSIFIED, 12)));
   CHECK_EQ(ExternalReference::new_space_start().address(),
            decoder.Decode(make_code(UNCLASSIFIED, 7)));
 }
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index 1d65e68..24b3c90 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -35,111 +35,6 @@
 using namespace v8::internal;
 
 
-enum Mode {
-  forward,
-  backward_unsigned
-};
-
-
-static v8::internal::byte* Write(v8::internal::byte* p, Mode m, int x) {
-  v8::internal::byte* q = NULL;
-  switch (m) {
-    case forward:
-      q = EncodeInt(p, x);
-      CHECK(q <= p + sizeof(x) + 1);
-      break;
-    case backward_unsigned:
-      q = EncodeUnsignedIntBackward(p, x);
-      CHECK(q >= p - sizeof(x) - 1);
-      break;
-  }
-  return q;
-}
-
-
-static v8::internal::byte* Read(v8::internal::byte* p, Mode m, int x) {
-  v8::internal::byte* q = NULL;
-  int y;
-  switch (m) {
-    case forward:
-      q = DecodeInt(p, &y);
-      CHECK(q <= p + sizeof(y) + 1);
-      break;
-    case backward_unsigned: {
-      unsigned int uy;
-      q = DecodeUnsignedIntBackward(p, &uy);
-      y = uy;
-      CHECK(q >= p - sizeof(uy) - 1);
-      break;
-    }
-  }
-  CHECK(y == x);
-  return q;
-}
-
-
-static v8::internal::byte* WriteMany(v8::internal::byte* p, Mode m, int x) {
-  p = Write(p, m, x - 7);
-  p = Write(p, m, x - 1);
-  p = Write(p, m, x);
-  p = Write(p, m, x + 1);
-  p = Write(p, m, x + 2);
-  p = Write(p, m, -x - 5);
-  p = Write(p, m, -x - 1);
-  p = Write(p, m, -x);
-  p = Write(p, m, -x + 1);
-  p = Write(p, m, -x + 3);
-
-  return p;
-}
-
-
-static v8::internal::byte* ReadMany(v8::internal::byte* p, Mode m, int x) {
-  p = Read(p, m, x - 7);
-  p = Read(p, m, x - 1);
-  p = Read(p, m, x);
-  p = Read(p, m, x + 1);
-  p = Read(p, m, x + 2);
-  p = Read(p, m, -x - 5);
-  p = Read(p, m, -x - 1);
-  p = Read(p, m, -x);
-  p = Read(p, m, -x + 1);
-  p = Read(p, m, -x + 3);
-
-  return p;
-}
-
-
-void ProcessValues(int* values, int n, Mode m) {
-  v8::internal::byte buf[4 * KB];  // make this big enough
-  v8::internal::byte* p0 = (m == forward ? buf : buf + ARRAY_SIZE(buf));
-
-  v8::internal::byte* p = p0;
-  for (int i = 0; i < n; i++) {
-    p = WriteMany(p, m, values[i]);
-  }
-
-  v8::internal::byte* q = p0;
-  for (int i = 0; i < n; i++) {
-    q = ReadMany(q, m, values[i]);
-  }
-
-  CHECK(p == q);
-}
-
-
-TEST(Utils0) {
-  int values[] = {
-    0, 1, 10, 16, 32, 64, 128, 256, 512, 1024, 1234, 5731,
-    10000, 100000, 1000000, 10000000, 100000000, 1000000000
-  };
-  const int n = ARRAY_SIZE(values);
-
-  ProcessValues(values, n, forward);
-  ProcessValues(values, n, backward_unsigned);
-}
-
-
 TEST(Utils1) {
   CHECK_EQ(-1000000, FastD2I(-1000000.0));
   CHECK_EQ(-1, FastD2I(-1.0));
diff --git a/test/mjsunit/array-functions-prototype-misc.js b/test/mjsunit/array-functions-prototype-misc.js
new file mode 100644
index 0000000..0543c32
--- /dev/null
+++ b/test/mjsunit/array-functions-prototype-misc.js
@@ -0,0 +1,314 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test splice, shift, unshift, slice and join on small
+ * and large arrays.  Some of these methods are specified such that they
+ * should work on other objects too, so we test that too.
+ */
+
+var LARGE = 40000000;
+var VERYLARGE = 4000000000;
+
+// Nicer for firefox 1.5.  Unless you uncomment the following two lines,
+// smjs will appear to hang on this file.
+//var LARGE = 40000;
+//var VERYLARGE = 40000;
+
+var fourhundredth = LARGE/400;
+
+function PseudoArray() {
+};
+
+for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
+  var poses = [0, 140, 20000, VERYLARGE];
+  var the_prototype;
+  var new_function;
+  var push_function;
+  var concat_function;
+  var slice_function;
+  var splice_function;
+  var splice_function_2;
+  var unshift_function;
+  var unshift_function_2;
+  var shift_function;
+  if (use_real_arrays) {
+    new_function = function(length) {
+      return new Array(length);
+    };
+    the_prototype = Array.prototype;
+    push_function = function(array, elt) {
+      return array.push(elt);
+    };
+    concat_function = function(array, other) {
+      return array.concat(other);
+    };
+    slice_function = function(array, start, len) {
+      return array.slice(start, len);
+    };
+    splice_function = function(array, start, len) {
+      return array.splice(start, len);
+    };
+    splice_function_2 = function(array, start, len, elt) {
+      return array.splice(start, len, elt);
+    };
+    unshift_function = function(array, elt) {
+      return array.unshift(elt);
+    };
+    unshift_function_2 = function(array, elt1, elt2) {
+      return array.unshift(elt1, elt2);
+    };
+    shift_function = function(array) {
+      return array.shift();
+    };
+  } else {
+    // Don't run largest size on non-arrays or we'll be here for ever.
+    poses.pop();
+    new_function = function(length) {
+      var obj = new PseudoArray();
+      obj.length = length;
+      return obj;
+    };
+    the_prototype = PseudoArray.prototype;
+    push_function = function(array, elt) {
+      array[array.length] = elt;
+      array.length++;
+    };
+    concat_function = function(array, other) {
+      return Array.prototype.concat.call(array, other);
+    };
+    slice_function = function(array, start, len) {
+      return Array.prototype.slice.call(array, start, len);
+    };
+    splice_function = function(array, start, len) {
+      return Array.prototype.splice.call(array, start, len);
+    };
+    splice_function_2 = function(array, start, len, elt) {
+      return Array.prototype.splice.call(array, start, len, elt);
+    };
+    unshift_function = function(array, elt) {
+      return Array.prototype.unshift.call(array, elt);
+    };
+    unshift_function_2 = function(array, elt1, elt2) {
+      return Array.prototype.unshift.call(array, elt1, elt2);
+    };
+    shift_function = function(array) {
+      return Array.prototype.shift.call(array);
+    };
+  }
+
+  for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
+    var pos = poses[pos_pos];
+    if (pos > 100) {
+      var a = new_function(pos);
+      assertEquals(pos, a.length);
+      push_function(a, 'foo');
+      assertEquals(pos + 1, a.length);
+      var b = ['bar'];
+      // Delete a huge number of holes.
+      var c = splice_function(a, 10, pos - 20);
+      assertEquals(pos - 20, c.length);
+      assertEquals(21, a.length);
+    }
+
+    // Add a numeric property to the prototype of the array class.  This
+    // allows us to test some borderline stuff relative to the standard.
+    the_prototype["" + (pos + 1)] = 'baz';
+
+    if (use_real_arrays) {
+      // It seems quite clear from ECMAScript spec 15.4.4.5.  Just call Get on
+      // every integer in the range.
+      // IE, Safari get this right.
+      // FF, Opera get this wrong.
+      var a = ['zero', ,'two'];
+      if (pos == 0) {
+        assertEquals("zero,baz,two", a.join(","));
+      }
+
+      // Concat only applies to real arrays, unlike most of the other methods.
+      var a = new_function(pos);
+      push_function(a, "con");
+      assertEquals("con", a[pos]);
+      assertEquals(pos + 1, a.length);
+      var b = new_function(0);
+      push_function(b, "cat");
+      assertEquals("cat", b[0]);
+      var ab = concat_function(a, b);
+      assertEquals("con", ab[pos]);
+      assertEquals(pos + 2, ab.length);
+      assertEquals("cat", ab[pos + 1]);
+      var ba = concat_function(b, a);
+      assertEquals("con", ba[pos + 1]);
+      assertEquals(pos + 2, ba.length);
+      assertEquals("cat", ba[0]);
+
+      // Join with '' as separator.
+      var join = a.join('');
+      assertEquals("con", join);
+      join = b.join('');
+      assertEquals("cat", join);
+      join = ab.join('');
+      assertEquals("concat", join);
+      join = ba.join('');
+      assertEquals("catcon", join);
+
+      var sparse = [];
+      sparse[pos + 1000] = 'is ';
+      sparse[pos + 271828] = 'time ';
+      sparse[pos + 31415] = 'the ';
+      sparse[pos + 012260199] = 'all ';
+      sparse[-1] = 'foo';
+      sparse[pos + 22591927] = 'good ';
+      sparse[pos + 1618033] = 'for ';
+      sparse[pos + 91] = ': Now ';
+      sparse[pos + 86720199] = 'men.';
+      sparse.hest = 'fisk';
+
+      assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+    }
+
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+
+    // Splice works differently from join.
+    // IE, Safari get this wrong.
+    // FF, Opera get this right.
+    // 15.4.4.12 line 24 says the object itself has to have the property...
+    var zero = splice_function(a, pos, 1);
+    assertEquals("undefined", typeof(a[pos]));
+    assertEquals("two", a[pos+1], "pos1:" + pos);
+    assertEquals(pos + 2, a.length, "a length");
+    assertEquals(1, zero.length, "zero length");
+    assertEquals("zero", zero[0]);
+
+    // 15.4.4.12 line 41 says the object itself has to have the property...
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+    var nothing = splice_function_2(a, pos, 0, 'minus1');
+    assertEquals("minus1", a[pos]);
+    assertEquals("zero", a[pos+1]);
+    assertEquals("undefined", typeof(a[pos+2]), "toot!");
+    assertEquals("two", a[pos+3], "pos3");
+    assertEquals(pos + 4, a.length);
+    assertEquals(1, zero.length);
+    assertEquals("zero", zero[0]);
+
+    // 15.4.4.12 line 10 says the object itself has to have the property...
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+    var one = splice_function(a, pos + 1, 1);
+    assertEquals("", one.join(","));
+    assertEquals(pos + 2, a.length);
+    assertEquals("zero", a[pos]);
+    assertEquals("two", a[pos+1]);
+
+    // Set things back to the way they were.
+    the_prototype[pos + 1] = undefined;
+
+    // Unshift.
+    var a = new_function(pos);
+    push_function(a, "foo");
+    assertEquals("foo", a[pos]);
+    assertEquals(pos + 1, a.length);
+    unshift_function(a, "bar");
+    assertEquals("foo", a[pos+1]);
+    assertEquals(pos + 2, a.length);
+    assertEquals("bar", a[0]);
+    unshift_function_2(a, "baz", "boo");
+    assertEquals("foo", a[pos+3]);
+    assertEquals(pos + 4, a.length);
+    assertEquals("baz", a[0]);
+    assertEquals("boo", a[1]);
+    assertEquals("bar", a[2]);
+
+    // Shift.
+    var baz = shift_function(a);
+    assertEquals("baz", baz);
+    assertEquals("boo", a[0]);
+    assertEquals(pos + 3, a.length);
+    assertEquals("foo", a[pos + 2]);
+
+    // Slice.
+    var bar = slice_function(a, 1, 0);  // don't throw an exception please.
+    bar = slice_function(a, 1, 2);
+    assertEquals("bar", bar[0]);
+    assertEquals(1, bar.length);
+    assertEquals("bar", a[1]);
+
+  }
+}
+
+// Lets see if performance is reasonable.
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += 1000) {
+  a[i] = i;
+}
+
+// Take something near the end of the array.
+for (var i = 0; i < 100; i++) {
+  var top = a.splice(LARGE, 5);
+  assertEquals(5, top.length);
+  assertEquals(LARGE, top[0]);
+  assertEquals("undefined", typeof(top[1]));
+  assertEquals(LARGE + 5, a.length);
+  a.splice(LARGE, 0, LARGE);
+  a.length = LARGE + 10;
+}
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += fourhundredth) {
+  a[i] = i;
+}
+
+// Take something near the middle of the array.
+for (var i = 0; i < 10; i++) {
+  var top = a.splice(LARGE >> 1, 5);
+  assertEquals(5, top.length);
+  assertEquals(LARGE >> 1, top[0]);
+  assertEquals("undefined", typeof(top[1]));
+  assertEquals(LARGE + 5, a.length);
+  a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
+}
+
+
+// Test http://b/issue?id=1202711
+arr = [0];
+arr.length = 2;
+Array.prototype[1] = 1;
+assertEquals(1, arr.pop());
+assertEquals(0, arr.pop());
+Array.prototype[1] = undefined;
+
+// Test http://code.google.com/p/chromium/issues/detail?id=21860
+Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
diff --git a/test/mjsunit/array-shift.js b/test/mjsunit/array-shift.js
new file mode 100644
index 0000000..d985b31
--- /dev/null
+++ b/test/mjsunit/array-shift.js
@@ -0,0 +1,71 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that shifting array of holes keeps it as array of holes
+(function() {
+  var array = new Array(10);
+  array.shift();
+  assertFalse(0 in array);
+})();
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+  Array.prototype[3] = "@3";
+  Array.prototype[7] = "@7";
+
+  assertEquals(len, array.length);
+  for (var i = 0; i < array.length; i++) {
+    assertEquals(array[i], Array.prototype[i]);
+  }
+
+  array.shift();
+
+  assertEquals(len - 1, array.length);
+  // Note that shift copies values from prototype into the array.
+  assertEquals(array[2], Array.prototype[3]);
+  assertTrue(array.hasOwnProperty(2));
+
+  assertEquals(array[6], Array.prototype[7]);
+  assertTrue(array.hasOwnProperty(6));
+
+  // ... but keeps the rest as holes:
+  Array.prototype[5] = "@5";
+  assertEquals(array[5], Array.prototype[5]);
+  assertFalse(array.hasOwnProperty(5));
+
+  assertEquals(array[3], Array.prototype[3]);
+  assertFalse(array.hasOwnProperty(3));
+
+  assertEquals(array[7], Array.prototype[7]);
+  assertFalse(array.hasOwnProperty(7));
+
+  assertTrue(delete Array.prototype[3]);
+  assertTrue(delete Array.prototype[5]);
+  assertTrue(delete Array.prototype[7]);
+})();
diff --git a/test/mjsunit/array-slice.js b/test/mjsunit/array-slice.js
new file mode 100644
index 0000000..c993a07
--- /dev/null
+++ b/test/mjsunit/array-slice.js
@@ -0,0 +1,162 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that slicing array of holes keeps it as array of holes
+(function() {
+  var array = new Array(10);
+  for (var i = 0; i < 7; i++) {
+    var sliced = array.slice();
+    assertEquals(array.length, sliced.length);
+    assertFalse(0 in sliced);
+  }
+})();
+
+
+// Check various forms of arguments omission.
+(function() {
+  var array = new Array(7);
+
+  for (var i = 0; i < 7; i++) {
+    assertEquals(array, array.slice());
+    assertEquals(array, array.slice(0));
+    assertEquals(array, array.slice(undefined));
+    assertEquals(array, array.slice("foobar"));
+    assertEquals(array, array.slice(undefined, undefined));
+  }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+  var array = new Array(7);
+
+  for (var i = 0; i < 7; i++) {
+    assertEquals(7, array.slice(-100).length);
+    assertEquals(3, array.slice(-3).length);
+    assertEquals(3, array.slice(4).length);
+    assertEquals(1, array.slice(6).length);
+    assertEquals(0, array.slice(7).length);
+    assertEquals(0, array.slice(8).length);
+    assertEquals(0, array.slice(100).length);
+
+    assertEquals(0, array.slice(0, -100).length);
+    assertEquals(4, array.slice(0, -3).length);
+    assertEquals(4, array.slice(0, 4).length);
+    assertEquals(6, array.slice(0, 6).length);
+    assertEquals(7, array.slice(0, 7).length);
+    assertEquals(7, array.slice(0, 8).length);
+    assertEquals(7, array.slice(0, 100).length);
+
+    // Some exotic cases.
+
+    obj = { toString: function() { throw 'Exception'; } };
+
+    // More than 2 arguments:
+    assertEquals(7, array.slice(0, 7, obj, null, undefined).length);
+
+    // Custom conversion:
+    assertEquals(1, array.slice({valueOf: function() { return 1; }},
+                                {toString: function() { return 2; }}).length);
+
+    // Throwing an exception in conversion:
+    try {
+      assertEquals(7, array.slice(0, obj).length);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
+    }
+  }
+})();
+
+
+// Nasty: modify the array in ToInteger.
+(function() {
+  var array = [];
+  var expected = []
+  bad_guy = { valueOf: function() { array.push(array.length); return -1; } };
+
+  for (var i = 0; i < 13; i++) {
+    var sliced = array.slice(bad_guy);
+    expected.push(i);
+    assertEquals(expected, array);
+    // According to the spec (15.4.4.10), length is calculated before
+    // performing ToInteger on arguments.
+    if (i == 0) {
+      assertEquals([], sliced);  // Length was 0, nothing to get.
+    } else {
+      // Actually out of array [0..i] we get [i - 1] as length is i.
+      assertEquals([i - 1], sliced);
+    }
+  }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+
+  var at3 = "@3";
+  var at7 = "@7";
+
+  for (var i = 0; i < 7; i++) {
+    Array.prototype[3] = at3;
+    Array.prototype[7] = at7;
+
+    assertEquals(len, array.length);
+    for (var i = 0; i < array.length; i++) {
+      assertEquals(array[i], Array.prototype[i]);
+    }
+
+    var sliced = array.slice();
+
+    assertEquals(len, sliced.length);
+
+    assertTrue(delete Array.prototype[3]);
+    assertTrue(delete Array.prototype[7]);
+
+    // Note that slice copies values from prototype into the array.
+    assertEquals(array[3], undefined);
+    assertFalse(array.hasOwnProperty(3));
+    assertEquals(sliced[3], at3);
+    assertTrue(sliced.hasOwnProperty(3));
+
+    assertEquals(array[7], undefined);
+    assertFalse(array.hasOwnProperty(7));
+    assertEquals(sliced[7], at7);
+    assertTrue(sliced.hasOwnProperty(7));
+
+    // ... but keeps the rest as holes:
+    Array.prototype[5] = "@5";
+    assertEquals(array[5], Array.prototype[5]);
+    assertFalse(array.hasOwnProperty(5));
+    assertEquals(sliced[5], Array.prototype[5]);
+    assertFalse(sliced.hasOwnProperty(5));
+
+    assertTrue(delete Array.prototype[5]);
+  }
+})();
diff --git a/test/mjsunit/array-splice.js b/test/mjsunit/array-splice.js
index 0543c32..18f81fe 100644
--- a/test/mjsunit/array-splice.js
+++ b/test/mjsunit/array-splice.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,290 +25,265 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-/**
- * @fileoverview Test splice, shift, unshift, slice and join on small
- * and large arrays.  Some of these methods are specified such that they
- * should work on other objects too, so we test that too.
- */
+// Check that splicing array of holes keeps it as array of holes
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var array = new Array(10);
+    var spliced = array.splice(1, 1, 'one', 'two');
+    assertEquals(1, spliced.length);
+    assertFalse(0 in spliced);
 
-var LARGE = 40000000;
-var VERYLARGE = 4000000000;
-
-// Nicer for firefox 1.5.  Unless you uncomment the following two lines,
-// smjs will appear to hang on this file.
-//var LARGE = 40000;
-//var VERYLARGE = 40000;
-
-var fourhundredth = LARGE/400;
-
-function PseudoArray() {
-};
-
-for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
-  var poses = [0, 140, 20000, VERYLARGE];
-  var the_prototype;
-  var new_function;
-  var push_function;
-  var concat_function;
-  var slice_function;
-  var splice_function;
-  var splice_function_2;
-  var unshift_function;
-  var unshift_function_2;
-  var shift_function;
-  if (use_real_arrays) {
-    new_function = function(length) {
-      return new Array(length);
-    };
-    the_prototype = Array.prototype;
-    push_function = function(array, elt) {
-      return array.push(elt);
-    };
-    concat_function = function(array, other) {
-      return array.concat(other);
-    };
-    slice_function = function(array, start, len) {
-      return array.slice(start, len);
-    };
-    splice_function = function(array, start, len) {
-      return array.splice(start, len);
-    };
-    splice_function_2 = function(array, start, len, elt) {
-      return array.splice(start, len, elt);
-    };
-    unshift_function = function(array, elt) {
-      return array.unshift(elt);
-    };
-    unshift_function_2 = function(array, elt1, elt2) {
-      return array.unshift(elt1, elt2);
-    };
-    shift_function = function(array) {
-      return array.shift();
-    };
-  } else {
-    // Don't run largest size on non-arrays or we'll be here for ever.
-    poses.pop();
-    new_function = function(length) {
-      var obj = new PseudoArray();
-      obj.length = length;
-      return obj;
-    };
-    the_prototype = PseudoArray.prototype;
-    push_function = function(array, elt) {
-      array[array.length] = elt;
-      array.length++;
-    };
-    concat_function = function(array, other) {
-      return Array.prototype.concat.call(array, other);
-    };
-    slice_function = function(array, start, len) {
-      return Array.prototype.slice.call(array, start, len);
-    };
-    splice_function = function(array, start, len) {
-      return Array.prototype.splice.call(array, start, len);
-    };
-    splice_function_2 = function(array, start, len, elt) {
-      return Array.prototype.splice.call(array, start, len, elt);
-    };
-    unshift_function = function(array, elt) {
-      return Array.prototype.unshift.call(array, elt);
-    };
-    unshift_function_2 = function(array, elt1, elt2) {
-      return Array.prototype.unshift.call(array, elt1, elt2);
-    };
-    shift_function = function(array) {
-      return Array.prototype.shift.call(array);
-    };
+    assertEquals(11, array.length);
+    assertFalse(0 in array);
+    assertTrue(1 in array);
+    assertTrue(2 in array);
+    assertFalse(3 in array);
   }
+})();
 
-  for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
-    var pos = poses[pos_pos];
-    if (pos > 100) {
-      var a = new_function(pos);
-      assertEquals(pos, a.length);
-      push_function(a, 'foo');
-      assertEquals(pos + 1, a.length);
-      var b = ['bar'];
-      // Delete a huge number of holes.
-      var c = splice_function(a, 10, pos - 20);
-      assertEquals(pos - 20, c.length);
-      assertEquals(21, a.length);
+
+// Check various forms of arguments omission.
+(function() {
+  var array;
+  for (var i = 0; i < 7; i++) {
+    // SpiderMonkey and JSC return undefined in the case where no
+    // arguments are given instead of using the implicit undefined
+    // arguments.  This does not follow ECMA-262, but we do the same for
+    // compatibility.
+    // TraceMonkey follows ECMA-262 though.
+    array = [1, 2, 3]
+    assertEquals(undefined, array.splice());
+    assertEquals([1, 2, 3], array);
+
+    // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+    // given differently from when an undefined delete count is given.
+    // This does not follow ECMA-262, but we do the same for
+    // compatibility.
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice(0));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice(undefined));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice("foobar"));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice(undefined, undefined));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice("foobar", undefined));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice(undefined, "foobar"));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice("foobar", "foobar"));
+    assertEquals([1, 2, 3], array);
+  }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+  var array, spliced;
+  for (var i = 0; i < 7; i++) {
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(-100);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(-3);
+    assertEquals([1, 2, 3, 4], array);
+    assertEquals([5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(4);
+    assertEquals([1, 2, 3, 4], array);
+    assertEquals([5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(6);
+    assertEquals([1, 2, 3, 4, 5, 6], array);
+    assertEquals([7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(7);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(8);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(100);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, -100);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, -3);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 4);
+    assertEquals([5, 6, 7], array);
+    assertEquals([1, 2, 3, 4], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 6);
+    assertEquals([7], array);
+    assertEquals([1, 2, 3, 4, 5, 6], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 7);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 8);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 100);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    // Some exotic cases.
+    obj = { toString: function() { throw 'Exception'; } };
+
+    // Throwing an exception in conversion:
+    try {
+      [1, 2, 3].splice(obj, 3);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
     }
 
-    // Add a numeric property to the prototype of the array class.  This
-    // allows us to test some borderline stuff relative to the standard.
-    the_prototype["" + (pos + 1)] = 'baz';
-
-    if (use_real_arrays) {
-      // It seems quite clear from ECMAScript spec 15.4.4.5.  Just call Get on
-      // every integer in the range.
-      // IE, Safari get this right.
-      // FF, Opera get this wrong.
-      var a = ['zero', ,'two'];
-      if (pos == 0) {
-        assertEquals("zero,baz,two", a.join(","));
-      }
-
-      // Concat only applies to real arrays, unlike most of the other methods.
-      var a = new_function(pos);
-      push_function(a, "con");
-      assertEquals("con", a[pos]);
-      assertEquals(pos + 1, a.length);
-      var b = new_function(0);
-      push_function(b, "cat");
-      assertEquals("cat", b[0]);
-      var ab = concat_function(a, b);
-      assertEquals("con", ab[pos]);
-      assertEquals(pos + 2, ab.length);
-      assertEquals("cat", ab[pos + 1]);
-      var ba = concat_function(b, a);
-      assertEquals("con", ba[pos + 1]);
-      assertEquals(pos + 2, ba.length);
-      assertEquals("cat", ba[0]);
-
-      // Join with '' as separator.
-      var join = a.join('');
-      assertEquals("con", join);
-      join = b.join('');
-      assertEquals("cat", join);
-      join = ab.join('');
-      assertEquals("concat", join);
-      join = ba.join('');
-      assertEquals("catcon", join);
-
-      var sparse = [];
-      sparse[pos + 1000] = 'is ';
-      sparse[pos + 271828] = 'time ';
-      sparse[pos + 31415] = 'the ';
-      sparse[pos + 012260199] = 'all ';
-      sparse[-1] = 'foo';
-      sparse[pos + 22591927] = 'good ';
-      sparse[pos + 1618033] = 'for ';
-      sparse[pos + 91] = ': Now ';
-      sparse[pos + 86720199] = 'men.';
-      sparse.hest = 'fisk';
-
-      assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+    try {
+      [1, 2, 3].splice(0, obj, 3);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
     }
 
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
+    array = [1, 2, 3];
+    array.splice(0, 3, obj);
+    assertEquals(1, array.length);
 
-    // Splice works differently from join.
-    // IE, Safari get this wrong.
-    // FF, Opera get this right.
-    // 15.4.4.12 line 24 says the object itself has to have the property...
-    var zero = splice_function(a, pos, 1);
-    assertEquals("undefined", typeof(a[pos]));
-    assertEquals("two", a[pos+1], "pos1:" + pos);
-    assertEquals(pos + 2, a.length, "a length");
-    assertEquals(1, zero.length, "zero length");
-    assertEquals("zero", zero[0]);
-
-    // 15.4.4.12 line 41 says the object itself has to have the property...
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
-    var nothing = splice_function_2(a, pos, 0, 'minus1');
-    assertEquals("minus1", a[pos]);
-    assertEquals("zero", a[pos+1]);
-    assertEquals("undefined", typeof(a[pos+2]), "toot!");
-    assertEquals("two", a[pos+3], "pos3");
-    assertEquals(pos + 4, a.length);
-    assertEquals(1, zero.length);
-    assertEquals("zero", zero[0]);
-
-    // 15.4.4.12 line 10 says the object itself has to have the property...
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
-    var one = splice_function(a, pos + 1, 1);
-    assertEquals("", one.join(","));
-    assertEquals(pos + 2, a.length);
-    assertEquals("zero", a[pos]);
-    assertEquals("two", a[pos+1]);
-
-    // Set things back to the way they were.
-    the_prototype[pos + 1] = undefined;
-
-    // Unshift.
-    var a = new_function(pos);
-    push_function(a, "foo");
-    assertEquals("foo", a[pos]);
-    assertEquals(pos + 1, a.length);
-    unshift_function(a, "bar");
-    assertEquals("foo", a[pos+1]);
-    assertEquals(pos + 2, a.length);
-    assertEquals("bar", a[0]);
-    unshift_function_2(a, "baz", "boo");
-    assertEquals("foo", a[pos+3]);
-    assertEquals(pos + 4, a.length);
-    assertEquals("baz", a[0]);
-    assertEquals("boo", a[1]);
-    assertEquals("bar", a[2]);
-
-    // Shift.
-    var baz = shift_function(a);
-    assertEquals("baz", baz);
-    assertEquals("boo", a[0]);
-    assertEquals(pos + 3, a.length);
-    assertEquals("foo", a[pos + 2]);
-
-    // Slice.
-    var bar = slice_function(a, 1, 0);  // don't throw an exception please.
-    bar = slice_function(a, 1, 2);
-    assertEquals("bar", bar[0]);
-    assertEquals(1, bar.length);
-    assertEquals("bar", a[1]);
-
+    // Custom conversion:
+    array = [1, 2, 3];
+    spliced = array.splice({valueOf: function() { return 1; }},
+                           {toString: function() { return 2; }},
+                           'one', 'two');
+    assertEquals([2, 3], spliced);
+    assertEquals([1, 'one', 'two'], array);
   }
-}
-
-// Lets see if performance is reasonable.
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += 1000) {
-  a[i] = i;
-}
-
-// Take something near the end of the array.
-for (var i = 0; i < 100; i++) {
-  var top = a.splice(LARGE, 5);
-  assertEquals(5, top.length);
-  assertEquals(LARGE, top[0]);
-  assertEquals("undefined", typeof(top[1]));
-  assertEquals(LARGE + 5, a.length);
-  a.splice(LARGE, 0, LARGE);
-  a.length = LARGE + 10;
-}
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += fourhundredth) {
-  a[i] = i;
-}
-
-// Take something near the middle of the array.
-for (var i = 0; i < 10; i++) {
-  var top = a.splice(LARGE >> 1, 5);
-  assertEquals(5, top.length);
-  assertEquals(LARGE >> 1, top[0]);
-  assertEquals("undefined", typeof(top[1]));
-  assertEquals(LARGE + 5, a.length);
-  a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
-}
+})();
 
 
-// Test http://b/issue?id=1202711
-arr = [0];
-arr.length = 2;
-Array.prototype[1] = 1;
-assertEquals(1, arr.pop());
-assertEquals(0, arr.pop());
-Array.prototype[1] = undefined;
+// Nasty: modify the array in ToInteger.
+(function() {
+  var array = [];
+  var spliced;
 
-// Test http://code.google.com/p/chromium/issues/detail?id=21860
-Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
+  for (var i = 0; i < 13; i++) {
+    bad_start = { valueOf: function() { array.push(2*i); return -1; } };
+    bad_count = { valueOf: function() { array.push(2*i + 1); return 1; } };
+    spliced = array.splice(bad_start, bad_count);
+    // According to the spec (15.4.4.12), length is calculated before
+    // performing ToInteger on arguments.  However, v8 ignores elements
+    // we add while converting, so we need corrective pushes.
+    array.push(2*i); array.push(2*i + 1);
+    if (i == 0) {
+      assertEquals([], spliced);  // Length was 0, nothing to get.
+      assertEquals([0, 1], array);
+    } else {
+      // When we start splice, array is [0 .. 2*i - 1], so we get
+      // as a result [2*i], this element is removed from the array,
+      // but [2 * i, 2 * i + 1] are added.
+      assertEquals([2 * i - 1], spliced);
+      assertEquals(2 * i, array[i]);
+      assertEquals(2 * i + 1, array[i + 1]);
+    }
+  }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+
+  var at3 = "@3";
+  var at7 = "@7";
+
+  for (var i = 0; i < 7; i++) {
+    var array = new Array(len);
+    Array.prototype[3] = at3;
+    Array.prototype[7] = at7;
+
+    var spliced = array.splice(2, 2, 'one', undefined, 'two');
+
+    // Second hole (at index 3) of array turns into
+    // value of Array.prototype[3] while copying.
+    assertEquals([, at3], spliced);
+    assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
+
+    // ... but array[7] is actually a hole:
+    assertTrue(delete Array.prototype[7]);
+    assertEquals(undefined, array[7]);
+
+    // and now check hasOwnProperty
+    assertFalse(array.hasOwnProperty(0));
+    assertFalse(array.hasOwnProperty(1));
+    assertTrue(array.hasOwnProperty(2));
+    assertTrue(array.hasOwnProperty(3));
+    assertTrue(array.hasOwnProperty(4));
+    assertFalse(array.hasOwnProperty(5));
+    assertFalse(array.hasOwnProperty(6));
+    assertFalse(array.hasOwnProperty(7));
+    assertTrue(array.hasOwnProperty(8));
+    assertFalse(array.hasOwnProperty(9));
+
+    // and now check couple of indices above length.
+    assertFalse(array.hasOwnProperty(10));
+    assertFalse(array.hasOwnProperty(15));
+    assertFalse(array.hasOwnProperty(31));
+    assertFalse(array.hasOwnProperty(63));
+    assertFalse(array.hasOwnProperty(2 << 32 - 1));
+  }
+})();
+
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    try {
+      new Array((1 << 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
+      throw 'Should have thrown RangeError';
+    } catch (e) {
+      assertTrue(e instanceof RangeError);
+    }
+
+    // Check smi boundary
+    var bigNum = (1 << 30) - 3;
+    var array = new Array(bigNum);
+    array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
+    assertEquals(bigNum + 7, array.length);
+  }
+})();
diff --git a/test/mjsunit/array-unshift.js b/test/mjsunit/array-unshift.js
new file mode 100644
index 0000000..06a78a7
--- /dev/null
+++ b/test/mjsunit/array-unshift.js
@@ -0,0 +1,132 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that unshifting array of holes keeps the original array
+// as array of holes
+(function() {
+  var array = new Array(10);
+  assertEquals(13, array.unshift('1st', '2ns', '3rd'));
+  assertTrue(0 in array);
+  assertTrue(1 in array);
+  assertTrue(2 in array);
+  assertFalse(3 in array);
+})();
+
+
+// Check that unshif with no args has a side-effect of
+// feeling the holes with elements from the prototype
+// (if present, of course)
+(function() {
+  var len = 3;
+  var array = new Array(len);
+
+  var at0 = '@0';
+  var at2 = '@2';
+
+  Array.prototype[0] = at0;
+  Array.prototype[2] = at2;
+
+  // array owns nothing...
+  assertFalse(array.hasOwnProperty(0));
+  assertFalse(array.hasOwnProperty(1));
+  assertFalse(array.hasOwnProperty(2));
+
+  // ... but sees values from Array.prototype
+  assertEquals(array[0], at0);
+  assertEquals(array[1], undefined);
+  assertEquals(array[2], at2);
+
+  assertEquals(len, array.unshift());
+
+  assertTrue(delete Array.prototype[0]);
+  assertTrue(delete Array.prototype[2]);
+
+  // unshift makes array own 0 and 2...
+  assertTrue(array.hasOwnProperty(0));
+  assertFalse(array.hasOwnProperty(1));
+  assertTrue(array.hasOwnProperty(2));
+
+  // ... so they are not affected be delete.
+  assertEquals(array[0], at0);
+  assertEquals(array[1], undefined);
+  assertEquals(array[2], at2);
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+  Array.prototype[3] = "@3";
+  Array.prototype[7] = "@7";
+
+  assertEquals(len, array.length);
+  for (var i = 0; i < array.length; i++) {
+    assertEquals(array[i], Array.prototype[i]);
+  }
+
+  assertEquals(len + 1, array.unshift('head'));
+
+  assertEquals(len + 1, array.length);
+  // Note that unshift copies values from prototype into the array.
+  assertEquals(array[4], Array.prototype[3]);
+  assertTrue(array.hasOwnProperty(4));
+
+  assertEquals(array[8], Array.prototype[7]);
+  assertTrue(array.hasOwnProperty(8));
+
+  // ... but keeps the rest as holes:
+  Array.prototype[5] = "@5";
+  assertEquals(array[5], Array.prototype[5]);
+  assertFalse(array.hasOwnProperty(5));
+
+  assertEquals(array[3], Array.prototype[3]);
+  assertFalse(array.hasOwnProperty(3));
+
+  assertEquals(array[7], Array.prototype[7]);
+  assertFalse(array.hasOwnProperty(7));
+
+  assertTrue(delete Array.prototype[3]);
+  assertTrue(delete Array.prototype[5]);
+  assertTrue(delete Array.prototype[7]);
+})();
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    try {
+      new Array((1 << 32) - 3).unshift(1, 2, 3, 4, 5);
+      throw 'Should have thrown RangeError';
+    } catch (e) {
+      assertTrue(e instanceof RangeError);
+    }
+
+    // Check smi boundary
+    var bigNum = (1 << 30) - 3;
+    assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7));
+  }
+})();
diff --git a/test/mjsunit/bugs/618.js b/test/mjsunit/bugs/618.js
new file mode 100644
index 0000000..afa9929
--- /dev/null
+++ b/test/mjsunit/bugs/618.js
@@ -0,0 +1,86 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Simple class using inline constructor.
+function C1() {
+  this.x = 23;
+};
+var c1 = new C1();
+assertEquals(23, c1.x);
+assertEquals("undefined", typeof c1.y);
+  
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C1.prototype = { set x(value) { this.y = 23; } };
+var c1 = new C1();
+assertEquals("undefined", typeof c1.x);
+assertEquals(23, c1.y);
+  
+// Simple class using inline constructor.
+function C2() {
+  this.x = 23;
+};
+var c2 = new C2();
+assertEquals(23, c2.x);
+assertEquals("undefined", typeof c2.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+var c2 = new C2();
+assertEquals("undefined", typeof c2.x);
+assertEquals(23, c2.y);
+
+// Simple class using inline constructor.
+function C3() {
+  this.x = 23;
+};
+var c3 = new C3();
+assertEquals(23, c3.x);
+assertEquals("undefined", typeof c3.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+var c3 = new C3();
+assertEquals("undefined", typeof c3.x);
+assertEquals(23, c3.y);
+
+// Simple class using inline constructor.
+function C4() {
+  this.x = 23;
+};
+var c4 = new C4();
+assertEquals(23, c4.x);
+assertEquals("undefined", typeof c4.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+var c4 = new C4();
+assertEquals("undefined", typeof c4.x);
+assertEquals(23, c4.y);
diff --git a/test/mjsunit/bugs/bug-619.js b/test/mjsunit/bugs/bug-619.js
new file mode 100644
index 0000000..ef8ba80
--- /dev/null
+++ b/test/mjsunit/bugs/bug-619.js
@@ -0,0 +1,62 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// When this bug is corrected move to object-define-property and add
+// additional tests for configurable in the same manner as existing tests
+// there.
+
+var obj = {};
+obj[1] = 42;
+assertEquals(42, obj[1]);
+Object.defineProperty(obj, '1', {value:10, writable:false});
+assertEquals(10, obj[1]);
+
+// We should not be able to override obj[1].
+obj[1] = 5;
+assertEquals(10, obj[1]);
+
+// Try on a range of numbers.
+for(var i = 0; i < 1024; i++) {
+  obj[i] = 42;
+}
+
+for(var i = 0; i < 1024; i++) {
+  Object.defineProperty(obj, i, {value: i, writable:false});
+}
+
+for(var i = 0; i < 1024; i++) {
+  assertEquals(i, obj[i]);
+}
+
+for(var i = 0; i < 1024; i++) {
+  obj[1] = 5;
+}
+
+for(var i = 0; i < 1024; i++) {
+  assertEquals(i, obj[i]);
+}
+
diff --git a/test/mjsunit/codegen-coverage.js b/test/mjsunit/codegen-coverage.js
index d5e7769..42c371b 100644
--- a/test/mjsunit/codegen-coverage.js
+++ b/test/mjsunit/codegen-coverage.js
@@ -25,64 +25,110 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test the paths in the code generator where values in specific
-// registers get moved around so that the shift operation can use
-// register ECX on ia32 for the shift amount.  Other codegen coverage
-// tests should go here too.
+// Flags: --nofull-compiler --nofast-compiler
 
-
-
+// Test paths in the code generator where values in specific registers
+// get moved around.
 function identity(x) {
   return x;
 }
 
 function cover_codegen_paths() {
   var x = 1;
-  var a;  // Register EAX
-  var b;  // Register EBX
-  var c;  // Register ECX
-  var d;  // Register EDX
-  // Register ESI is already used.
-  var di;  // Register EDI
+
+  // This test depends on the fixed order of register allocation.  We try to
+  // get values in specific registers (ia32, x64):
+  var a;   // Register eax, rax.
+  var b;   // Register ebx, rbx.
+  var c;   // Register ecx, rcx.
+  var d;   // Register edx, rdx.
+  var di;  // Register edi, rdi.
 
   while (x == 1) {
+    // The call will spill registers and leave x in {eax,rax}.
     x = identity(1);
+    // The add will spill x and reuse {eax,rax} for the result.
     a = x + 1;
+    // A fresh register {ebx,rbx} will be allocated for x, then reused for
+    // the result.
+    b = x + 1;
+    // Et cetera.
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
     // Locals are in the corresponding registers here.
-    assertEquals(c << a, 8);
+    assertEquals(8, c << a);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
-    assertEquals(a << c, 8);
+    assertEquals(8, a << c);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
     c = 0; // Free register ecx.
-    assertEquals(a << d, 8);
+    assertEquals(8, a << d);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
     b = 0; // Free register ebx.
-    assertEquals(a << d, 8);
+    assertEquals(8, a << d);
+
+    // Test the non-commutative subtraction operation with a smi on the
+    // left, all available registers on the right, and a non-smi result.
+    x = identity(-1073741824);  // Least (31-bit) smi.
+    a = x + 1;  // Still a smi, the greatest smi negated.
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    // Subtraction should overflow the 31-bit smi range.  The result
+    // (1073741824) is outside the 31-bit smi range so it doesn't hit the
+    // "unsafe smi" code that spills a register.
+    assertEquals(1073741824, 1 - a);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - b);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - c);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - d);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - di);
 
     x = 3;
   }
diff --git a/test/mjsunit/compiler/assignment.js b/test/mjsunit/compiler/assignment.js
new file mode 100644
index 0000000..ee2d323
--- /dev/null
+++ b/test/mjsunit/compiler/assignment.js
@@ -0,0 +1,264 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests for compound assignments at the top level
+
+z = 2;
+z += 4;
+
+assertEquals(z, 6);
+
+a = new Array(10);
+
+a[2] += 7;
+a[2] = 15;
+a[2] += 2;
+
+assertEquals(17, a[2]);
+
+b = new Object();
+b.foo = 5;
+b.foo += 12;
+
+assertEquals(17, b.foo);
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+  var z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  var a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  var b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+  z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo() {
+  var z = 3;
+  z += 4;
+
+  assertEquals(z, 7);
+
+  var a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  var b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+foo();
+
+// Test compound assignments in a named function with global variables.
+function bar() {
+  z = 2;
+  z += 5;
+
+  assertEquals(z, 7);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+bar();
+
+// Entire series of tests repeated, in loops.
+// -------------------------------------------
+// Tests for compound assignments in a loop at the top level
+
+for (i = 0; i < 5; ++i) {
+  z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+  for (var i = 0; i < 5; ++i) {
+    var z = 2;
+    z += 4;
+
+    assertEquals(z, 6);
+
+    var a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    var b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+  for (i = 0; i < 5; ++i) {
+    z = 2;
+    z += 4;
+
+    assertEquals(z, 6);
+
+    a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo_loop() {
+  for (i = 0; i < 5; ++i) {
+    var z = 3;
+    z += 4;
+
+    assertEquals(z, 7);
+
+    var a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    var b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+}
+
+foo_loop();
+
+// Test compound assignments in a named function with global variables.
+function bar_loop() {
+  for (i = 0; i < 5; ++i) {
+    z = 2;
+    z += 5;
+
+    assertEquals(z, 7);
+
+    a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+}
+
+bar_loop();
diff --git a/test/mjsunit/compiler/simple-bailouts.js b/test/mjsunit/compiler/simple-bailouts.js
new file mode 100644
index 0000000..af80b7f
--- /dev/null
+++ b/test/mjsunit/compiler/simple-bailouts.js
@@ -0,0 +1,127 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+function Test() {
+  this.result = 0;
+  this.x = 0;
+  this.y = 0;
+  this.z = 0;
+}
+var a = 1;
+var b = 2;
+var c = 4;
+var d = 8;
+
+// Test operations expected to stay on the fast path.  Enumerate all binary
+// trees with <= 4 leaves.
+Test.prototype.test0 = function () {
+  this.result = a | b;
+};
+
+Test.prototype.test1 = function() {
+  this.result = (a | b) | c;
+};
+
+Test.prototype.test2 = function() {
+  this.result = a | (b | c);
+};
+
+Test.prototype.test3 = function() {
+  this.result = ((a | b) | c) | d;
+};
+
+Test.prototype.test4 = function() {
+  this.result = (a | (b | c)) | d;
+};
+
+Test.prototype.test5 = function() {
+  this.result = (a | b) | (c | d);
+};
+
+Test.prototype.test6 = function() {
+  this.result = a | ((b | c) | d);
+};
+
+Test.prototype.test7 = function() {
+  this.result = a | (b | (c | d));
+};
+
+// These tests should fail if we bailed out to the beginning of the full
+// code.
+Test.prototype.test8 = function () {
+  // If this.x = 1 and a = 1.1:
+  this.y = this.x | b;  // Should be (1 | 2) == 3.
+  this.x = c;           // Should be 4.
+  this.z = this.x | a;  // Should be (4 | 1.1) == 5.
+};
+
+Test.prototype.test9 = function() {
+  // If this.x = 2 and a = 1.1:
+  this.z =              // (14 | 1.1) == 15
+      (this.x =         // (6 | 8) == 14
+           (this.y =    // (2 | 4) == 6
+                this.x  // 2
+                | c)    // 4
+            | d)        // 8
+       | a;             // 1.1
+}
+
+var t = new Test();
+
+t.test0();
+assertEquals(3, t.result);
+
+t.test1();
+assertEquals(7, t.result);
+t.test2();
+assertEquals(7, t.result);
+
+t.test3();
+assertEquals(15, t.result);
+t.test4();
+assertEquals(15, t.result);
+t.test5();
+assertEquals(15, t.result);
+t.test6();
+assertEquals(15, t.result);
+t.test7();
+assertEquals(15, t.result);
+
+a = 1.1;
+t.x = 1;
+t.test8();
+assertEquals(4, t.x);
+assertEquals(3, t.y);
+assertEquals(5, t.z);
+
+t.x = 2;
+t.test9();
+assertEquals(14, t.x);
+assertEquals(6, t.y);
+assertEquals(15, t.z);
diff --git a/test/mjsunit/compiler/simple-binary-op.js b/test/mjsunit/compiler/simple-binary-op.js
new file mode 100644
index 0000000..15e1a55
--- /dev/null
+++ b/test/mjsunit/compiler/simple-binary-op.js
@@ -0,0 +1,40 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+var a = 1;
+var b = 2;
+var c = 4;
+
+function f() { this.x = this.x | a | b | c | a | c; }
+
+var o = {x:0, g:f}
+
+o.g();
+
+assertEquals(7, o.x);
diff --git a/test/mjsunit/compiler/simple-global-access.js b/test/mjsunit/compiler/simple-global-access.js
new file mode 100644
index 0000000..35746ba
--- /dev/null
+++ b/test/mjsunit/compiler/simple-global-access.js
@@ -0,0 +1,53 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+// Test global variable loads with the fast compiler.
+var g1 = 42;
+var g2 = 43;
+var g3 = 44;
+this.__defineGetter__("g4", function () { return 45; });
+
+function f1() { this.x = this.y = this.z = g1; }
+function f2() { this.x = g1; this.y = g2; this.z = g3; }
+function f3() { this.x = g4; }
+
+var o = { x:0, y:0, z:0, test1:f1, test2:f2, test3:f3 }
+
+o.test1();
+assertEquals(42, o.x);
+assertEquals(42, o.y);
+assertEquals(42, o.z);
+
+o.test2();
+assertEquals(42, o.x);
+assertEquals(43, o.y);
+assertEquals(44, o.z);
+
+o.test3();
+assertEquals(45, o.x);
diff --git a/test/mjsunit/compiler/this-property-refs.js b/test/mjsunit/compiler/this-property-refs.js
new file mode 100644
index 0000000..5e8ea59
--- /dev/null
+++ b/test/mjsunit/compiler/this-property-refs.js
@@ -0,0 +1,64 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+// Test references to properties of this.
+function Test() {
+  this.a = 0;
+  this.b = 1;
+  this.c = 2;
+  this.d = 3;
+}
+
+Test.prototype.test0 = function () {
+  this.a = this.b;
+};
+
+Test.prototype.test1 = function() {
+  this.a = this.b = this.c;
+};
+
+Test.prototype.test2 = function() {
+  this.c = this.d;
+  this.b = this.c;
+  this.a = this.b;
+};
+
+var t = new Test();
+
+t.test0();
+assertEquals(1, t.a);
+
+t.test1();
+assertEquals(2, t.a);
+assertEquals(2, t.b);
+
+t.test2();
+assertEquals(3, t.a);
+assertEquals(3, t.b);
+assertEquals(3, t.c);
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index 071183b..e7ecf47 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -90,6 +90,11 @@
       var json = event_data.toJSONProtocol();
       var msg = eval('(' + json + ')');
       assertTrue('context' in msg.body.script);
+
+      // Check that we pick script name from //@ sourceURL, iff present
+      assertEquals(current_source.indexOf('sourceURL') >= 0 ? 
+                     'myscript.js' : undefined,
+                   event_data.script().name());
     }
   } catch (e) {
     exception = e
@@ -109,6 +114,7 @@
 source_count += 2;  // Using eval causes additional compilation event.
 compileSource('JSON.parse(\'{"a":1,"b":2}\')');
 source_count++;  // Using JSON.parse causes additional compilation event.
+compileSource('x=1; //@ sourceURL=myscript.js');
 
 // Make sure that the debug event listener was invoked.
 assertFalse(exception, "exception in listener")
diff --git a/test/mjsunit/debug-evaluate.js b/test/mjsunit/debug-evaluate.js
index c477907..182e2ac 100644
--- a/test/mjsunit/debug-evaluate.js
+++ b/test/mjsunit/debug-evaluate.js
@@ -87,6 +87,37 @@
       testRequest(dcp, '{"expression":"a","global":true}', true, 1);
       testRequest(dcp, '{"expression":"this.a","global":true}', true, 1);
 
+      // Test that the whole string text is returned if maxStringLength
+      // parameter is passed.
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:-1}',
+          true,
+          longString);
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:' +
+              longString.length + '}',
+          true,
+          longString);
+      var truncatedStringSuffix = '... (length: ' + longString.length + ')';
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:0}',
+          true,
+          truncatedStringSuffix);
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:1}',
+          true,
+          longString.charAt(0) + truncatedStringSuffix);
+      // Test that by default string is truncated to first 80 chars.
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true}',
+          true,
+          longString.substring(0, 80) + truncatedStringSuffix);
+
       // Indicate that all was processed.
       listenerComplete = true;
     }
@@ -109,6 +140,12 @@
 
 a = 1;
 
+// String which is longer than 80 chars.
+var longString = "1234567890_";
+for (var i = 0; i < 4; i++) {
+  longString += longString;
+}
+
 // Set a break point at return in f and invoke g to hit the breakpoint.
 Debug.setBreakPoint(f, 2, 0);
 g();
diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js
index b3c77e1..1d352b5 100644
--- a/test/mjsunit/div-mod.js
+++ b/test/mjsunit/div-mod.js
@@ -154,4 +154,18 @@
       doTest(-a,-b);
     }
   }
-})()
+})();
+
+
+(function () {
+  // Edge cases
+  var zero = 0;
+  var minsmi32 = -0x40000000;
+  var minsmi64 = -0x80000000;
+  var somenum = 3532;
+  assertEquals(-0, zero / -1, "0 / -1");
+  assertEquals(1, minsmi32 / -0x40000000, "minsmi/minsmi-32");
+  assertEquals(1, minsmi64 / -0x80000000, "minsmi/minsmi-64");
+  assertEquals(somenum, somenum % -0x40000000, "%minsmi-32");
+  assertEquals(somenum, somenum % -0x80000000, "%minsmi-64");
+})();
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index d906eb8..e2f601e 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -27,6 +27,9 @@
 
 // Flags: --allow-natives-syntax
 
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
 function makeArguments() {
   var result = [ ];
   result.push(17);
@@ -74,13 +77,23 @@
   var func = makeFunction(name, argc);
   while (hasMore) {
     var argPool = makeArguments();
+    // When we have 5 or more arguments we lower the amount of tests cases
+    // by randomly removing kOnManyArgumentsRemove entries
+    var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+      kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+    if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+      for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+        var rand = Math.floor(Math.random() * (kArgObjects - i));
+        argPool.splice(rand,1);
+      }
+    }
     var current = type;
     var hasMore = false;
     var argList = [ ];
     for (var i = 0; i < argc; i++) {
-      var index = current % kArgObjects;
-      current = (current / kArgObjects) << 0;
-      if (index != (kArgObjects - 1))
+      var index = current % numArguments;
+      current = (current / numArguments) << 0;
+      if (index != (numArguments - 1))
         hasMore = true;
       argList.push(argPool[index]);
     }
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
new file mode 100644
index 0000000..6b3725b
--- /dev/null
+++ b/test/mjsunit/object-define-properties.js
@@ -0,0 +1,56 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests the Object.defineProperties method - ES 15.2.3.7
+// Note that the internal DefineOwnProperty method is tested through 
+// object-define-property.js, this file only contains tests specific for
+// Object.defineProperties. Also note that object-create.js contains
+// a range of indirect tests on this method since Object.create uses
+// Object.defineProperties as a step in setting up the object.
+
+// Try defining with null as descriptor:
+try {
+  Object.defineProperties({}, null);
+} catch(e) {
+  assertTrue(/null to object/.test(e));
+}
+
+// Try defining with null as object
+try {
+  Object.defineProperties(null, {});
+} catch(e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+
+var desc = {foo: {value: 10}, bar: {get: function() {return 42; }}};
+var obj = {};
+// Check that we actually get the object back as returnvalue
+var x = Object.defineProperties(obj, desc);
+
+assertEquals(x.foo, 10);
+assertEquals(x.bar, 42);
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
new file mode 100644
index 0000000..43b1c7f
--- /dev/null
+++ b/test/mjsunit/object-define-property.js
@@ -0,0 +1,499 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests the object.defineProperty method - ES 15.2.3.6
+
+// Flags: --allow-natives-syntax
+
+// Check that an exception is thrown when null is passed as object.
+try {
+  Object.defineProperty(null, null, null);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when undefined is passed as object.
+try {
+  Object.defineProperty(undefined, undefined, undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when non-object is passed as object.
+try {
+  Object.defineProperty(0, "foo", undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Object
+var obj1 = {};
+
+// Values
+var val1 = 0;
+var val2 = 0;
+var val3 = 0;
+
+// Descriptors
+var emptyDesc = {};
+
+var accessorConfigurable = { 
+    set: function() { val1++; },
+    get: function() { return val1; },
+    configurable: true
+};
+
+var accessorNoConfigurable = {
+    set: function() { val2++; },
+    get: function() { return val2; },
+    configurable: false 
+};
+
+var accessorOnlySet = {
+  set: function() { val3++; },
+  configurable: true
+};
+
+var accessorOnlyGet = {
+  get: function() { return val3; },
+  configurable: true
+};
+
+var accessorDefault = {set: function(){} };
+
+var dataConfigurable = { value: 1000, configurable: true };
+
+var dataNoConfigurable = { value: 2000, configurable: false };
+
+var dataWritable = { value: 3000, writable: true};
+
+
+// Check that we can't add property with undefined attributes.
+try {
+  Object.defineProperty(obj1, "foo", undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/must be an object/.test(e));
+}
+
+// Make sure that we can add a property with an empty descriptor and
+// that it has the default descriptor values.
+Object.defineProperty(obj1, "foo", emptyDesc);
+
+// foo should be undefined as it has no get, set or value
+assertEquals(undefined, obj1.foo);
+
+// We should, however, be able to retrieve the propertydescriptor which should
+// have all default values (according to 8.6.1).
+var desc = Object.getOwnPropertyDescriptor(obj1, "foo");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertFalse(desc.writable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+assertEquals(desc.value, undefined);
+
+// Make sure that getOwnPropertyDescriptor does not return a descriptor
+// with default values if called with non existing property (otherwise
+// the test above is invalid).
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertEquals(desc, undefined);
+
+// Make sure that foo can't be reset (as configurable is false).
+try {
+  Object.defineProperty(obj1, "foo", accessorConfigurable);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Accessor properties
+
+Object.defineProperty(obj1, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(1, val1);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(2, obj1.bar);
+
+// Redefine bar with non configurable test
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(1, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(2, val2);
+assertEquals(2, obj1.bar);
+
+// Try to redefine bar again - should fail as configurable is false.
+try {
+  Object.defineProperty(obj1, "bar", accessorConfigurable);
+  assertTrue(false);
+} catch(e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try to redefine bar again using the data descriptor - should fail.
+try {
+  Object.defineProperty(obj1, "bar", dataConfigurable);
+  assertTrue(false);
+} catch(e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Redefine using same descriptor - should succeed.
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(3, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(4, val2);
+assertEquals(4, obj1.bar);
+
+// Define an accessor that has only a setter
+Object.defineProperty(obj1, "setOnly", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(desc.get, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(1, val3);
+
+// Add a getter - should not touch the setter
+Object.defineProperty(obj1, "setOnly", accessorOnlyGet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, accessorOnlyGet.get);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(2, val3);
+
+// The above should also work if redefining just a getter or setter on 
+// an existing property with both a getter and a setter.
+Object.defineProperty(obj1, "both", accessorConfigurable);
+
+Object.defineProperty(obj1, "both", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "both");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.both = 1);
+assertEquals(3, val3);
+
+
+// Data properties
+
+Object.defineProperty(obj1, "foobar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+//Try writing to non writable attribute - should remain 1000
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1000);
+
+
+// Redefine to writable descriptor - now writing to foobar should be allowed
+Object.defineProperty(obj1, "foobar", dataWritable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 3000);
+assertEquals(desc.value, 3000);
+// Note that since dataWritable does not define configurable the configurable
+// setting from the redefined property (in this case true) is used.
+assertTrue(desc.configurable);
+assertTrue(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+// Writing to the property should now be allowed
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1001);
+
+
+// Redefine with non configurable data property.
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+// Try redefine again - shold fail because configurable is now false.
+try {
+  Object.defineProperty(obj1, "foobar", dataConfigurable);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try redefine again with accessor property - shold also fail.
+try {
+  Object.defineProperty(obj1, "foobar", dataConfigurable);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Redifine with the same descriptor - should succeed (step 6).
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// New object
+var obj2 = {};
+
+// Make accessor - redefine to data
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+
+// Redefine to data property
+Object.defineProperty(obj2, "foo", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertEquals(obj2.foo, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefine back to accessor
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.foo = 1);
+assertEquals(3, val1);
+assertEquals(4, val2);
+assertEquals(3, obj2.foo);
+
+// Make data - redefine to accessor
+Object.defineProperty(obj2, "bar", dataConfigurable)
+
+// Redefine to accessor property
+Object.defineProperty(obj2, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.bar = 1);
+assertEquals(4, val1);
+assertEquals(4, val2);
+assertEquals(4, obj2.foo);
+
+// Redefine back to data property
+Object.defineProperty(obj2, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertEquals(obj2.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefinition of an accessor defined using __defineGetter__ and 
+// __defineSetter__
+function get(){return this.x}
+function set(x){this.x=x};
+
+var obj3 = {x:1000};
+obj3.__defineGetter__("foo", get);
+obj3.__defineSetter__("foo", set);
+
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, get);
+assertEquals(desc.set, set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(1, obj3.x);
+assertEquals(1, obj3.foo);
+
+// Redefine to accessor property (non configurable) - note that enumerable
+// which we do not redefine should remain the same (true).
+Object.defineProperty(obj3, "foo", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertFalse(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(5, val2);
+assertEquals(5, obj3.foo);
+
+
+obj3.__defineGetter__("bar", get);
+obj3.__defineSetter__("bar", set);
+
+
+// Redefine back to data property
+Object.defineProperty(obj3, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "bar");
+assertEquals(obj3.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertTrue(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+var obj4 = {};
+var func = function (){return 42;};
+obj4.bar = func;
+assertEquals(42, obj4.bar());
+
+Object.defineProperty(obj4, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj4, "bar");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj4.bar = 1);
+assertEquals(5, val1);
+assertEquals(5, obj4.bar);
+
+// Make sure an error is thrown when trying to access to redefined function
+try {
+  obj4.bar();
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/is not a function/.test(e));
+}
+
+
+// Test runtime calls to DefineOrRedefineDataProperty and
+// DefineOrRedefineAccessorProperty - make sure we don't 
+// crash
+try {
+  %DefineOrRedefineAccessorProperty(0, 0, 0, 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(0, 0, 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(null, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineAccessorProperty(null, null, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty({}, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+// Defining properties null should fail even when we have
+// other allowed values
+try {
+  %DefineOrRedefineAccessorProperty(null, 'foo', 0, func, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(null, 'foo', 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
diff --git a/test/mjsunit/object-get-own-property-names.js b/test/mjsunit/object-get-own-property-names.js
index f52cee2..33aa85e 100644
--- a/test/mjsunit/object-get-own-property-names.js
+++ b/test/mjsunit/object-get-own-property-names.js
@@ -57,6 +57,8 @@
 assertEquals(3, propertyNames.length);
 assertEquals("0", propertyNames[0]);
 assertEquals("1", propertyNames[1]);
+assertEquals("string", typeof propertyNames[0]);
+assertEquals("string", typeof propertyNames[1]);
 assertEquals("length", propertyNames[2]);
 
 // Check that no proto properties are returned.
diff --git a/test/mjsunit/regress/regress-603.js b/test/mjsunit/regress/regress-603.js
new file mode 100644
index 0000000..7d4c322
--- /dev/null
+++ b/test/mjsunit/regress/regress-603.js
@@ -0,0 +1,49 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Calling non-objects directly or via Function.prototype.call should
+// not mess up the stack.
+// http://code.google.com/p/v8/issues/detail?id=603
+
+function test0() {
+  var re = /b../;
+  return re('abcdefghijklm') + 'z';
+}
+assertEquals('bcdz', test0());
+
+var re1 = /c../;
+re1.call = Function.prototype.call;
+var test1 = re1.call(null, 'abcdefghijklm') + 'z';
+assertEquals('cdez', test1);
+
+var re2 = /d../;
+var test2 = Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
+assertEquals('defz', test2);
+
+var re3 = /e../;
+var test3 = Function.prototype.call.apply(re3, [null, 'abcdefghijklm']) + 'z';
+assertEquals('efgz', test3);
diff --git a/test/mjsunit/regress/regress-612.js b/test/mjsunit/regress/regress-612.js
new file mode 100644
index 0000000..aee6d53
--- /dev/null
+++ b/test/mjsunit/regress/regress-612.js
@@ -0,0 +1,44 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests intercation between __defineGetter__/__defineSetter and fast and slow
+// mode of the objects due to series of assignments optimization.
+// (See http://code.google.com/p/v8/issues/detail?id=612)
+
+obj = {}
+
+// Define getter which currently moves object into slow mode.
+obj.__defineGetter__('foobar', function() { return 42; })
+
+// Starts initialization block mode.  And turns object into slow mode.
+obj.a = 1
+obj.b = 2;
+obj.c = 3;
+// Now object is turned into fast mode, but it has getter defined above...
+
+// Now assert is triggered.
+obj.__defineGetter__('foobar', function() { return 42; })
diff --git a/test/mjsunit/setter-on-constructor-prototype.js b/test/mjsunit/setter-on-constructor-prototype.js
new file mode 100644
index 0000000..d5718f9
--- /dev/null
+++ b/test/mjsunit/setter-on-constructor-prototype.js
@@ -0,0 +1,111 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function RunTest(ensure_fast_case) {
+  function C1() {
+    this.x = 23;
+  };
+  C1.prototype = { set x(value) { this.y = 23; } };
+  if (ensure_fast_case) {
+    %ToFastProperties(C1.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c1 = new C1();
+    assertEquals("undefined", typeof c1.x);
+    assertEquals(23, c1.y);
+  }
+  
+  
+  function C2() {
+    this.x = 23;
+  };
+  C2.prototype = { };
+  C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+  if (ensure_fast_case) {
+    %ToFastProperties(C2.prototype.__proto__)
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c2 = new C2();
+    assertEquals("undefined", typeof c2.x);
+    assertEquals(23, c2.y);
+  }
+  
+  
+  function C3() {
+    this.x = 23;
+  };
+  C3.prototype = { };
+  C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+  if (ensure_fast_case) {
+    %ToFastProperties(C3.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c3 = new C3();
+    assertEquals("undefined", typeof c3.x);
+    assertEquals(23, c3.y);
+  }
+  
+  
+  function C4() {
+    this.x = 23;
+  };
+  C4.prototype = { };
+  C4.prototype.__proto__ = {  };
+  C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+  if (ensure_fast_case) {
+    %ToFastProperties(C4.prototype.__proto__);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c4 = new C4();
+    assertEquals("undefined", typeof c4.x);
+    assertEquals(23, c4.y);
+  }
+  
+  
+  function D() {
+    this.x = 23;
+  };
+  D.prototype = 1;
+  if (ensure_fast_case) {
+    %ToFastProperties(D.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var d = new D();
+    assertEquals(23, d.x);
+    assertEquals("undefined", typeof d.y);
+  }
+}
+
+RunTest(false);
+RunTest(true);
diff --git a/test/mjsunit/substr.js b/test/mjsunit/substr.js
old mode 100644
new mode 100755
diff --git a/test/mjsunit/tools/tickprocessor-test-func-info.log b/test/mjsunit/tools/tickprocessor-test-func-info.log
new file mode 100644
index 0000000..29a12f6
--- /dev/null
+++ b/test/mjsunit/tools/tickprocessor-test-func-info.log
@@ -0,0 +1,13 @@
+shared-library,"shell",0x08048000,0x081ee000
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+profiler,"begin",1
+code-creation,Stub,0x424260,348,"CompareStub_GE"
+code-creation,LazyCompile,0x2a8100,18535,"DrawQube 3d-cube.js:188"
+function-creation,0x2d11b8,0x2a8100
+code-creation,LazyCompile,0x480100,3908,"DrawLine 3d-cube.js:17"
+function-creation,0x2d0f7c,0x480100
+tick,0x424284,0xbfffeea0,0x2d0f7c,0,0x2aaaa5
+tick,0x42429f,0xbfffed88,0x2d0f7c,0,0x2aacb4
+tick,0x48063d,0xbfffec7c,0x2d0f7c,0,0x2aaec6
+profiler,"end"
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index f2d1b98..f190598 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -269,7 +269,6 @@
         '../../src/execution.h',
         '../../src/factory.cc',
         '../../src/factory.h',
-        '../../src/fast-codegen.cc',
         '../../src/fast-codegen.h',
         '../../src/flag-definitions.h',
         '../../src/flags.cc',
@@ -308,6 +307,8 @@
         '../../src/jsregexp.h',
         '../../src/list-inl.h',
         '../../src/list.h',
+        '../../src/liveedit.cc',
+        '../../src/liveedit.h',
         '../../src/log-inl.h',
         '../../src/log-utils.cc',
         '../../src/log-utils.h',
@@ -320,6 +321,7 @@
         '../../src/messages.cc',
         '../../src/messages.h',
         '../../src/natives.h',
+	'../../src/number-info.h',
         '../../src/objects-debug.cc',
         '../../src/objects-inl.h',
         '../../src/objects.cc',
@@ -401,6 +403,7 @@
             '../../src/arm',
           ],
           'sources': [
+            '../../src/fast-codegen.cc',
             '../../src/arm/assembler-arm-inl.h',
             '../../src/arm/assembler-arm.cc',
             '../../src/arm/assembler-arm.h',
@@ -452,6 +455,7 @@
             '../../src/ia32/debug-ia32.cc',
             '../../src/ia32/disasm-ia32.cc',
             '../../src/ia32/fast-codegen-ia32.cc',
+            '../../src/ia32/fast-codegen-ia32.h',
             '../../src/ia32/frames-ia32.cc',
             '../../src/ia32/frames-ia32.h',
             '../../src/ia32/full-codegen-ia32.cc',
@@ -472,6 +476,7 @@
             '../../src/x64',
           ],
           'sources': [
+            '../../src/fast-codegen.cc',
             '../../src/x64/assembler-x64-inl.h',
             '../../src/x64/assembler-x64.cc',
             '../../src/x64/assembler-x64.h',
@@ -556,11 +561,11 @@
           '../../src/math.js',
           '../../src/messages.js',
           '../../src/apinatives.js',
-          '../../src/debug-delay.js',
-          '../../src/mirror-delay.js',
-          '../../src/date-delay.js',
-          '../../src/json-delay.js',
-          '../../src/regexp-delay.js',
+          '../../src/debug-debugger.js',
+          '../../src/mirror-debugger.js',
+          '../../src/date.js',
+          '../../src/json.js',
+          '../../src/regexp.js',
           '../../src/macros.py',
         ],
       },
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index 40cee8a..a3e14c3 100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -160,10 +160,6 @@
           processor: this.processHeapSampleEnd },
       'heap-js-prod-item': { parsers: [null, 'var-args'],
           processor: this.processJSProducer, backrefs: true },
-      'PAGE-LOAD-START': { parsers: [null, null],
-          processor: this.processPageLoadStart },
-      'PAGE-LOAD-END': { parsers: [null, null],
-          processor: this.processPageLoadEnd },
       // Ignored events.
       'profiler': null,
       'heap-sample-stats': null,
@@ -180,7 +176,6 @@
   this.stateFilter_ = stateFilter;
   this.snapshotLogProcessor_ = snapshotLogProcessor;
   this.deserializedEntriesNames_ = [];
-  this.handle_ticks_ = false;
   var ticks = this.ticks_ =
     { total: 0, unaccounted: 0, excluded: 0, gc: 0 };
 
@@ -344,7 +339,6 @@
 
 
 TickProcessor.prototype.processTick = function(pc, sp, func, vmState, stack) {
-  if (!this.handle_ticks_) return;
   this.ticks_.total++;
   if (vmState == TickProcessor.VmStates.GC) this.ticks_.gc++;
   if (!this.includeTick(vmState)) {
@@ -392,16 +386,6 @@
 };
 
 
-TickProcessor.prototype.processPageLoadStart = function() {
-  this.handle_ticks_ = true;
-};
-
-
-TickProcessor.prototype.processPageLoadEnd = function() {
-  this.handle_ticks_ = false;
-};
-
-
 TickProcessor.prototype.processJSProducer = function(constructor, stack) {
   if (!this.currentProducerProfile_) return;
   if (stack.length == 0) return;
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index e58e8ff..8593528 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -401,7 +401,7 @@
                                 >
                         </File>
                         <File
-                                RelativePath="..\..\src\fast-codegen.cc"
+                                RelativePath="..\..\src\ia32\fast-codegen-ia32.h"
                                 >
                         </File>
                         <File
@@ -577,6 +577,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\liveedit.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\liveedit.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\log.cc"
 				>
 			</File>
@@ -633,6 +641,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\number-info.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\objects-debug.cc"
 				>
 				<FileConfiguration
diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj
index 4b37b53..2602be4 100644
--- a/tools/visual_studio/v8_base_arm.vcproj
+++ b/tools/visual_studio/v8_base_arm.vcproj
@@ -581,6 +581,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\liveedit.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\liveedit.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\log.cc"
 				>
 			</File>
@@ -637,6 +645,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\number-info.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\objects-debug.cc"
 				>
 				<FileConfiguration
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
index b6d5c7d..d3f55c6 100644
--- a/tools/visual_studio/v8_base_x64.vcproj
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -578,6 +578,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\liveedit.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\liveedit.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\log.cc"
 				>
 			</File>
@@ -634,6 +642,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\number-info.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\objects-debug.cc"
 				>
 				<FileConfiguration