Version 3.21.8

Added scriptId to StackTrace frames (issue 2865).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@16469 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 2922fc3..13d0a22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-09-02: Version 3.21.8
+
+        Added scriptId to StackTrace frames (issue 2865).
+
+        Performance and stability improvements on all platforms.
+
+
 2013-08-30: Version 3.21.7
 
         Fixed casts of eternal handles.
diff --git a/include/v8.h b/include/v8.h
index cfc1de6..13842ba 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1157,6 +1157,7 @@
 
   static const int kNoLineNumberInfo = 0;
   static const int kNoColumnInfo = 0;
+  static const int kNoScriptIdInfo = 0;
 };
 
 
@@ -1179,6 +1180,7 @@
     kIsEval = 1 << 4,
     kIsConstructor = 1 << 5,
     kScriptNameOrSourceURL = 1 << 6,
+    kScriptId = 1 << 7,
     kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
     kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL
   };
@@ -1234,6 +1236,14 @@
   int GetColumn() const;
 
   /**
+   * Returns the id of the script for the function for this StackFrame.
+   * This method will return Message::kNoScriptIdInfo if it is unable to
+   * retrieve the script id, or if kScriptId was not passed as an option when
+   * capturing the StackTrace.
+   */
+  int GetScriptId() const;
+
+  /**
    * Returns the name of the resource that contains the script for the
    * function for this StackFrame.
    */
@@ -5394,7 +5404,7 @@
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 134;
+  static const int kEmptyStringRootIndex = 133;
 
   static const int kNodeClassIdOffset = 1 * kApiPointerSize;
   static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
@@ -5405,7 +5415,7 @@
   static const int kNodeIsIndependentShift = 4;
   static const int kNodeIsPartiallyDependentShift = 5;
 
-  static const int kJSObjectType = 0xb2;
+  static const int kJSObjectType = 0xb1;
   static const int kFirstNonstringType = 0x80;
   static const int kOddballType = 0x83;
   static const int kForeignType = 0x87;
diff --git a/include/v8config.h b/include/v8config.h
index 2bf3b9d..0993a9f 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -28,6 +28,52 @@
 #ifndef V8CONFIG_H_
 #define V8CONFIG_H_
 
+// Platform headers for feature detection below.
+#if defined(__ANDROID__)
+# include <sys/cdefs.h>
+#elif defined(__APPLE__)
+# include <TargetConditionals.h>
+#elif defined(__linux__)
+# include <features.h>
+#endif
+
+
+// This macro allows to test for the version of the GNU C library (or
+// a compatible C library that masquerades as glibc). It evaluates to
+// 0 if libc is not GNU libc or compatible.
+// Use like:
+//  #if V8_GLIBC_PREREQ(2, 3)
+//   ...
+//  #endif
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define V8_GLIBC_PREREQ(major, minor)                                    \
+    ((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
+#else
+# define V8_GLIBC_PREREQ(major, minor) 0
+#endif
+
+
+// This macro allows to test for the version of the GNU C++ compiler.
+// Note that this also applies to compilers that masquerade as GCC,
+// for example clang and the Intel C++ compiler for Linux.
+// Use like:
+//  #if V8_GNUC_PREREQ(4, 3, 1)
+//   ...
+//  #endif
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define V8_GNUC_PREREQ(major, minor, patchlevel)                         \
+    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >=   \
+     ((major) * 10000 + (minor) * 100 + (patchlevel)))
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define V8_GNUC_PREREQ(major, minor, patchlevel)       \
+    ((__GNUC__ * 10000 + __GNUC_MINOR__) >=             \
+     ((major) * 10000 + (minor) * 100 + (patchlevel)))
+#else
+# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
+#endif
+
+
+
 // -----------------------------------------------------------------------------
 // Operating system detection
 //
@@ -87,6 +133,32 @@
 
 
 // -----------------------------------------------------------------------------
+// C library detection
+//
+//  V8_LIBC_BIONIC  - Bionic libc
+//  V8_LIBC_BSD     - BSD libc derivate
+//  V8_LIBC_GLIBC   - GNU C library
+//  V8_LIBC_UCLIBC  - uClibc
+//
+// Note that testing for libc must be done using #if not #ifdef. For example,
+// to test for the GNU C library, use:
+//  #if V8_LIBC_GLIBC
+//   ...
+//  #endif
+
+#if defined(__BIONIC__)
+# define V8_LIBC_BIONIC 1
+# define V8_LIBC_BSD 1
+#elif defined(__UCLIBC__)
+# define V8_LIBC_UCLIBC 1
+#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
+# define V8_LIBC_GLIBC 1
+#else
+# define V8_LIBC_BSD V8_OS_BSD
+#endif
+
+
+// -----------------------------------------------------------------------------
 // Compiler detection
 //
 //  V8_CC_CLANG   - Clang
@@ -134,9 +206,6 @@
 
 #if defined(__clang__)
 
-// Don't treat clang as GCC.
-# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
-
 # define V8_CC_CLANG 1
 
 // Clang defines __alignof__ as alias for __alignof
@@ -161,10 +230,6 @@
 
 #elif defined(__GNUC__)
 
-# define V8_GNUC_PREREQ(major, minor, patchlevel)                         \
-    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >=   \
-     ((major) * 10000 + (minor) * 100 + (patchlevel)))
-
 # define V8_CC_GNU 1
 // Intel C++ also masquerades as GCC 3.2.0
 # define V8_CC_INTEL (defined(__INTEL_COMPILER))
@@ -207,8 +272,6 @@
 
 #elif defined(_MSC_VER)
 
-# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
-
 # define V8_CC_MSVC 1
 
 # define V8_HAS___ALIGNOF 1
diff --git a/src/accessors.cc b/src/accessors.cc
index 45869ea..b87d921 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -51,19 +51,27 @@
 
 
 // Entry point that never should be called.
-MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
+MaybeObject* Accessors::IllegalSetter(Isolate* isolate,
+                                      JSObject*,
+                                      Object*,
+                                      void*) {
   UNREACHABLE();
   return NULL;
 }
 
 
-Object* Accessors::IllegalGetAccessor(Object* object, void*) {
+Object* Accessors::IllegalGetAccessor(Isolate* isolate,
+                                      Object* object,
+                                      void*) {
   UNREACHABLE();
   return object;
 }
 
 
-MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
+MaybeObject* Accessors::ReadOnlySetAccessor(Isolate* isolate,
+                                            JSObject*,
+                                            Object* value,
+                                            void*) {
   // According to ECMA-262, section 8.6.2.2, page 28, setting
   // read-only properties must be silently ignored.
   return value;
@@ -75,29 +83,32 @@
 //
 
 
-MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
+MaybeObject* Accessors::ArrayGetLength(Isolate* isolate,
+                                       Object* object,
+                                       void*) {
   // Traverse the prototype chain until we reach an array.
-  JSArray* holder = FindInstanceOf<JSArray>(Isolate::Current(), object);
+  JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
   return holder == NULL ? Smi::FromInt(0) : holder->length();
 }
 
 
 // The helper function will 'flatten' Number objects.
-Object* Accessors::FlattenNumber(Object* value) {
+Object* Accessors::FlattenNumber(Isolate* isolate, Object* value) {
   if (value->IsNumber() || !value->IsJSValue()) return value;
   JSValue* wrapper = JSValue::cast(value);
-  ASSERT(Isolate::Current()->context()->native_context()->number_function()->
+  ASSERT(wrapper->GetIsolate()->context()->native_context()->number_function()->
       has_initial_map());
-  Map* number_map = Isolate::Current()->context()->native_context()->
+  Map* number_map = isolate->context()->native_context()->
       number_function()->initial_map();
   if (wrapper->map() == number_map) return wrapper->value();
   return value;
 }
 
 
-MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) {
-  Isolate* isolate = object->GetIsolate();
-
+MaybeObject* Accessors::ArraySetLength(Isolate* isolate,
+                                       JSObject* object,
+                                       Object* value,
+                                       void*) {
   // This means one of the object's prototypes is a JSArray and the
   // object does not have a 'length' property.  Calling SetProperty
   // causes an infinite loop.
@@ -106,7 +117,7 @@
         isolate->heap()->length_string(), value, NONE);
   }
 
-  value = FlattenNumber(value);
+  value = FlattenNumber(isolate, value);
 
   // Need to call methods that may trigger GC.
   HandleScope scope(isolate);
@@ -142,7 +153,9 @@
 //
 
 
-MaybeObject* Accessors::StringGetLength(Object* object, void*) {
+MaybeObject* Accessors::StringGetLength(Isolate* isolate,
+                                        Object* object,
+                                        void*) {
   Object* value = object;
   if (object->IsJSValue()) value = JSValue::cast(object)->value();
   if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
@@ -164,7 +177,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetSource(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetSource(Isolate* isolate,
+                                        Object* object,
+                                        void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->source();
 }
@@ -182,7 +197,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetName(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetName(Isolate* isolate,
+                                      Object* object,
+                                      void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->name();
 }
@@ -200,7 +217,7 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetId(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetId(Isolate* isolate, Object* object, void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->id();
 }
@@ -218,7 +235,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetLineOffset(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetLineOffset(Isolate* isolate,
+                                            Object* object,
+                                            void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->line_offset();
 }
@@ -236,7 +255,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetColumnOffset(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetColumnOffset(Isolate* isolate,
+                                              Object* object,
+                                              void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->column_offset();
 }
@@ -254,7 +275,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetData(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetData(Isolate* isolate,
+                                      Object* object,
+                                      void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->data();
 }
@@ -272,7 +295,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetType(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetType(Isolate* isolate,
+                                      Object* object,
+                                      void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->type();
 }
@@ -290,7 +315,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetCompilationType(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetCompilationType(Isolate* isolate,
+                                                 Object* object,
+                                                 void*) {
   Object* script = JSValue::cast(object)->value();
   return Smi::FromInt(Script::cast(script)->compilation_type());
 }
@@ -308,9 +335,10 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetLineEnds(Isolate* isolate,
+                                          Object* object,
+                                          void*) {
   JSValue* wrapper = JSValue::cast(object);
-  Isolate* isolate = wrapper->GetIsolate();
   HandleScope scope(isolate);
   Handle<Script> script(Script::cast(wrapper->value()), isolate);
   InitScriptLineEnds(script);
@@ -337,7 +365,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetContextData(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetContextData(Isolate* isolate,
+                                             Object* object,
+                                             void*) {
   Object* script = JSValue::cast(object)->value();
   return Script::cast(script)->context_data();
 }
@@ -355,7 +385,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromScript(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetEvalFromScript(Isolate* isolate,
+                                                Object* object,
+                                                void*) {
   Object* script = JSValue::cast(object)->value();
   if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
     Handle<SharedFunctionInfo> eval_from_shared(
@@ -382,9 +414,11 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Isolate* isolate,
+                                                        Object* object,
+                                                        void*) {
   Script* raw_script = Script::cast(JSValue::cast(object)->value());
-  HandleScope scope(raw_script->GetIsolate());
+  HandleScope scope(isolate);
   Handle<Script> script(raw_script);
 
   // If this is not a script compiled through eval there is no eval position.
@@ -413,7 +447,9 @@
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Object* object, void*) {
+MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Isolate* isolate,
+                                                      Object* object,
+                                                      void*) {
   Object* script = JSValue::cast(object)->value();
   Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
       Script::cast(script)->eval_from_shared()));
@@ -442,7 +478,9 @@
 
 Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
   CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionGetPrototype(*function, NULL),
+                     Accessors::FunctionGetPrototype(function->GetIsolate(),
+                                                     *function,
+                                                     NULL),
                      Object);
 }
 
@@ -451,15 +489,17 @@
                                                Handle<Object> prototype) {
   ASSERT(function->should_have_prototype());
   CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionSetPrototype(*function,
+                     Accessors::FunctionSetPrototype(function->GetIsolate(),
+                                                     *function,
                                                      *prototype,
                                                      NULL),
                      Object);
 }
 
 
-MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
-  Isolate* isolate = Isolate::Current();
+MaybeObject* Accessors::FunctionGetPrototype(Isolate* isolate,
+                                             Object* object,
+                                             void*) {
   JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
   if (function_raw == NULL) return isolate->heap()->undefined_value();
   while (!function_raw->should_have_prototype()) {
@@ -480,10 +520,10 @@
 }
 
 
-MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
+MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
+                                             JSObject* object,
                                              Object* value_raw,
                                              void*) {
-  Isolate* isolate = object->GetIsolate();
   Heap* heap = isolate->heap();
   JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
   if (function_raw == NULL) return heap->undefined_value();
@@ -534,8 +574,9 @@
 //
 
 
-MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
-  Isolate* isolate = Isolate::Current();
+MaybeObject* Accessors::FunctionGetLength(Isolate* isolate,
+                                          Object* object,
+                                          void*) {
   JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
   if (function == NULL) return Smi::FromInt(0);
   // Check if already compiled.
@@ -565,8 +606,9 @@
 //
 
 
-MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
-  Isolate* isolate = Isolate::Current();
+MaybeObject* Accessors::FunctionGetName(Isolate* isolate,
+                                        Object* object,
+                                        void*) {
   JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
   return holder == NULL
       ? isolate->heap()->undefined_value()
@@ -588,7 +630,9 @@
 
 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
   CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionGetArguments(*function, NULL),
+                     Accessors::FunctionGetArguments(function->GetIsolate(),
+                                                     *function,
+                                                     NULL),
                      Object);
 }
 
@@ -620,8 +664,9 @@
 }
 
 
-MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
-  Isolate* isolate = Isolate::Current();
+MaybeObject* Accessors::FunctionGetArguments(Isolate* isolate,
+                                             Object* object,
+                                             void*) {
   HandleScope scope(isolate);
   JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
   if (holder == NULL) return isolate->heap()->undefined_value();
@@ -743,8 +788,9 @@
 };
 
 
-MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
-  Isolate* isolate = Isolate::Current();
+MaybeObject* Accessors::FunctionGetCaller(Isolate* isolate,
+                                          Object* object,
+                                          void*) {
   HandleScope scope(isolate);
   DisallowHeapAllocation no_allocation;
   JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
@@ -850,15 +896,16 @@
     Handle<String> name,
     int index,
     PropertyAttributes attributes) {
-  Factory* factory = name->GetIsolate()->factory();
+  Isolate* isolate = name->GetIsolate();
+  Factory* factory = isolate->factory();
   Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
   info->set_property_attributes(attributes);
   info->set_all_can_read(true);
   info->set_all_can_write(true);
   info->set_name(*name);
   info->set_data(Smi::FromInt(index));
-  Handle<Object> getter = v8::FromCData(&ModuleGetExport);
-  Handle<Object> setter = v8::FromCData(&ModuleSetExport);
+  Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
+  Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
   info->set_getter(*getter);
   if (!(attributes & ReadOnly)) info->set_setter(*setter);
   return info;
diff --git a/src/accessors.h b/src/accessors.h
index 38368c2..d9a2130 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -88,34 +88,70 @@
 
  private:
   // Accessor functions only used through the descriptor.
-  static MaybeObject* FunctionSetPrototype(JSObject* object, Object*, void*);
-  static MaybeObject* FunctionGetPrototype(Object* object, void*);
-  static MaybeObject* FunctionGetLength(Object* object, void*);
-  static MaybeObject* FunctionGetName(Object* object, void*);
-  static MaybeObject* FunctionGetArguments(Object* object, void*);
-  static MaybeObject* FunctionGetCaller(Object* object, void*);
-  static MaybeObject* ArraySetLength(JSObject* object, Object*, void*);
-  static MaybeObject* ArrayGetLength(Object* object, void*);
-  static MaybeObject* StringGetLength(Object* object, void*);
-  static MaybeObject* ScriptGetName(Object* object, void*);
-  static MaybeObject* ScriptGetId(Object* object, void*);
-  static MaybeObject* ScriptGetSource(Object* object, void*);
-  static MaybeObject* ScriptGetLineOffset(Object* object, void*);
-  static MaybeObject* ScriptGetColumnOffset(Object* object, void*);
-  static MaybeObject* ScriptGetData(Object* object, void*);
-  static MaybeObject* ScriptGetType(Object* object, void*);
-  static MaybeObject* ScriptGetCompilationType(Object* object, void*);
-  static MaybeObject* ScriptGetLineEnds(Object* object, void*);
-  static MaybeObject* ScriptGetContextData(Object* object, void*);
-  static MaybeObject* ScriptGetEvalFromScript(Object* object, void*);
-  static MaybeObject* ScriptGetEvalFromScriptPosition(Object* object, void*);
-  static MaybeObject* ScriptGetEvalFromFunctionName(Object* object, void*);
+  static MaybeObject* FunctionSetPrototype(Isolate* isolate,
+                                           JSObject* object,
+                                           Object*,
+                                           void*);
+  static MaybeObject* FunctionGetPrototype(Isolate* isolate,
+                                           Object* object,
+                                           void*);
+  static MaybeObject* FunctionGetLength(Isolate* isolate,
+                                        Object* object,
+                                        void*);
+  static MaybeObject* FunctionGetName(Isolate* isolate, Object* object, void*);
+  static MaybeObject* FunctionGetArguments(Isolate* isolate,
+                                           Object* object,
+                                           void*);
+  static MaybeObject* FunctionGetCaller(Isolate* isolate,
+                                        Object* object,
+                                        void*);
+  static MaybeObject* ArraySetLength(Isolate* isolate,
+                                     JSObject* object,
+                                     Object*,
+                                     void*);
+  static MaybeObject* ArrayGetLength(Isolate* isolate, Object* object, void*);
+  static MaybeObject* StringGetLength(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetName(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetId(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetSource(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetLineOffset(Isolate* isolate,
+                                          Object* object,
+                                          void*);
+  static MaybeObject* ScriptGetColumnOffset(Isolate* isolate,
+                                            Object* object,
+                                            void*);
+  static MaybeObject* ScriptGetData(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetType(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ScriptGetCompilationType(Isolate* isolate,
+                                               Object* object,
+                                               void*);
+  static MaybeObject* ScriptGetLineEnds(Isolate* isolate,
+                                        Object* object,
+                                        void*);
+  static MaybeObject* ScriptGetContextData(Isolate* isolate,
+                                           Object* object,
+                                           void*);
+  static MaybeObject* ScriptGetEvalFromScript(Isolate* isolate,
+                                              Object* object,
+                                              void*);
+  static MaybeObject* ScriptGetEvalFromScriptPosition(Isolate* isolate,
+                                                      Object* object,
+                                                      void*);
+  static MaybeObject* ScriptGetEvalFromFunctionName(Isolate* isolate,
+                                                    Object* object,
+                                                    void*);
 
   // Helper functions.
-  static Object* FlattenNumber(Object* value);
-  static MaybeObject* IllegalSetter(JSObject*, Object*, void*);
-  static Object* IllegalGetAccessor(Object* object, void*);
-  static MaybeObject* ReadOnlySetAccessor(JSObject*, Object* value, void*);
+  static Object* FlattenNumber(Isolate* isolate, Object* value);
+  static MaybeObject* IllegalSetter(Isolate* isolate,
+                                    JSObject*,
+                                    Object*,
+                                    void*);
+  static Object* IllegalGetAccessor(Isolate* isolate, Object* object, void*);
+  static MaybeObject* ReadOnlySetAccessor(Isolate* isolate,
+                                          JSObject*,
+                                          Object* value,
+                                          void*);
 };
 
 } }  // namespace v8::internal
diff --git a/src/api.cc b/src/api.cc
index 643a5b4..aecb58c 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1264,7 +1264,7 @@
 
 
 #define SET_FIELD_WRAPPED(obj, setter, cdata) do {    \
-    i::Handle<i::Object> foreign = FromCData(cdata);  \
+    i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata);  \
     (obj)->setter(*foreign);                          \
   } while (false)
 
@@ -2356,6 +2356,22 @@
 }
 
 
+int StackFrame::GetScriptId() const {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptId()")) {
+    return Message::kNoScriptIdInfo;
+  }
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::Object> scriptId = GetProperty(self, "scriptId");
+  if (!scriptId->IsSmi()) {
+    return Message::kNoScriptIdInfo;
+  }
+  return i::Smi::cast(*scriptId)->value();
+}
+
+
 Local<String> StackFrame::GetScriptName() const {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
@@ -3600,7 +3616,8 @@
       name, getter, setter, data, settings, attributes, signature);
   if (info.is_null()) return false;
   bool fast = Utils::OpenHandle(obj)->HasFastProperties();
-  i::Handle<i::Object> result = i::SetAccessor(Utils::OpenHandle(obj), info);
+  i::Handle<i::Object> result =
+      i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
   if (result.is_null() || result->IsUndefined()) return false;
   if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
   return true;
@@ -3851,7 +3868,7 @@
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::Handle<i::String> key_string =
       isolate->factory()->InternalizeString(key_obj);
-  self->DeleteHiddenProperty(*key_string);
+  i::JSObject::DeleteHiddenProperty(self, key_string);
   return true;
 }
 
diff --git a/src/api.h b/src/api.h
index 63a29e4..51bc494 100644
--- a/src/api.h
+++ b/src/api.h
@@ -125,8 +125,8 @@
 
 
 template <typename T>
-inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) {
-  v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
+inline v8::internal::Handle<v8::internal::Object> FromCData(
+    v8::internal::Isolate* isolate, T obj) {
   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
   return isolate->factory()->NewForeign(
       reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index c020ab6..d9cc387 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -44,8 +44,8 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  CodeGenerator() {
-    InitializeAstVisitor();
+  explicit CodeGenerator(Isolate* isolate) {
+    InitializeAstVisitor(isolate);
   }
 
   static bool MakeCode(CompilationInfo* info);
diff --git a/src/assembler.h b/src/assembler.h
index b358136..671f813 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -691,7 +691,7 @@
 
   explicit ExternalReference(const SCTableReference& table_ref);
 
-  // Isolate::Current() as an external reference.
+  // Isolate as an external reference.
   static ExternalReference isolate_address(Isolate* isolate);
 
   // One-of-a-kind references. These references are not part of a general
diff --git a/src/ast.cc b/src/ast.cc
index 8734171..b966cc3 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1183,7 +1183,6 @@
 
 Handle<String> Literal::ToString() {
   if (value_->IsString()) return Handle<String>::cast(value_);
-  Factory* factory = Isolate::Current()->factory();
   ASSERT(value_->IsNumber());
   char arr[100];
   Vector<char> buffer(arr, ARRAY_SIZE(arr));
@@ -1195,7 +1194,7 @@
   } else {
     str = DoubleToCString(value_->Number(), buffer);
   }
-  return factory->NewStringFromAscii(CStrVector(str));
+  return isolate_->factory()->NewStringFromAscii(CStrVector(str));
 }
 
 
diff --git a/src/ast.h b/src/ast.h
index bf76cfa..f22c96c 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1381,12 +1381,15 @@
  protected:
   Literal(Isolate* isolate, Handle<Object> value)
       : Expression(isolate),
-        value_(value) { }
+        value_(value),
+        isolate_(isolate) { }
 
  private:
   Handle<String> ToString();
 
   Handle<Object> value_;
+  // TODO(dcarney): remove.  this is only needed for Match and Hash.
+  Isolate* isolate_;
 };
 
 
@@ -2811,8 +2814,8 @@
   }                                                                 \
                                                                     \
 private:                                                            \
-  void InitializeAstVisitor() {                                     \
-    isolate_ = Isolate::Current();                                  \
+  void InitializeAstVisitor(Isolate* isolate) {                     \
+    isolate_ = isolate;                                             \
     stack_overflow_ = false;                                        \
   }                                                                 \
   Isolate* isolate() { return isolate_; }                           \
diff --git a/src/codegen.cc b/src/codegen.cc
index e988810..6ec3751 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -89,12 +89,12 @@
 #ifdef DEBUG
   if (!info->IsStub() && print_source) {
     PrintF("--- Source from AST ---\n%s\n",
-           PrettyPrinter().PrintProgram(info->function()));
+           PrettyPrinter(info->isolate()).PrintProgram(info->function()));
   }
 
   if (!info->IsStub() && print_ast) {
     PrintF("--- AST ---\n%s\n",
-           AstPrinter().PrintProgram(info->function()));
+           AstPrinter(info->isolate()).PrintProgram(info->function()));
   }
 #endif  // DEBUG
 }
diff --git a/src/factory.cc b/src/factory.cc
index 6faa84e..2dddc9f 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1190,13 +1190,6 @@
 }
 
 
-void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
-  CALL_HEAP_FUNCTION_VOID(
-      isolate(),
-      object->SetIdentityHash(hash, ALLOW_CREATION));
-}
-
-
 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
     Handle<String> name,
     int number_of_literals,
@@ -1249,21 +1242,6 @@
 }
 
 
-Handle<OptimizedCodeEntry> Factory::NewOptimizedCodeEntry(
-      Handle<Context> native_context,
-      Handle<JSFunction> function,
-      Handle<Code> code,
-      Handle<FixedArray> literals) {
-  CALL_HEAP_FUNCTION(isolate(),
-                     isolate()->heap()->AllocateOptimizedCodeEntry(
-                         *native_context,
-                         *function,
-                         *code,
-                         *literals),
-                     OptimizedCodeEntry);
-}
-
-
 Handle<String> Factory::NumberToString(Handle<Object> number) {
   CALL_HEAP_FUNCTION(isolate(),
                      isolate()->heap()->NumberToString(*number), String);
diff --git a/src/factory.h b/src/factory.h
index 390329c..e592020 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -346,8 +346,6 @@
   void BecomeJSObject(Handle<JSReceiver> object);
   void BecomeJSFunction(Handle<JSReceiver> object);
 
-  void SetIdentityHash(Handle<JSObject> object, Smi* hash);
-
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Object> prototype);
 
@@ -487,12 +485,6 @@
       Handle<ScopeInfo> scope_info);
   Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
 
-  Handle<OptimizedCodeEntry> NewOptimizedCodeEntry(
-      Handle<Context> native_context,
-      Handle<JSFunction> function,
-      Handle<Code> code,
-      Handle<FixedArray> literals);
-
   Handle<JSMessageObject> NewJSMessageObject(
       Handle<String> type,
       Handle<JSArray> arguments,
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 8846107..f6a36f5 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -415,7 +415,7 @@
                          !Snapshot::HaveASnapshotToStartFrom();
   masm_->set_emit_debug_code(generate_debug_code_);
   masm_->set_predictable_code_size(true);
-  InitializeAstVisitor();
+  InitializeAstVisitor(info_->isolate());
 }
 
 
@@ -830,7 +830,7 @@
   } else {
     // Check if the statement will be breakable without adding a debug break
     // slot.
-    BreakableStatementChecker checker;
+    BreakableStatementChecker checker(isolate());
     checker.Check(stmt);
     // Record the statement position right here if the statement is not
     // breakable. For breakable statements the actual recording of the
@@ -856,7 +856,7 @@
   } else {
     // Check if the expression will be breakable without adding a debug break
     // slot.
-    BreakableStatementChecker checker;
+    BreakableStatementChecker checker(isolate());
     checker.Check(expr);
     // Record a statement position right here if the expression is not
     // breakable. For breakable expressions the actual recording of the
diff --git a/src/full-codegen.h b/src/full-codegen.h
index af63aed..ed2cc17 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -52,8 +52,8 @@
 // debugger to piggybag on.
 class BreakableStatementChecker: public AstVisitor {
  public:
-  BreakableStatementChecker() : is_breakable_(false) {
-    InitializeAstVisitor();
+  explicit BreakableStatementChecker(Isolate* isolate) : is_breakable_(false) {
+    InitializeAstVisitor(isolate);
   }
 
   void Check(Statement* stmt);
diff --git a/src/handles.cc b/src/handles.cc
index 9d47690..1ac77cc 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -309,11 +309,6 @@
 }
 
 
-Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info) {
-  CALL_HEAP_FUNCTION(obj->GetIsolate(), obj->DefineAccessor(*info), Object);
-}
-
-
 // Wrappers for scripts are kept alive and cached in weak global
 // handles referred from foreign objects held by the scripts as long as
 // they are used. When they are not used anymore, the garbage
diff --git a/src/handles.h b/src/handles.h
index 560944c..c3e4dca 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -259,8 +259,6 @@
 
 Handle<JSObject> DeepCopy(Handle<JSObject> obj);
 
-Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info);
-
 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray>,
                                       Handle<JSArray> array);
 
diff --git a/src/heap.cc b/src/heap.cc
index d4425ea..bd0a6f9 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2824,12 +2824,6 @@
   }
   set_shared_function_info_map(Map::cast(obj));
 
-  { MaybeObject* maybe_obj = AllocateMap(OPTIMIZED_CODE_ENTRY_TYPE,
-                                         OptimizedCodeEntry::kAlignedSize);
-    if (!maybe_obj->ToObject(&obj)) return false;
-  }
-  set_optimized_code_entry_map(Map::cast(obj));
-
   { MaybeObject* maybe_obj = AllocateMap(JS_MESSAGE_OBJECT_TYPE,
                                          JSMessageObject::kSize);
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -3657,30 +3651,6 @@
 }
 
 
-MaybeObject* Heap::AllocateOptimizedCodeEntry(
-      Context* native_context,
-      JSFunction* function,
-      Code* code,
-      FixedArray* literals) {
-  OptimizedCodeEntry* entry;
-  MaybeObject* maybe = Allocate(optimized_code_entry_map(), OLD_POINTER_SPACE);
-  if (!maybe->To<OptimizedCodeEntry>(&entry)) return maybe;
-
-  // Set pointer fields.
-  entry->set_native_context(native_context);
-  entry->set_function(function);
-  entry->set_code(code);
-  entry->set_literals(literals);
-
-  // NULL-out link fields.
-  entry->set_next_by_shared_info(NULL, SKIP_WRITE_BARRIER);
-  entry->set_next_by_native_context(NULL, SKIP_WRITE_BARRIER);
-  entry->set_cacheable(false);
-
-  return entry;
-}
-
-
 MaybeObject* Heap::AllocateJSMessageObject(String* type,
                                            JSArray* arguments,
                                            int start_position,
diff --git a/src/heap.h b/src/heap.h
index 14b395f..3bfd618 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -63,7 +63,6 @@
   V(Map, cell_map, CellMap)                                                    \
   V(Map, global_property_cell_map, GlobalPropertyCellMap)                      \
   V(Map, shared_function_info_map, SharedFunctionInfoMap)                      \
-  V(Map, optimized_code_entry_map, OptimizedCodeEntryMap)                      \
   V(Map, meta_map, MetaMap)                                                    \
   V(Map, heap_number_map, HeapNumberMap)                                       \
   V(Map, native_context_map, NativeContextMap)                                 \
@@ -1098,16 +1097,6 @@
   // Please note this does not perform a garbage collection.
   MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name);
 
-  // Allocates a new OptimizedCodeEntry object.
-  // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
-  // failed.
-  // Please note this does not perform a garbage collection.
-  MUST_USE_RESULT MaybeObject* AllocateOptimizedCodeEntry(
-      Context* native_context,
-      JSFunction* function,
-      Code* code,
-      FixedArray* literals);
-
   // Allocates a new JSMessageObject object.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
   // failed.
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index dd42190..0357805 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -947,6 +947,11 @@
     return type().ToStringOrToNumberCanBeObserved(representation());
   }
 
+  MinusZeroMode GetMinusZeroMode() {
+    return CheckFlag(kBailoutOnMinusZero)
+        ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO;
+  }
+
  protected:
   // This function must be overridden for instructions with flag kUseGVN, to
   // compare the non-Operand parts of the instruction.
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index feacefd..0b1fe09 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2040,7 +2040,7 @@
   // constructor for the initial state relies on function_state_ == NULL
   // to know it's the initial state.
   function_state_= &initial_function_state_;
-  InitializeAstVisitor();
+  InitializeAstVisitor(info->isolate());
 }
 
 
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index d6b6dab..551d031 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -183,6 +183,7 @@
 const IntelDoubleRegister double_register_5 = { 5 };
 const IntelDoubleRegister double_register_6 = { 6 };
 const IntelDoubleRegister double_register_7 = { 7 };
+const IntelDoubleRegister no_double_reg = { -1 };
 
 
 struct XMMRegister : IntelDoubleRegister {
@@ -227,6 +228,7 @@
 #define xmm5 (static_cast<const XMMRegister&>(double_register_5))
 #define xmm6 (static_cast<const XMMRegister&>(double_register_6))
 #define xmm7 (static_cast<const XMMRegister&>(double_register_7))
+#define no_xmm_reg (static_cast<const XMMRegister&>(no_double_reg))
 
 
 struct X87Register : IntelDoubleRegister {
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 42b1296..7891dc6 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -658,18 +658,6 @@
 }
 
 
-// Uses SSE2 to convert the heap number in |source| to an integer. Jumps to
-// |conversion_failure| if the heap number did not contain an int32 value.
-// Result is in ecx. Trashes ebx, xmm0, and xmm1.
-static void ConvertHeapNumberToInt32(MacroAssembler* masm,
-                                     Register source,
-                                     Label* conversion_failure) {
-  __ movdbl(xmm0, FieldOperand(source, HeapNumber::kValueOffset));
-  FloatingPointHelper::CheckSSE2OperandIsInt32(
-      masm, conversion_failure, xmm0, ecx, ebx, xmm1);
-}
-
-
 void BinaryOpStub::Initialize() {
   platform_specific_bit_ = CpuFeatures::IsSupported(SSE3);
 }
@@ -2270,16 +2258,7 @@
   __ cmp(ebx, factory->heap_number_map());
   __ j(not_equal, &check_undefined_arg1);
 
-  // Get the untagged integer version of the edx heap number in ecx.
-  if (left_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) {
-    CpuFeatureScope use_sse2(masm, SSE2);
-    ConvertHeapNumberToInt32(masm, edx, conversion_failure);
-  } else {
-    DoubleToIStub stub(edx, ecx, HeapNumber::kValueOffset - kHeapObjectTag,
-                       true);
-    __ call(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
-  }
-  __ mov(edx, ecx);
+  __ TruncateHeapNumberToI(edx, edx);
 
   // Here edx has the untagged integer, eax has a Smi or a heap number.
   __ bind(&load_arg2);
@@ -2308,14 +2287,7 @@
   __ j(not_equal, &check_undefined_arg2);
   // Get the untagged integer version of the eax heap number in ecx.
 
-  if (right_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) {
-    CpuFeatureScope use_sse2(masm, SSE2);
-    ConvertHeapNumberToInt32(masm, eax, conversion_failure);
-  } else {
-    DoubleToIStub stub(eax, ecx, HeapNumber::kValueOffset - kHeapObjectTag,
-                       true);
-    __ call(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
-  }
+  __ TruncateHeapNumberToI(ecx, eax);
 
   __ bind(&done);
   __ mov(eax, edx);
@@ -2542,16 +2514,16 @@
   }
 
   if (exponent_type_ != INTEGER) {
-    Label fast_power;
-    // Detect integer exponents stored as double.
-    __ cvttsd2si(exponent, Operand(double_exponent));
+    Label fast_power, try_arithmetic_simplification;
+    __ DoubleToI(exponent, double_exponent, double_scratch,
+                 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
+    __ jmp(&int_exponent);
+
+    __ bind(&try_arithmetic_simplification);
     // Skip to runtime if possibly NaN (indicated by the indefinite integer).
+    __ cvttsd2si(exponent, Operand(double_exponent));
     __ cmp(exponent, Immediate(0x80000000u));
     __ j(equal, &call_runtime);
-    __ cvtsi2sd(double_scratch, exponent);
-    // Already ruled out NaNs for exponent.
-    __ ucomisd(double_exponent, double_scratch);
-    __ j(equal, &int_exponent);
 
     if (exponent_type_ == ON_STACK) {
       // Detect square root case.  Crankshaft detects constant +/-0.5 at
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 15b0990..75525ed 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -423,6 +423,8 @@
   if (deferred_.length() > 0) {
     for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
       LDeferredCode* code = deferred_[i];
+      X87Stack copy(code->x87_stack());
+      x87_stack_ = copy;
 
       int pos = instructions_->at(code->instruction_index())->position();
       RecordAndUpdatePosition(pos);
@@ -446,6 +448,7 @@
         Comment(";;; Deferred code");
       }
       code->Generate();
+      __ bind(code->done());
       if (NeedsDeferredFrame()) {
         Comment(";;; Destroy frame");
         ASSERT(frame_is_built_);
@@ -503,6 +506,7 @@
 
 
 void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) {
+  ASSERT(is_mutable_);
   ASSERT(Contains(reg) && stack_depth_ > other_slot);
   int i  = ArrayIndex(reg);
   int st = st2idx(i);
@@ -547,6 +551,7 @@
 
 
 void LCodeGen::X87Stack::Free(X87Register reg) {
+  ASSERT(is_mutable_);
   ASSERT(Contains(reg));
   int i  = ArrayIndex(reg);
   int st = st2idx(i);
@@ -606,6 +611,7 @@
 
 
 void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) {
+  ASSERT(is_mutable_);
   if (Contains(reg)) {
     Free(reg);
   }
@@ -615,6 +621,7 @@
 
 
 void LCodeGen::X87Stack::CommitWrite(X87Register reg) {
+  ASSERT(is_mutable_);
   // Assert the reg is prepared to write, but not on the virtual stack yet
   ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) &&
       stack_depth_ < X87Register::kNumAllocatableRegisters);
@@ -2841,8 +2848,9 @@
   class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode {
    public:
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
-                                  LInstanceOfKnownGlobal* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+                                  LInstanceOfKnownGlobal* instr,
+                                  const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
@@ -2854,7 +2862,7 @@
   };
 
   DeferredInstanceOfKnownGlobal* deferred;
-  deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
+  deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr, x87_stack_);
 
   Label done, false_result;
   Register object = ToRegister(instr->value());
@@ -3808,8 +3816,10 @@
   // Class for deferred case.
   class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode {
    public:
-    DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
+                                    LMathAbs* instr,
+                                    const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
@@ -3832,7 +3842,7 @@
     EmitIntegerMathAbs(instr);
   } else {  // Tagged case.
     DeferredMathAbsTaggedHeapNumber* deferred =
-        new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
+        new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_);
     Register input_reg = ToRegister(instr->value());
     // Smi check.
     __ JumpIfNotSmi(input_reg, deferred->entry());
@@ -4048,15 +4058,18 @@
 void LCodeGen::DoRandom(LRandom* instr) {
   class DeferredDoRandom V8_FINAL : public LDeferredCode {
    public:
-    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredDoRandom(LCodeGen* codegen,
+                     LRandom* instr,
+                     const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
     virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
    private:
     LRandom* instr_;
   };
 
-  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
+  DeferredDoRandom* deferred =
+      new(zone()) DeferredDoRandom(this, instr, x87_stack_);
 
   CpuFeatureScope scope(masm(), SSE2);
   // Having marked this instruction as a call we can use any
@@ -4791,8 +4804,10 @@
 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
   class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
    public:
-    DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredStringCharCodeAt(LCodeGen* codegen,
+                             LStringCharCodeAt* instr,
+                             const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredStringCharCodeAt(instr_);
     }
@@ -4802,7 +4817,7 @@
   };
 
   DeferredStringCharCodeAt* deferred =
-      new(zone()) DeferredStringCharCodeAt(this, instr);
+      new(zone()) DeferredStringCharCodeAt(this, instr, x87_stack_);
 
   StringCharLoadGenerator::Generate(masm(),
                                     factory(),
@@ -4848,8 +4863,10 @@
 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
   class DeferredStringCharFromCode V8_FINAL : public LDeferredCode {
    public:
-    DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredStringCharFromCode(LCodeGen* codegen,
+                               LStringCharFromCode* instr,
+                               const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
@@ -4859,7 +4876,7 @@
   };
 
   DeferredStringCharFromCode* deferred =
-      new(zone()) DeferredStringCharFromCode(this, instr);
+      new(zone()) DeferredStringCharFromCode(this, instr, x87_stack_);
 
   ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
   Register char_code = ToRegister(instr->char_code());
@@ -4947,8 +4964,10 @@
 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
   class DeferredNumberTagI V8_FINAL : public LDeferredCode {
    public:
-    DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredNumberTagI(LCodeGen* codegen,
+                       LNumberTagI* instr,
+                       const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32);
     }
@@ -4961,7 +4980,8 @@
   ASSERT(input->IsRegister() && input->Equals(instr->result()));
   Register reg = ToRegister(input);
 
-  DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
+  DeferredNumberTagI* deferred =
+      new(zone()) DeferredNumberTagI(this, instr, x87_stack_);
   __ SmiTag(reg);
   __ j(overflow, deferred->entry());
   __ bind(deferred->exit());
@@ -4971,8 +4991,10 @@
 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
   class DeferredNumberTagU V8_FINAL : public LDeferredCode {
    public:
-    DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredNumberTagU(LCodeGen* codegen,
+                       LNumberTagU* instr,
+                       const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32);
     }
@@ -4985,7 +5007,8 @@
   ASSERT(input->IsRegister() && input->Equals(instr->result()));
   Register reg = ToRegister(input);
 
-  DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
+  DeferredNumberTagU* deferred =
+      new(zone()) DeferredNumberTagU(this, instr, x87_stack_);
   __ cmp(reg, Immediate(Smi::kMaxValue));
   __ j(above, deferred->entry());
   __ SmiTag(reg);
@@ -5074,8 +5097,10 @@
 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
   class DeferredNumberTagD V8_FINAL : public LDeferredCode {
    public:
-    DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredNumberTagD(LCodeGen* codegen,
+                       LNumberTagD* instr,
+                       const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredNumberTagD(instr_);
     }
@@ -5093,7 +5118,8 @@
     X87LoadForUsage(src);
   }
 
-  DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
+  DeferredNumberTagD* deferred =
+      new(zone()) DeferredNumberTagD(this, instr, x87_stack_);
   if (FLAG_inline_new) {
     Register tmp = ToRegister(instr->temp());
     __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
@@ -5281,104 +5307,51 @@
 }
 
 
-void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
-  Label done, heap_number;
+void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
   Register input_reg = ToRegister(instr->value());
 
-  // Heap number map check.
-  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
-         factory()->heap_number_map());
 
   if (instr->truncating()) {
+    Label heap_number, slow_case;
+
+    // Heap number map check.
+    __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
+           factory()->heap_number_map());
     __ j(equal, &heap_number, Label::kNear);
+
     // Check for undefined. Undefined is converted to zero for truncating
     // conversions.
     __ cmp(input_reg, factory()->undefined_value());
     __ RecordComment("Deferred TaggedToI: cannot truncate");
     DeoptimizeIf(not_equal, instr->environment());
     __ mov(input_reg, 0);
-    __ jmp(&done, Label::kNear);
+    __ jmp(done);
 
     __ bind(&heap_number);
-    if (CpuFeatures::IsSupported(SSE3)) {
-      CpuFeatureScope scope(masm(), SSE3);
-      Label convert;
-      // Use more powerful conversion when sse3 is available.
-      // Load x87 register with heap number.
-      __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
-      // Get exponent alone and check for too-big exponent.
-      __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
-      __ and_(input_reg, HeapNumber::kExponentMask);
-      const uint32_t kTooBigExponent =
-          (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
-      __ cmp(Operand(input_reg), Immediate(kTooBigExponent));
-      __ j(less, &convert, Label::kNear);
-      // Pop FPU stack before deoptimizing.
-      __ fstp(0);
-      __ RecordComment("Deferred TaggedToI: exponent too big");
-      DeoptimizeIf(no_condition, instr->environment());
-
-      // Reserve space for 64 bit answer.
-      __ bind(&convert);
-      __ sub(Operand(esp), Immediate(kDoubleSize));
-      // Do conversion, which cannot fail because we checked the exponent.
-      __ fisttp_d(Operand(esp, 0));
-      __ mov(input_reg, Operand(esp, 0));  // Low word of answer is the result.
-      __ add(Operand(esp), Immediate(kDoubleSize));
-    } else if (CpuFeatures::IsSupported(SSE2)) {
-      CpuFeatureScope scope(masm(), SSE2);
-      XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
-      __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
-      __ cvttsd2si(input_reg, Operand(xmm0));
-      __ cmp(input_reg, 0x80000000u);
-      __ j(not_equal, &done);
-      // Check if the input was 0x8000000 (kMinInt).
-      // If no, then we got an overflow and we deoptimize.
-      ExternalReference min_int = ExternalReference::address_of_min_int();
-      __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
-      __ ucomisd(xmm_temp, xmm0);
-      DeoptimizeIf(not_equal, instr->environment());
-      DeoptimizeIf(parity_even, instr->environment());  // NaN.
-    } else {
-      UNREACHABLE();
-    }
-  } else if (CpuFeatures::IsSupported(SSE2)) {
-    CpuFeatureScope scope(masm(), SSE2);
-    // Deoptimize if we don't have a heap number.
-    __ RecordComment("Deferred TaggedToI: not a heap number");
-    DeoptimizeIf(not_equal, instr->environment());
-
-    XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
-    __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
-    __ cvttsd2si(input_reg, Operand(xmm0));
-    __ cvtsi2sd(xmm_temp, Operand(input_reg));
-    __ ucomisd(xmm0, xmm_temp);
-    __ RecordComment("Deferred TaggedToI: lost precision");
-    DeoptimizeIf(not_equal, instr->environment());
-    __ RecordComment("Deferred TaggedToI: NaN");
-    DeoptimizeIf(parity_even, instr->environment());  // NaN.
-    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ test(input_reg, Operand(input_reg));
-      __ j(not_zero, &done);
-      __ movmskpd(input_reg, xmm0);
-      __ and_(input_reg, 1);
-      __ RecordComment("Deferred TaggedToI: minus zero");
-      DeoptimizeIf(not_zero, instr->environment());
-    }
+    __ TruncateHeapNumberToI(input_reg, input_reg);
   } else {
-    UNREACHABLE();
+    Label bailout;
+    XMMRegister scratch = (instr->temp() != NULL)
+        ? ToDoubleRegister(instr->temp())
+        : no_xmm_reg;
+    __ TaggedToI(input_reg, input_reg, scratch,
+                 instr->hydrogen()->GetMinusZeroMode(), &bailout);
+    __ jmp(done);
+    __ bind(&bailout);
+    DeoptimizeIf(no_condition, instr->environment());
   }
-  __ bind(&done);
 }
 
 
 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
   class DeferredTaggedToI V8_FINAL : public LDeferredCode {
    public:
-    DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredTaggedToI(LCodeGen* codegen,
+                      LTaggedToI* instr,
+                      const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_);
+      codegen()->DoDeferredTaggedToI(instr_, done());
     }
     virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
    private:
@@ -5390,7 +5363,8 @@
   Register input_reg = ToRegister(input);
   ASSERT(input_reg.is(ToRegister(instr->result())));
 
-  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
+  DeferredTaggedToI* deferred =
+      new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
 
   __ JumpIfNotSmi(input_reg, deferred->entry());
   __ SmiUntag(input_reg);
@@ -5398,169 +5372,6 @@
 }
 
 
-void LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) {
-  Label done, heap_number;
-  Register result_reg = ToRegister(instr->result());
-  Register input_reg = ToRegister(instr->value());
-
-  // Heap number map check.
-  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
-         factory()->heap_number_map());
-  if (instr->truncating()) {
-    __ j(equal, &heap_number, Label::kNear);
-    // Check for undefined. Undefined is converted to zero for truncating
-    // conversions.
-    __ cmp(input_reg, factory()->undefined_value());
-    __ RecordComment("Deferred TaggedToI: cannot truncate");
-    DeoptimizeIf(not_equal, instr->environment());
-    __ xor_(result_reg, result_reg);
-    __ jmp(&done, Label::kFar);
-    __ bind(&heap_number);
-  } else {
-    // Deoptimize if we don't have a heap number.
-    DeoptimizeIf(not_equal, instr->environment());
-  }
-
-  // Surprisingly, all of this crazy bit manipulation is considerably
-  // faster than using the built-in x86 CPU conversion functions (about 6x).
-  Label right_exponent, adjust_bias, zero_result;
-  Register scratch = ToRegister(instr->scratch());
-  Register scratch2 = ToRegister(instr->scratch2());
-  // Get exponent word.
-  __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset));
-  // Get exponent alone in scratch2.
-  __ mov(scratch2, scratch);
-  __ and_(scratch2, HeapNumber::kExponentMask);
-  __ shr(scratch2, HeapNumber::kExponentShift);
-  if (instr->truncating()) {
-    __ j(zero, &zero_result);
-  } else {
-    __ j(not_zero, &adjust_bias);
-    __ test(scratch, Immediate(HeapNumber::kMantissaMask));
-    DeoptimizeIf(not_zero, instr->environment());
-    __ cmp(FieldOperand(input_reg, HeapNumber::kMantissaOffset), Immediate(0));
-    DeoptimizeIf(not_equal, instr->environment());
-    __ bind(&adjust_bias);
-  }
-  __ sub(scratch2, Immediate(HeapNumber::kExponentBias));
-  if (!instr->truncating()) {
-    DeoptimizeIf(negative, instr->environment());
-  } else {
-    __ j(negative, &zero_result);
-  }
-
-  // Get the second half of the double. For some exponents we don't
-  // actually need this because the bits get shifted out again, but
-  // it's probably slower to test than just to do it.
-  Register scratch3 = ToRegister(instr->scratch3());
-  __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
-  __ xor_(result_reg, result_reg);
-
-  const uint32_t non_int32_exponent = 31;
-  __ cmp(scratch2, Immediate(non_int32_exponent));
-  // If we have a match of the int32 exponent then skip some logic.
-  __ j(equal, &right_exponent, Label::kNear);
-  // If the number doesn't find in an int32, deopt.
-  DeoptimizeIf(greater, instr->environment());
-
-  // Exponent word in scratch, exponent in scratch2.  We know that 0 <= exponent
-  // < 31.
-  __ mov(result_reg, Immediate(31));
-  __ sub(result_reg, scratch2);
-
-  __ bind(&right_exponent);
-
-  // Save off exponent for negative check later.
-  __ mov(scratch2, scratch);
-
-  // Here result_reg is the shift, scratch is the exponent word.
-  // Get the top bits of the mantissa.
-  __ and_(scratch, HeapNumber::kMantissaMask);
-  // Put back the implicit 1.
-  __ or_(scratch, 1 << HeapNumber::kExponentShift);
-  // Shift up the mantissa bits to take up the space the exponent used to
-  // take. We have kExponentShift + 1 significant bits int he low end of the
-  // word.  Shift them to the top bits.
-  const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1;
-  __ shl(scratch, shift_distance);
-  if (!instr->truncating()) {
-    // If not truncating, a non-zero value in the bottom 22 bits means a
-    // non-integral value --> trigger a deopt.
-    __ test(scratch3, Immediate((1 << (32 - shift_distance)) - 1));
-    DeoptimizeIf(not_equal, instr->environment());
-  }
-  // Shift down 22 bits to get the most significant 10 bits or the low
-  // mantissa word.
-  __ shr(scratch3, 32 - shift_distance);
-  __ or_(scratch3, scratch);
-  if (!instr->truncating()) {
-    // If truncating, a non-zero value in the bits that will be shifted away
-    // when adjusting the exponent means rounding --> deopt.
-    __ mov(scratch, 0x1);
-    ASSERT(result_reg.is(ecx));
-    __ shl_cl(scratch);
-    __ dec(scratch);
-    __ test(scratch3, scratch);
-    DeoptimizeIf(not_equal, instr->environment());
-  }
-  // Move down according to the exponent.
-  ASSERT(result_reg.is(ecx));
-  __ shr_cl(scratch3);
-  // Now the unsigned 32-bit answer is in scratch3.  We need to move it to
-  // result_reg and we may need to fix the sign.
-  Label negative_result;
-  __ xor_(result_reg, result_reg);
-  __ cmp(scratch2, result_reg);
-  __ j(less, &negative_result, Label::kNear);
-  __ cmp(scratch3, result_reg);
-  __ mov(result_reg, scratch3);
-  // If the result is > MAX_INT, result doesn't fit in signed 32-bit --> deopt.
-  DeoptimizeIf(less, instr->environment());
-  __ jmp(&done, Label::kNear);
-  __ bind(&zero_result);
-  __ xor_(result_reg, result_reg);
-  __ jmp(&done, Label::kNear);
-  __ bind(&negative_result);
-  __ sub(result_reg, scratch3);
-  if (!instr->truncating()) {
-    // -0.0 triggers a deopt.
-    DeoptimizeIf(zero, instr->environment());
-  }
-  // If the negative subtraction overflows into a positive number, there was an
-  // overflow --> deopt.
-  DeoptimizeIf(positive, instr->environment());
-  __ bind(&done);
-}
-
-
-void LCodeGen::DoTaggedToINoSSE2(LTaggedToINoSSE2* instr) {
-  class DeferredTaggedToINoSSE2 V8_FINAL : public LDeferredCode {
-   public:
-    DeferredTaggedToINoSSE2(LCodeGen* codegen, LTaggedToINoSSE2* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() V8_OVERRIDE {
-      codegen()->DoDeferredTaggedToINoSSE2(instr_);
-    }
-    virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
-   private:
-    LTaggedToINoSSE2* instr_;
-  };
-
-  LOperand* input = instr->value();
-  ASSERT(input->IsRegister());
-  Register input_reg = ToRegister(input);
-  ASSERT(input_reg.is(ToRegister(instr->result())));
-
-  DeferredTaggedToINoSSE2* deferred =
-      new(zone()) DeferredTaggedToINoSSE2(this, instr);
-
-  // Smi check.
-  __ JumpIfNotSmi(input_reg, deferred->entry());
-  __ SmiUntag(input_reg);  // Untag smi.
-  __ bind(deferred->exit());
-}
-
-
 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
   LOperand* input = instr->value();
   ASSERT(input->IsRegister());
@@ -5607,73 +5418,33 @@
   ASSERT(result->IsRegister());
   Register result_reg = ToRegister(result);
 
-  Label done;
-  if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
-    CpuFeatureScope scope(masm(), SSE2);
-
-    XMMRegister input_reg = ToDoubleRegister(input);
-
-    __ cvttsd2si(result_reg, Operand(input_reg));
-
-    if (instr->truncating()) {
-      // Performs a truncating conversion of a floating point number as used by
-      // the JS bitwise operations.
-      Label fast_case_succeeded;
-      __ cmp(result_reg, 0x80000000u);
-      __ j(not_equal, &fast_case_succeeded);
-      __ sub(esp, Immediate(kDoubleSize));
-      __ movdbl(MemOperand(esp, 0), input_reg);
-      DoubleToIStub stub(esp, result_reg, 0, true);
-      __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
-      __ add(esp, Immediate(kDoubleSize));
-      __ bind(&fast_case_succeeded);
+  if (instr->truncating()) {
+    if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+      CpuFeatureScope scope(masm(), SSE2);
+      XMMRegister input_reg = ToDoubleRegister(input);
+      __ TruncateDoubleToI(result_reg, input_reg);
     } else {
-      __ cvtsi2sd(xmm0, Operand(result_reg));
-      __ ucomisd(xmm0, input_reg);
-      DeoptimizeIf(not_equal, instr->environment());
-      DeoptimizeIf(parity_even, instr->environment());  // NaN.
-      if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-        // The integer converted back is equal to the original. We
-        // only have to test if we got -0 as an input.
-        __ test(result_reg, Operand(result_reg));
-        __ j(not_zero, &done, Label::kNear);
-        __ movmskpd(result_reg, input_reg);
-        // Bit 0 contains the sign of the double in input_reg.
-        // If input was positive, we are ok and return 0, otherwise
-        // deoptimize.
-        __ and_(result_reg, 1);
-        DeoptimizeIf(not_zero, instr->environment());
-      }
-      __ bind(&done);
+      X87Register input_reg = ToX87Register(input);
+      X87Fxch(input_reg);
+      __ TruncateX87TOSToI(result_reg);
     }
   } else {
-    X87Register input_reg = ToX87Register(input);
-    __ push(result_reg);
-    X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
-    if (instr->truncating()) {
-      __ pop(result_reg);
+    Label bailout, done;
+    if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+      CpuFeatureScope scope(masm(), SSE2);
+      XMMRegister input_reg = ToDoubleRegister(input);
+       __ DoubleToI(result_reg, input_reg, xmm0,
+           instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
     } else {
+      X87Register input_reg = ToX87Register(input);
       X87Fxch(input_reg);
-      __ fld(0);
-      __ fild_s(Operand(esp, 0));
-      __ pop(result_reg);
-      __ FCmp();
-      DeoptimizeIf(not_equal, instr->environment());
-      DeoptimizeIf(parity_even, instr->environment());  // NaN.
+      __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
+                   &bailout, Label::kNear);
     }
-    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ test(result_reg, Operand(result_reg));
-      __ j(not_zero, &done, Label::kNear);
-      // To check for minus zero, we load the value again as float, and check
-      // if that is still 0.
-      X87Fxch(input_reg);
-      __ push(result_reg);
-      __ fst_s(Operand(esp, 0));
-      __ pop(result_reg);
-      __ test(result_reg, Operand(result_reg));
-      DeoptimizeIf(not_zero, instr->environment());
-      __ bind(&done);
-    }
+    __ jmp(&done, Label::kNear);
+    __ bind(&bailout);
+    DeoptimizeIf(no_condition, instr->environment());
+    __ bind(&done);
   }
 }
 
@@ -5685,55 +5456,23 @@
   ASSERT(result->IsRegister());
   Register result_reg = ToRegister(result);
 
-  Label done;
+  Label bailout, done;
   if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
     CpuFeatureScope scope(masm(), SSE2);
-
     XMMRegister input_reg = ToDoubleRegister(input);
-
-    __ cvttsd2si(result_reg, Operand(input_reg));
-    __ cvtsi2sd(xmm0, Operand(result_reg));
-    __ ucomisd(xmm0, input_reg);
-    DeoptimizeIf(not_equal, instr->environment());
-    DeoptimizeIf(parity_even, instr->environment());  // NaN.
-    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      // The integer converted back is equal to the original. We
-      // only have to test if we got -0 as an input.
-      __ test(result_reg, Operand(result_reg));
-      __ j(not_zero, &done, Label::kNear);
-      __ movmskpd(result_reg, input_reg);
-      // Bit 0 contains the sign of the double in input_reg.
-      // If input was positive, we are ok and return 0, otherwise
-      // deoptimize.
-      __ and_(result_reg, 1);
-      DeoptimizeIf(not_zero, instr->environment());
-      __ bind(&done);
-    }
+    __ DoubleToI(result_reg, input_reg, xmm0,
+        instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
   } else {
     X87Register input_reg = ToX87Register(input);
     X87Fxch(input_reg);
-    __ push(result_reg);
-    X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
-    __ fld(0);
-    __ fild_s(Operand(esp, 0));
-    __ pop(result_reg);
-    __ FCmp();
-    DeoptimizeIf(not_equal, instr->environment());
-    DeoptimizeIf(parity_even, instr->environment());  // NaN.
-
-    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ test(result_reg, Operand(result_reg));
-      __ j(not_zero, &done, Label::kNear);
-      // To check for minus zero, we load the value again as float, and check
-      // if that is still 0.
-      __ push(result_reg);
-      __ fst_s(Operand(esp, 0));
-      __ pop(result_reg);
-      __ test(result_reg, Operand(result_reg));
-      DeoptimizeIf(not_zero, instr->environment());
-      __ bind(&done);
-    }
+    __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
+        &bailout, Label::kNear);
   }
+  __ jmp(&done, Label::kNear);
+  __ bind(&bailout);
+  DeoptimizeIf(no_condition, instr->environment());
+  __ bind(&done);
+
   __ SmiTag(result_reg);
   DeoptimizeIf(overflow, instr->environment());
 }
@@ -5832,8 +5571,11 @@
 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
   class DeferredCheckMaps V8_FINAL : public LDeferredCode {
    public:
-    DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
-        : LDeferredCode(codegen), instr_(instr), object_(object) {
+    DeferredCheckMaps(LCodeGen* codegen,
+                      LCheckMaps* instr,
+                      Register object,
+                      const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
     virtual void Generate() V8_OVERRIDE {
@@ -5857,7 +5599,7 @@
 
   DeferredCheckMaps* deferred = NULL;
   if (instr->hydrogen()->has_migration_target()) {
-    deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
+    deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_);
     __ bind(deferred->check_maps());
   }
 
@@ -6055,8 +5797,10 @@
 void LCodeGen::DoAllocate(LAllocate* instr) {
   class DeferredAllocate V8_FINAL : public LDeferredCode {
    public:
-    DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredAllocate(LCodeGen* codegen,
+                     LAllocate* instr,
+                     const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredAllocate(instr_);
     }
@@ -6066,7 +5810,7 @@
   };
 
   DeferredAllocate* deferred =
-      new(zone()) DeferredAllocate(this, instr);
+      new(zone()) DeferredAllocate(this, instr, x87_stack_);
 
   Register result = ToRegister(instr->result());
   Register temp = ToRegister(instr->temp());
@@ -6406,8 +6150,10 @@
 void LCodeGen::DoStackCheck(LStackCheck* instr) {
   class DeferredStackCheck V8_FINAL : public LDeferredCode {
    public:
-    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
+    DeferredStackCheck(LCodeGen* codegen,
+                       LStackCheck* instr,
+                       const X87Stack& x87_stack)
+        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
       codegen()->DoDeferredStackCheck(instr_);
     }
@@ -6441,7 +6187,7 @@
     ASSERT(instr->hydrogen()->is_backwards_branch());
     // Perform stack overflow check if this goto needs it before jumping.
     DeferredStackCheck* deferred_stack_check =
-        new(zone()) DeferredStackCheck(this, instr);
+        new(zone()) DeferredStackCheck(this, instr, x87_stack_);
     ExternalReference stack_limit =
         ExternalReference::address_of_stack_limit(isolate());
     __ cmp(esp, Operand::StaticVariable(stack_limit));
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index 5a474b6..23b2e48 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -163,8 +163,7 @@
                             LOperand* value,
                             IntegerSignedness signedness);
 
-  void DoDeferredTaggedToI(LTaggedToI* instr);
-  void DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr);
+  void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
   void DoDeferredRandom(LRandom* instr);
@@ -448,10 +447,10 @@
 
   class X87Stack {
    public:
-    explicit X87Stack(MacroAssembler* masm) : stack_depth_(0), masm_(masm) { }
+    explicit X87Stack(MacroAssembler* masm)
+        : stack_depth_(0), is_mutable_(true), masm_(masm) { }
     explicit X87Stack(const X87Stack& other)
-        : stack_depth_(0), masm_(other.masm_) {
-      stack_depth_ = other.stack_depth_;
+        : stack_depth_(other.stack_depth_), is_mutable_(false), masm_(masm()) {
       for (int i = 0; i < stack_depth_; i++) {
         stack_[i] = other.stack_[i];
       }
@@ -470,8 +469,12 @@
     void CommitWrite(X87Register reg);
     void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
     int depth() const { return stack_depth_; }
-    void pop() { stack_depth_--; }
+    void pop() {
+      ASSERT(is_mutable_);
+      stack_depth_--;
+    }
     void push(X87Register reg) {
+      ASSERT(is_mutable_);
       ASSERT(stack_depth_ < X87Register::kNumAllocatableRegisters);
       stack_[stack_depth_] = reg;
       stack_depth_++;
@@ -482,9 +485,11 @@
    private:
     int ArrayIndex(X87Register reg);
     int st2idx(int pos);
+
     X87Register stack_[X87Register::kNumAllocatableRegisters];
     int stack_depth_;
-    MacroAssembler* const masm_;
+    bool is_mutable_;
+    MacroAssembler* masm_;
   };
   X87Stack x87_stack_;
 
@@ -528,10 +533,11 @@
 
 class LDeferredCode : public ZoneObject {
  public:
-  explicit LDeferredCode(LCodeGen* codegen)
+  explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack)
       : codegen_(codegen),
         external_exit_(NULL),
-        instruction_index_(codegen->current_instruction_) {
+        instruction_index_(codegen->current_instruction_),
+        x87_stack_(x87_stack) {
     codegen->AddDeferredCode(this);
   }
 
@@ -542,7 +548,9 @@
   void SetExit(Label* exit) { external_exit_ = exit; }
   Label* entry() { return &entry_; }
   Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
+  Label* done() { return &done_; }
   int instruction_index() const { return instruction_index_; }
+  const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; }
 
  protected:
   LCodeGen* codegen() const { return codegen_; }
@@ -553,7 +561,9 @@
   Label entry_;
   Label exit_;
   Label* external_exit_;
+  Label done_;
   int instruction_index_;
+  LCodeGen::X87Stack x87_stack_;
 };
 
 } }  // namespace v8::internal
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index e6cc719..8d66085 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1944,21 +1944,11 @@
         return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
       } else {
         bool truncating = instr->CanTruncateToInt32();
-        if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
-          LOperand* value = UseRegister(val);
-          LOperand* xmm_temp =
-              (truncating && CpuFeatures::IsSupported(SSE3))
-              ? NULL
-              : FixedTemp(xmm1);
-          LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp);
-          return AssignEnvironment(DefineSameAsFirst(res));
-        } else {
-          LOperand* value = UseFixed(val, ecx);
-          LTaggedToINoSSE2* res =
-              new(zone()) LTaggedToINoSSE2(value, TempRegister(),
-                                           TempRegister(), TempRegister());
-          return AssignEnvironment(DefineFixed(res, ecx));
-        }
+        LOperand* xmm_temp =
+            (CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating)
+                ? FixedTemp(xmm1) : NULL;
+        LTaggedToI* res = new(zone()) LTaggedToI(UseRegister(val), xmm_temp);
+        return AssignEnvironment(DefineSameAsFirst(res));
       }
     }
   } else if (from.IsDouble()) {
@@ -1978,7 +1968,7 @@
     } else {
       ASSERT(to.IsInteger32());
       bool truncating = instr->CanTruncateToInt32();
-      bool needs_temp = truncating && !CpuFeatures::IsSupported(SSE3);
+      bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating;
       LOperand* value = needs_temp ?
           UseTempRegister(instr->value()) : UseRegister(instr->value());
       LOperand* temp = needs_temp ? TempRegister() : NULL;
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index e795926..8b311b7 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -175,7 +175,6 @@
   V(StringCompareAndBranch)                     \
   V(SubI)                                       \
   V(TaggedToI)                                  \
-  V(TaggedToINoSSE2)                            \
   V(ThisFunction)                               \
   V(Throw)                                      \
   V(ToFastProperties)                           \
@@ -2171,31 +2170,6 @@
 };
 
 
-// Truncating conversion from a tagged value to an int32.
-class LTaggedToINoSSE2 V8_FINAL : public LTemplateInstruction<1, 1, 3> {
- public:
-  LTaggedToINoSSE2(LOperand* value,
-                   LOperand* temp1,
-                   LOperand* temp2,
-                   LOperand* temp3) {
-    inputs_[0] = value;
-    temps_[0] = temp1;
-    temps_[1] = temp2;
-    temps_[2] = temp3;
-  }
-
-  LOperand* value() { return inputs_[0]; }
-  LOperand* scratch() { return temps_[0]; }
-  LOperand* scratch2() { return temps_[1]; }
-  LOperand* scratch3() { return temps_[2]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(TaggedToINoSSE2, "tagged-to-i-nosse2")
-  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
-
-  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
-};
-
-
 class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LSmiTag(LOperand* value) {
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index aaacbd9..bd058f8 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -215,6 +215,231 @@
 }
 
 
+void MacroAssembler::SlowTruncateToI(Register result_reg,
+                                     Register input_reg,
+                                     int offset) {
+  DoubleToIStub stub(input_reg, result_reg, offset, true);
+  call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+}
+
+
+void MacroAssembler::TruncateDoubleToI(Register result_reg,
+                                       XMMRegister input_reg) {
+  Label done;
+  cvttsd2si(result_reg, Operand(input_reg));
+  cmp(result_reg, 0x80000000u);
+  j(not_equal, &done, Label::kNear);
+
+  sub(esp, Immediate(kDoubleSize));
+  movdbl(MemOperand(esp, 0), input_reg);
+  SlowTruncateToI(result_reg, esp, 0);
+  add(esp, Immediate(kDoubleSize));
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateX87TOSToI(Register result_reg) {
+  sub(esp, Immediate(kDoubleSize));
+  fst_d(MemOperand(esp, 0));
+  SlowTruncateToI(result_reg, esp, 0);
+  add(esp, Immediate(kDoubleSize));
+}
+
+
+void MacroAssembler::X87TOSToI(Register result_reg,
+                               MinusZeroMode minus_zero_mode,
+                               Label* conversion_failed,
+                               Label::Distance dst) {
+  Label done;
+  sub(esp, Immediate(kPointerSize));
+  fist_s(MemOperand(esp, 0));
+  fld(0);
+  fild_s(MemOperand(esp, 0));
+  pop(result_reg);
+  FCmp();
+  j(not_equal, conversion_failed, dst);
+  j(parity_even, conversion_failed, dst);
+  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+    test(result_reg, Operand(result_reg));
+    j(not_zero, &done, Label::kNear);
+    // To check for minus zero, we load the value again as float, and check
+    // if that is still 0.
+    sub(esp, Immediate(kPointerSize));
+    fst_s(MemOperand(esp, 0));
+    pop(result_reg);
+    test(result_reg, Operand(result_reg));
+    j(not_zero, conversion_failed, dst);
+  }
+  bind(&done);
+}
+
+
+void MacroAssembler::DoubleToI(Register result_reg,
+                               XMMRegister input_reg,
+                               XMMRegister scratch,
+                               MinusZeroMode minus_zero_mode,
+                               Label* conversion_failed,
+                               Label::Distance dst) {
+  ASSERT(!input_reg.is(scratch));
+  Label done;
+  cvttsd2si(result_reg, Operand(input_reg));
+  cvtsi2sd(scratch, Operand(result_reg));
+  ucomisd(scratch, input_reg);
+  j(not_equal, conversion_failed, dst);
+  j(parity_even, conversion_failed, dst);  // NaN.
+  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+    test(result_reg, Operand(result_reg));
+    j(not_zero, &done, Label::kNear);
+    movmskpd(result_reg, input_reg);
+    and_(result_reg, 1);
+    j(not_zero, conversion_failed, dst);
+  }
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
+                                           Register input_reg) {
+  Label done, slow_case;
+
+  if (CpuFeatures::IsSupported(SSE3)) {
+    CpuFeatureScope scope(this, SSE3);
+    Label convert;
+    // Use more powerful conversion when sse3 is available.
+    // Load x87 register with heap number.
+    fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
+    // Get exponent alone and check for too-big exponent.
+    mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
+    and_(result_reg, HeapNumber::kExponentMask);
+    const uint32_t kTooBigExponent =
+        (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
+    cmp(Operand(result_reg), Immediate(kTooBigExponent));
+    j(greater_equal, &slow_case, Label::kNear);
+
+    // Reserve space for 64 bit answer.
+    sub(Operand(esp), Immediate(kDoubleSize));
+    // Do conversion, which cannot fail because we checked the exponent.
+    fisttp_d(Operand(esp, 0));
+    mov(result_reg, Operand(esp, 0));  // Low word of answer is the result.
+    add(Operand(esp), Immediate(kDoubleSize));
+    jmp(&done, Label::kNear);
+
+    // Slow case.
+    bind(&slow_case);
+    if (input_reg.is(result_reg)) {
+      // Input is clobbered. Restore number from fpu stack
+      sub(Operand(esp), Immediate(kDoubleSize));
+      fstp_d(Operand(esp, 0));
+      SlowTruncateToI(result_reg, esp, 0);
+      add(esp, Immediate(kDoubleSize));
+    } else {
+      fstp(0);
+      SlowTruncateToI(result_reg, input_reg);
+    }
+  } else if (CpuFeatures::IsSupported(SSE2)) {
+    CpuFeatureScope scope(this, SSE2);
+    movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+    cvttsd2si(result_reg, Operand(xmm0));
+    cmp(result_reg, 0x80000000u);
+    j(not_equal, &done, Label::kNear);
+    // Check if the input was 0x8000000 (kMinInt).
+    // If no, then we got an overflow and we deoptimize.
+    ExternalReference min_int = ExternalReference::address_of_min_int();
+    ucomisd(xmm0, Operand::StaticVariable(min_int));
+    j(not_equal, &slow_case, Label::kNear);
+    j(parity_even, &slow_case, Label::kNear);  // NaN.
+    jmp(&done, Label::kNear);
+
+    // Slow case.
+    bind(&slow_case);
+    if (input_reg.is(result_reg)) {
+      // Input is clobbered. Restore number from double scratch.
+      sub(esp, Immediate(kDoubleSize));
+      movdbl(MemOperand(esp, 0), xmm0);
+      SlowTruncateToI(result_reg, esp, 0);
+      add(esp, Immediate(kDoubleSize));
+    } else {
+      SlowTruncateToI(result_reg, input_reg);
+    }
+  } else {
+    SlowTruncateToI(result_reg, input_reg);
+  }
+  bind(&done);
+}
+
+
+void MacroAssembler::TaggedToI(Register result_reg,
+                               Register input_reg,
+                               XMMRegister temp,
+                               MinusZeroMode minus_zero_mode,
+                               Label* lost_precision) {
+  Label done;
+  ASSERT(!temp.is(xmm0));
+
+  cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
+      isolate()->factory()->heap_number_map());
+  j(not_equal, lost_precision, Label::kNear);
+
+  if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+    ASSERT(!temp.is(no_xmm_reg));
+    CpuFeatureScope scope(this, SSE2);
+
+    movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+    cvttsd2si(result_reg, Operand(xmm0));
+    cvtsi2sd(temp, Operand(result_reg));
+    ucomisd(xmm0, temp);
+    RecordComment("Deferred TaggedToI: lost precision");
+    j(not_equal, lost_precision, Label::kNear);
+    RecordComment("Deferred TaggedToI: NaN");
+    j(parity_even, lost_precision, Label::kNear);
+    if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+      test(result_reg, Operand(result_reg));
+      j(not_zero, &done, Label::kNear);
+      movmskpd(result_reg, xmm0);
+      and_(result_reg, 1);
+      RecordComment("Deferred TaggedToI: minus zero");
+      j(not_zero, lost_precision, Label::kNear);
+    }
+  } else {
+    // TODO(olivf) Converting a number on the fpu is actually quite slow. We
+    // should first try a fast conversion and then bailout to this slow case.
+    Label lost_precision_pop, zero_check;
+    Label* lost_precision_int = (minus_zero_mode == FAIL_ON_MINUS_ZERO)
+        ? &lost_precision_pop : lost_precision;
+    sub(esp, Immediate(kPointerSize));
+    fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
+    if (minus_zero_mode == FAIL_ON_MINUS_ZERO) fld(0);
+    fist_s(MemOperand(esp, 0));
+    fild_s(MemOperand(esp, 0));
+    FCmp();
+    pop(result_reg);
+    j(not_equal, lost_precision_int, Label::kNear);
+    j(parity_even, lost_precision_int, Label::kNear);  // NaN.
+    if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+      test(result_reg, Operand(result_reg));
+      j(zero, &zero_check, Label::kNear);
+      fstp(0);
+      jmp(&done, Label::kNear);
+      bind(&zero_check);
+      // To check for minus zero, we load the value again as float, and check
+      // if that is still 0.
+      sub(esp, Immediate(kPointerSize));
+      fstp_s(Operand(esp, 0));
+      pop(result_reg);
+      test(result_reg, Operand(result_reg));
+      j(zero, &done, Label::kNear);
+      jmp(lost_precision, Label::kNear);
+
+      bind(&lost_precision_pop);
+      fstp(0);
+      jmp(lost_precision, Label::kNear);
+    }
+  }
+  bind(&done);
+}
+
+
+
 static double kUint32Bias =
     static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
 
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 4d9ebad..e4e4533 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -474,6 +474,21 @@
                           XMMRegister scratch_reg,
                           Register result_reg);
 
+  void SlowTruncateToI(Register result_reg, Register input_reg,
+      int offset = HeapNumber::kValueOffset - kHeapObjectTag);
+
+  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
+  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);
+  void TruncateX87TOSToI(Register result_reg);
+
+  void DoubleToI(Register result_reg, XMMRegister input_reg,
+      XMMRegister scratch, MinusZeroMode minus_zero_mode,
+      Label* conversion_failed, Label::Distance dst = Label::kFar);
+  void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode,
+      Label* conversion_failed, Label::Distance dst = Label::kFar);
+
+  void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
+      MinusZeroMode minus_zero_mode, Label* lost_precision);
 
   // Smi tagging support.
   void SmiTag(Register reg) {
diff --git a/src/isolate.cc b/src/isolate.cc
index d0b6d46..0e7b6d5 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -734,7 +734,9 @@
       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("column"));
   Handle<String> line_key =
       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("lineNumber"));
-  Handle<String> script_key =
+  Handle<String> script_id_key =
+      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptId"));
+  Handle<String> script_name_key =
       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptName"));
   Handle<String> script_name_or_source_url_key =
       factory()->InternalizeOneByteString(
@@ -790,11 +792,20 @@
                 Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE));
       }
 
+      if (options & StackTrace::kScriptId) {
+        Handle<Smi> script_id(script->id(), this);
+        CHECK_NOT_EMPTY_HANDLE(this,
+                               JSObject::SetLocalPropertyIgnoreAttributes(
+                                   stack_frame, script_id_key, script_id,
+                                   NONE));
+      }
+
       if (options & StackTrace::kScriptName) {
         Handle<Object> script_name(script->name(), this);
         CHECK_NOT_EMPTY_HANDLE(this,
                                JSObject::SetLocalPropertyIgnoreAttributes(
-                                   stack_frame, script_key, script_name, NONE));
+                                   stack_frame, script_name_key, script_name,
+                                   NONE));
       }
 
       if (options & StackTrace::kScriptNameOrSourceURL) {
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 8b0fdb2..93f3fde 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -521,6 +521,64 @@
 }
 
 
+void DoubleToIStub::Generate(MacroAssembler* masm) {
+  Label out_of_range, only_low, negate, done;
+  Register input_reg = source();
+  Register result_reg = destination();
+
+  int double_offset = offset();
+  // Account for saved regs if input is sp.
+  if (input_reg.is(sp)) double_offset += 3 * kPointerSize;
+
+  Register scratch =
+      GetRegisterThatIsNotOneOf(input_reg, result_reg);
+  Register scratch2 =
+      GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch);
+  Register scratch3 =
+      GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch2);
+  DoubleRegister double_scratch = kLithiumScratchDouble.low();
+  DoubleRegister double_input = f12;
+
+  __ Push(scratch, scratch2, scratch3);
+
+  __ ldc1(double_input, MemOperand(input_reg, double_offset));
+
+  if (!skip_fastpath()) {
+    // Clear cumulative exception flags and save the FCSR.
+    __ cfc1(scratch2, FCSR);
+    __ ctc1(zero_reg, FCSR);
+    // Try a conversion to a signed integer.
+    __ trunc_w_d(double_scratch, double_input);
+    __ mfc1(result_reg, double_scratch);
+    // Retrieve and restore the FCSR.
+    __ cfc1(scratch, FCSR);
+    __ ctc1(scratch2, FCSR);
+    // Check for overflow and NaNs.
+    __ And(
+        scratch, scratch,
+        kFCSROverflowFlagMask | kFCSRUnderflowFlagMask
+           | kFCSRInvalidOpFlagMask);
+    // If we had no exceptions we are done.
+    __ Branch(&done, eq, scratch, Operand(zero_reg));
+  }
+
+  // Load the double value and perform a manual truncation.
+  Register input_high = scratch2;
+  Register input_low = scratch3;
+  __ Move(input_low, input_high, double_input);
+
+  __ EmitOutOfInt32RangeTruncate(result_reg,
+                                 input_high,
+                                 input_low,
+                                 scratch);
+
+  __ bind(&done);
+
+  __ Pop(scratch, scratch2, scratch3);
+  __ Ret();
+}
+
+
 bool WriteInt32ToHeapNumberStub::IsPregenerated() {
   // These variants are compiled ahead of time.  See next method.
   if (the_int_.is(a1) &&
@@ -1532,12 +1590,12 @@
         __ SmiUntag(a2, right);
       } else {
         // Convert operands to 32-bit integers. Right in a2 and left in a3.
-        __ ConvertNumberToInt32(
+        __ TruncateNumberToI(
             left, a3, heap_number_map,
-            scratch1, scratch2, scratch3, f0, not_numbers);
-        __ ConvertNumberToInt32(
+            scratch1, scratch2, scratch3, not_numbers);
+        __ TruncateNumberToI(
             right, a2, heap_number_map,
-            scratch1, scratch2, scratch3, f0, not_numbers);
+            scratch1, scratch2, scratch3, not_numbers);
       }
       Label result_not_a_smi;
       switch (op) {
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index 221b344..1800178 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -391,7 +391,7 @@
           address_(address),
           scratch0_(scratch0) {
       ASSERT(!AreAliased(scratch0, object, address, no_reg));
-      scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
+      scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
     }
 
     void Save(MacroAssembler* masm) {
@@ -434,19 +434,6 @@
     Register scratch0_;
     Register scratch1_;
 
-    Register GetRegThatIsNotOneOf(Register r1,
-                                  Register r2,
-                                  Register r3) {
-      for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
-        Register candidate = Register::FromAllocationIndex(i);
-        if (candidate.is(r1)) continue;
-        if (candidate.is(r2)) continue;
-        if (candidate.is(r3)) continue;
-        return candidate;
-      }
-      UNREACHABLE();
-      return no_reg;
-    }
     friend class RecordWriteStub;
   };
 
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 240b02c..950df21 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -46,8 +46,8 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  CodeGenerator() {
-    InitializeAstVisitor();
+  explicit CodeGenerator(Isolate* isolate) {
+    InitializeAstVisitor(isolate);
   }
 
   static bool MakeCode(CompilationInfo* info);
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 11aac0b..e7f05a6 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4853,7 +4853,7 @@
   Register scratch1 = scratch0();
   Register scratch2 = ToRegister(instr->temp());
   DoubleRegister double_scratch = double_scratch0();
-  DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
+  DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp2());
 
   ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
   ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
@@ -4868,11 +4868,6 @@
   // of the if.
 
   if (instr->truncating()) {
-    Register scratch3 = ToRegister(instr->temp2());
-    FPURegister single_scratch = double_scratch.low();
-    ASSERT(!scratch3.is(input_reg) &&
-           !scratch3.is(scratch1) &&
-           !scratch3.is(scratch2));
     // Performs a truncating conversion of a floating point number as used by
     // the JS bitwise operations.
     Label heap_number;
@@ -4886,14 +4881,8 @@
     __ Branch(&done);
 
     __ bind(&heap_number);
-    __ ldc1(double_scratch2,
-            FieldMemOperand(input_reg, HeapNumber::kValueOffset));
-    __ EmitECMATruncate(input_reg,
-                        double_scratch2,
-                        single_scratch,
-                        scratch1,
-                        scratch2,
-                        scratch3);
+    __ mov(scratch2, input_reg);
+    __ TruncateHeapNumberToI(input_reg, scratch2);
   } else {
     // Deoptimize if we don't have a heap number.
     DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at));
@@ -4980,20 +4969,12 @@
 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
   Register result_reg = ToRegister(instr->result());
   Register scratch1 = scratch0();
-  Register scratch2 = ToRegister(instr->temp());
   DoubleRegister double_input = ToDoubleRegister(instr->value());
 
   if (instr->truncating()) {
-    Register scratch3 = ToRegister(instr->temp2());
-    FPURegister single_scratch = double_scratch0().low();
-    __ EmitECMATruncate(result_reg,
-                        double_input,
-                        single_scratch,
-                        scratch1,
-                        scratch2,
-                        scratch3);
+    __ TruncateDoubleToI(result_reg, double_input);
   } else {
-    Register except_flag = scratch2;
+    Register except_flag = LCodeGen::scratch1();
 
     __ EmitFPUTruncate(kRoundToMinusInf,
                        result_reg,
@@ -5020,21 +5001,13 @@
 
 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
   Register result_reg = ToRegister(instr->result());
-  Register scratch1 = scratch0();
-  Register scratch2 = ToRegister(instr->temp());
+  Register scratch1 = LCodeGen::scratch0();
   DoubleRegister double_input = ToDoubleRegister(instr->value());
 
   if (instr->truncating()) {
-    Register scratch3 = ToRegister(instr->temp2());
-    FPURegister single_scratch = double_scratch0().low();
-    __ EmitECMATruncate(result_reg,
-                        double_input,
-                        single_scratch,
-                        scratch1,
-                        scratch2,
-                        scratch3);
+    __ TruncateDoubleToI(result_reg, double_input);
   } else {
-    Register except_flag = scratch2;
+    Register except_flag = LCodeGen::scratch1();
 
     __ EmitFPUTruncate(kRoundToMinusInf,
                        result_reg,
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index b8775c3..695a058 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1844,13 +1844,10 @@
       } else {
         value = UseRegister(val);
         LOperand* temp1 = TempRegister();
-        LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
-                                                      : NULL;
-        LOperand* temp3 = FixedTemp(f22);
+        LOperand* temp2 = FixedTemp(f22);
         res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
                                                        temp1,
-                                                       temp2,
-                                                       temp3));
+                                                       temp2));
         res = AssignEnvironment(res);
       }
       return res;
@@ -1870,14 +1867,12 @@
       return AssignPointerMap(result);
     } else if (to.IsSmi()) {
       LOperand* value = UseRegister(instr->value());
-      return AssignEnvironment(DefineAsRegister(new(zone()) LDoubleToSmi(value,
-          TempRegister(), TempRegister())));
+      return AssignEnvironment(
+          DefineAsRegister(new(zone()) LDoubleToSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
       LOperand* value = UseRegister(instr->value());
-      LOperand* temp1 = TempRegister();
-      LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() : NULL;
-      LDoubleToI* res = new(zone()) LDoubleToI(value, temp1, temp2);
+      LDoubleToI* res = new(zone()) LDoubleToI(value);
       return AssignEnvironment(DefineAsRegister(res));
     }
   } else if (from.IsInteger32()) {
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index dfdf63c..584682c 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -2041,17 +2041,13 @@
 };
 
 
-class LDoubleToSmi V8_FINAL : public LTemplateInstruction<1, 1, 2> {
+class LDoubleToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
  public:
-  LDoubleToSmi(LOperand* value, LOperand* temp, LOperand* temp2) {
+  explicit LDoubleToSmi(LOperand* value) {
     inputs_[0] = value;
-    temps_[0] = temp;
-    temps_[1] = temp2;
   }
 
   LOperand* value() { return inputs_[0]; }
-  LOperand* temp() { return temps_[0]; }
-  LOperand* temp2() { return temps_[1]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -2061,17 +2057,13 @@
 
 
 // Sometimes truncating conversion from a tagged value to an int32.
-class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
+class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
  public:
-  LDoubleToI(LOperand* value, LOperand* temp, LOperand* temp2) {
+  explicit LDoubleToI(LOperand* value) {
     inputs_[0] = value;
-    temps_[0] = temp;
-    temps_[1] = temp2;
   }
 
   LOperand* value() { return inputs_[0]; }
-  LOperand* temp() { return temps_[0]; }
-  LOperand* temp2() { return temps_[1]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
@@ -2081,22 +2073,19 @@
 
 
 // Truncating conversion from a tagged value to an int32.
-class LTaggedToI V8_FINAL : public LTemplateInstruction<1, 1, 3> {
+class LTaggedToI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
  public:
   LTaggedToI(LOperand* value,
              LOperand* temp,
-             LOperand* temp2,
-             LOperand* temp3) {
+             LOperand* temp2) {
     inputs_[0] = value;
     temps_[0] = temp;
     temps_[1] = temp2;
-    temps_[2] = temp3;
   }
 
   LOperand* value() { return inputs_[0]; }
   LOperand* temp() { return temps_[0]; }
   LOperand* temp2() { return temps_[1]; }
-  LOperand* temp3() { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 2738900..cd1d38e 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -1498,22 +1498,12 @@
 }
 
 
-void MacroAssembler::EmitECMATruncate(Register result,
-                                      FPURegister double_input,
-                                      FPURegister single_scratch,
-                                      Register scratch,
-                                      Register scratch2,
-                                      Register scratch3) {
-  ASSERT(!scratch2.is(result));
-  ASSERT(!scratch3.is(result));
-  ASSERT(!scratch3.is(scratch2));
-  ASSERT(!scratch.is(result) &&
-         !scratch.is(scratch2) &&
-         !scratch.is(scratch3));
-  ASSERT(!single_scratch.is(double_input));
-
-  Label done;
-  Label manual;
+void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
+                                                DoubleRegister double_input,
+                                                Label* done) {
+  DoubleRegister single_scratch = kLithiumScratchDouble.low();
+  Register scratch = at;
+  Register scratch2 = t9;
 
   // Clear cumulative exception flags and save the FCSR.
   cfc1(scratch2, FCSR);
@@ -1529,16 +1519,83 @@
       scratch,
       kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask);
   // If we had no exceptions we are done.
-  Branch(&done, eq, scratch, Operand(zero_reg));
+  Branch(done, eq, scratch, Operand(zero_reg));
+}
 
-  // Load the double value and perform a manual truncation.
-  Register input_high = scratch2;
-  Register input_low = scratch3;
-  Move(input_low, input_high, double_input);
+
+void MacroAssembler::TruncateDoubleToI(Register result,
+                                       DoubleRegister double_input) {
+  Label done;
+
+  TryInlineTruncateDoubleToI(result, double_input, &done);
+
+  // If we fell through then inline version didn't succeed - call stub instead.
+  push(ra);
+  Subu(sp, sp, Operand(kDoubleSize));  // Put input on stack.
+  sdc1(double_input, MemOperand(sp, 0));
+
+  DoubleToIStub stub(sp, result, 0, true, true);
+  CallStub(&stub);
+
+  Addu(sp, sp, Operand(kDoubleSize));
+  pop(ra);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateHeapNumberToI(Register result, Register object) {
+  Label done;
+  DoubleRegister double_scratch = f12;
+  ASSERT(!result.is(object));
+
+  ldc1(double_scratch,
+       MemOperand(object, HeapNumber::kValueOffset - kHeapObjectTag));
+  TryInlineTruncateDoubleToI(result, double_scratch, &done);
+
+  // If we fell through then inline version didn't succeed - call stub instead.
+  push(ra);
+  DoubleToIStub stub(object,
+                     result,
+                     HeapNumber::kValueOffset - kHeapObjectTag,
+                     true,
+                     true);
+  CallStub(&stub);
+  pop(ra);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateNumberToI(Register object,
+                                       Register result,
+                                       Register heap_number_map,
+                                       Register scratch1,
+                                       Register scratch2,
+                                       Register scratch3,
+                                       Label* not_number) {
+  Label done;
+  Label not_in_int32_range;
+  DoubleRegister double_scratch = f12;
+
+  UntagAndJumpIfSmi(result, object, &done);
+  JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
+  ConvertToInt32(object,
+                 result,
+                 scratch1,
+                 scratch2,
+                 double_scratch,
+                 &not_in_int32_range);
+  jmp(&done);
+
+  bind(&not_in_int32_range);
+  lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
+  lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
   EmitOutOfInt32RangeTruncate(result,
-                              input_high,
-                              input_low,
-                              scratch);
+                              scratch1,
+                              scratch2,
+                              scratch3);
+
   bind(&done);
 }
 
@@ -4577,40 +4634,6 @@
 }
 
 
-void MacroAssembler::ConvertNumberToInt32(Register object,
-                                          Register dst,
-                                          Register heap_number_map,
-                                          Register scratch1,
-                                          Register scratch2,
-                                          Register scratch3,
-                                          FPURegister double_scratch,
-                                          Label* not_number) {
-  Label done;
-  Label not_in_int32_range;
-
-  UntagAndJumpIfSmi(dst, object, &done);
-  JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
-  ConvertToInt32(object,
-                 dst,
-                 scratch1,
-                 scratch2,
-                 double_scratch,
-                 &not_in_int32_range);
-  jmp(&done);
-
-  bind(&not_in_int32_range);
-  lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
-  lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
-
-  EmitOutOfInt32RangeTruncate(dst,
-                              scratch1,
-                              scratch2,
-                              scratch3);
-
-  bind(&done);
-}
-
-
 void MacroAssembler::LoadNumber(Register object,
                                 FPURegister dst,
                                 Register heap_number_map,
@@ -5642,6 +5665,30 @@
 }
 
 
+Register GetRegisterThatIsNotOneOf(Register reg1,
+                                   Register reg2,
+                                   Register reg3,
+                                   Register reg4,
+                                   Register reg5,
+                                   Register reg6) {
+  RegList regs = 0;
+  if (reg1.is_valid()) regs |= reg1.bit();
+  if (reg2.is_valid()) regs |= reg2.bit();
+  if (reg3.is_valid()) regs |= reg3.bit();
+  if (reg4.is_valid()) regs |= reg4.bit();
+  if (reg5.is_valid()) regs |= reg5.bit();
+  if (reg6.is_valid()) regs |= reg6.bit();
+
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
+    if (regs & candidate.bit()) continue;
+    return candidate;
+  }
+  UNREACHABLE();
+  return no_reg;
+}
+
+
 bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
   if (r1.is(r2)) return true;
   if (r1.is(r3)) return true;
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 26bed68..8f0b3b1 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -90,6 +90,13 @@
 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
 enum RAStatus { kRAHasNotBeenSaved, kRAHasBeenSaved };
 
+Register GetRegisterThatIsNotOneOf(Register reg1,
+                                   Register reg2 = no_reg,
+                                   Register reg3 = no_reg,
+                                   Register reg4 = no_reg,
+                                   Register reg5 = no_reg,
+                                   Register reg6 = no_reg);
+
 bool AreAliased(Register r1, Register r2, Register r3, Register r4);
 
 
@@ -788,26 +795,36 @@
                                    Register scratch);
 
   // Performs a truncating conversion of a floating point number as used by
+  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
+  // succeeds, otherwise falls through if result is saturated. On return
+  // 'result' either holds answer, or is clobbered on fall through.
+  //
+  // Only public for the test code in test-code-stubs-arm.cc.
+  void TryInlineTruncateDoubleToI(Register result,
+                                  DoubleRegister input,
+                                  Label* done);
+
+  // Performs a truncating conversion of a floating point number as used by
   // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
-  // Exits with 'result' holding the answer and all other registers clobbered.
-  void EmitECMATruncate(Register result,
-                        FPURegister double_input,
-                        FPURegister single_scratch,
-                        Register scratch,
-                        Register scratch2,
-                        Register scratch3);
+  // Exits with 'result' holding the answer.
+  void TruncateDoubleToI(Register result, DoubleRegister double_input);
+
+  // Performs a truncating conversion of a heap number as used by
+  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 'result' and 'input'
+  // must be different registers. Exits with 'result' holding the answer.
+  void TruncateHeapNumberToI(Register result, Register object);
 
   // Converts the smi or heap number in object to an int32 using the rules
   // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
-  // and brought into the range -2^31 .. +2^31 - 1.
-  void ConvertNumberToInt32(Register object,
-                            Register dst,
-                            Register heap_number_map,
-                            Register scratch1,
-                            Register scratch2,
-                            Register scratch3,
-                            FPURegister double_scratch,
-                            Label* not_int32);
+  // and brought into the range -2^31 .. +2^31 - 1. 'result' and 'input' must be
+  // different registers.
+  void TruncateNumberToI(Register object,
+                         Register result,
+                         Register heap_number_map,
+                         Register scratch1,
+                         Register scratch2,
+                         Register scratch3,
+                         Label* not_int32);
 
   // Loads the number from object into dst register.
   // If |object| is neither smi nor heap number, |not_number| is jumped to
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 4ba70c3..a61eacf 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -201,9 +201,6 @@
     case SHARED_FUNCTION_INFO_TYPE:
       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
       break;
-    case OPTIMIZED_CODE_ENTRY_TYPE:
-      OptimizedCodeEntry::cast(this)->OptimizedCodeEntryVerify();
-      break;
     case JS_MESSAGE_OBJECT_TYPE:
       JSMessageObject::cast(this)->JSMessageObjectVerify();
       break;
@@ -580,17 +577,6 @@
 }
 
 
-void OptimizedCodeEntry::OptimizedCodeEntryVerify() {
-  CHECK(IsOptimizedCodeEntry());
-  VerifyObjectField(kNativeContextOffset);
-  VerifyObjectField(kFunctionOffset);
-  VerifyObjectField(kCodeOffset);
-  VerifyObjectField(kLiteralsOffset);
-  VerifyObjectField(kNextBySharedInfoOffset);
-  VerifyObjectField(kNextByNativeContextOffset);
-}
-
-
 void JSGlobalProxy::JSGlobalProxyVerify() {
   CHECK(IsJSGlobalProxy());
   JSObjectVerify();
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 77b4e38..f629d9f 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -675,7 +675,6 @@
 TYPE_CHECKER(Cell, CELL_TYPE)
 TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
-TYPE_CHECKER(OptimizedCodeEntry, OPTIMIZED_CODE_ENTRY_TYPE)
 TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
 TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
 TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
@@ -2573,7 +2572,6 @@
 CAST_ACCESSOR(Cell)
 CAST_ACCESSOR(PropertyCell)
 CAST_ACCESSOR(SharedFunctionInfo)
-CAST_ACCESSOR(OptimizedCodeEntry)
 CAST_ACCESSOR(Map)
 CAST_ACCESSOR(JSFunction)
 CAST_ACCESSOR(GlobalObject)
@@ -4926,52 +4924,6 @@
 }
 
 
-ACCESSORS(OptimizedCodeEntry, native_context, Context, kNativeContextOffset)
-ACCESSORS(OptimizedCodeEntry, function, JSFunction, kFunctionOffset)
-ACCESSORS(OptimizedCodeEntry, code, Code, kCodeOffset)
-ACCESSORS(OptimizedCodeEntry, literals, FixedArray, kLiteralsOffset)
-
-
-OptimizedCodeEntry* OptimizedCodeEntry::next_by_shared_info() {
-  Object* object = READ_FIELD(this, kNextBySharedInfoOffset);
-  if (object == NULL) return NULL;
-  return OptimizedCodeEntry::cast(object);
-}
-
-
-OptimizedCodeEntry* OptimizedCodeEntry::next_by_native_context() {
-  Object* object = READ_FIELD(this, kNextByNativeContextOffset);
-  if (object == NULL) return NULL;
-  return OptimizedCodeEntry::cast(object);
-}
-
-
-void OptimizedCodeEntry::set_next_by_shared_info(OptimizedCodeEntry* value,
-    WriteBarrierMode mode) {
-  WRITE_FIELD(this, kNextBySharedInfoOffset, value);
-  CONDITIONAL_WRITE_BARRIER(
-      GetHeap(), this, kNextBySharedInfoOffset, value, mode);
-}
-
-
-void OptimizedCodeEntry::set_next_by_native_context(OptimizedCodeEntry* value,
-    WriteBarrierMode mode) {
-  WRITE_FIELD(this, kNextByNativeContextOffset, value);
-  CONDITIONAL_WRITE_BARRIER(
-      GetHeap(), this, kNextByNativeContextOffset, value, mode);
-}
-
-
-bool OptimizedCodeEntry::cacheable() {
-  return static_cast<bool>(READ_BYTE_FIELD(this, kCacheableOffset));
-}
-
-
-void OptimizedCodeEntry::set_cacheable(bool val) {
-  WRITE_BYTE_FIELD(this, kCacheableOffset, static_cast<byte>(val));
-}
-
-
 bool JSFunction::IsBuiltin() {
   return context()->global_object()->IsJSBuiltinsObject();
 }
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index dd6cd2c..9ea060f 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -195,9 +195,6 @@
     case SHARED_FUNCTION_INFO_TYPE:
       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out);
       break;
-    case OPTIMIZED_CODE_ENTRY_TYPE:
-      OptimizedCodeEntry::cast(this)->OptimizedCodeEntryPrint(out);
-      break;
     case JS_MESSAGE_OBJECT_TYPE:
       JSMessageObject::cast(this)->JSMessageObjectPrint(out);
       break;
@@ -893,25 +890,6 @@
 }
 
 
-void OptimizedCodeEntry::OptimizedCodeEntryPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "OptimizedCodeEntry");
-  PrintF(out, "\n - native_context = ");
-  native_context()->ShortPrint(out);
-  PrintF(out, "\n - function = ");
-  function()->ShortPrint(out);
-  PrintF(out, "\n - code = ");
-  code()->ShortPrint(out);
-  PrintF(out, "\n - literals = ");
-  literals()->ShortPrint(out);
-  PrintF(out, "\n - next_by_shared_info = ");
-  next_by_shared_info()->ShortPrint(out);
-  PrintF(out, "\n - next_by_native_context = ");
-  next_by_native_context()->ShortPrint(out);
-  PrintF(out, "\n - cacheable = %s", cacheable() ? "true" : "false");
-  PrintF(out, "\n");
-}
-
-
 void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
   PrintF(out, "global_proxy ");
   JSObjectPrint(out);
diff --git a/src/objects-visiting.cc b/src/objects-visiting.cc
index ece8b35..cd46013 100644
--- a/src/objects-visiting.cc
+++ b/src/objects-visiting.cc
@@ -119,9 +119,6 @@
     case SHARED_FUNCTION_INFO_TYPE:
       return kVisitSharedFunctionInfo;
 
-    case OPTIMIZED_CODE_ENTRY_TYPE:
-      return kVisitOptimizedCodeEntry;
-
     case JS_PROXY_TYPE:
       return GetVisitorIdForSize(kVisitStruct,
                                  kVisitStructGeneric,
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index 44ad8e9..2175737 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -92,7 +92,6 @@
   V(Cell)                     \
   V(PropertyCell)             \
   V(SharedFunctionInfo)       \
-  V(OptimizedCodeEntry)       \
   V(JSFunction)               \
   V(JSWeakMap)                \
   V(JSWeakSet)                \
diff --git a/src/objects.cc b/src/objects.cc
index 8cf74ad..2183fb4 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -341,7 +341,7 @@
     AccessorDescriptor* callback =
         reinterpret_cast<AccessorDescriptor*>(
             Foreign::cast(structure)->foreign_address());
-    MaybeObject* value = (callback->getter)(receiver, callback->data);
+    MaybeObject* value = (callback->getter)(isolate, receiver, callback->data);
     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
     return value;
   }
@@ -452,14 +452,17 @@
 }
 
 
-MaybeObject* JSProxy::SetElementWithHandler(JSReceiver* receiver,
-                                            uint32_t index,
-                                            Object* value,
-                                            StrictModeFlag strict_mode) {
-  String* name;
-  MaybeObject* maybe = GetHeap()->Uint32ToString(index);
-  if (!maybe->To<String>(&name)) return maybe;
-  return SetPropertyWithHandler(receiver, name, value, NONE, strict_mode);
+Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
+                                              Handle<JSReceiver> receiver,
+                                              uint32_t index,
+                                              Handle<Object> value,
+                                              StrictModeFlag strict_mode) {
+  Isolate* isolate = proxy->GetIsolate();
+  Handle<String> name = isolate->factory()->Uint32ToString(index);
+  CALL_HEAP_FUNCTION(isolate,
+                     proxy->SetPropertyWithHandler(
+                         *receiver, *name, *value, NONE, strict_mode),
+                     Object);
 }
 
 
@@ -1787,10 +1790,6 @@
       SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
       break;
     }
-    case OPTIMIZED_CODE_ENTRY_TYPE: {
-      OptimizedCodeEntry::BodyDescriptor::IterateBody(this, v);
-      break;
-    }
 
 #define MAKE_STRUCT_CASE(NAME, Name, name) \
         case NAME##_TYPE:
@@ -2829,7 +2828,8 @@
     AccessorDescriptor* callback =
         reinterpret_cast<AccessorDescriptor*>(
             Foreign::cast(structure)->foreign_address());
-    MaybeObject* obj = (callback->setter)(this,  value, callback->data);
+    MaybeObject* obj = (callback->setter)(
+        isolate, this,  value, callback->data);
     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
     if (obj->IsFailure()) return obj;
     return *value_handle;
@@ -3541,20 +3541,20 @@
 
 
 Handle<Object> JSProxy::DeletePropertyWithHandler(
-    Handle<JSProxy> object, Handle<Name> name, DeleteMode mode) {
-  Isolate* isolate = object->GetIsolate();
+    Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
+  Isolate* isolate = proxy->GetIsolate();
 
   // TODO(rossberg): adjust once there is a story for symbols vs proxies.
   if (name->IsSymbol()) return isolate->factory()->false_value();
 
   Handle<Object> args[] = { name };
-  Handle<Object> result = object->CallTrap(
+  Handle<Object> result = proxy->CallTrap(
       "delete", Handle<Object>(), ARRAY_SIZE(args), args);
   if (isolate->has_pending_exception()) return Handle<Object>();
 
   bool result_bool = result->BooleanValue();
   if (mode == STRICT_DELETION && !result_bool) {
-    Handle<Object> handler(object->handler(), isolate);
+    Handle<Object> handler(proxy->handler(), isolate);
     Handle<String> trap_name = isolate->factory()->InternalizeOneByteString(
         STATIC_ASCII_VECTOR("delete"));
     Handle<Object> args[] = { handler, trap_name };
@@ -3568,10 +3568,10 @@
 
 
 Handle<Object> JSProxy::DeleteElementWithHandler(
-    Handle<JSProxy> object, uint32_t index, DeleteMode mode) {
-  Isolate* isolate = object->GetIsolate();
+    Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) {
+  Isolate* isolate = proxy->GetIsolate();
   Handle<String> name = isolate->factory()->Uint32ToString(index);
-  return JSProxy::DeletePropertyWithHandler(object, name, mode);
+  return JSProxy::DeletePropertyWithHandler(proxy, name, mode);
 }
 
 
@@ -3653,27 +3653,23 @@
 }
 
 
-void JSProxy::Fix() {
-  Isolate* isolate = GetIsolate();
-  HandleScope scope(isolate);
-  Handle<JSProxy> self(this);
+void JSProxy::Fix(Handle<JSProxy> proxy) {
+  Isolate* isolate = proxy->GetIsolate();
 
   // Save identity hash.
-  MaybeObject* maybe_hash = GetIdentityHash(OMIT_CREATION);
+  Handle<Object> hash = JSProxy::GetIdentityHash(proxy, OMIT_CREATION);
 
-  if (IsJSFunctionProxy()) {
-    isolate->factory()->BecomeJSFunction(self);
+  if (proxy->IsJSFunctionProxy()) {
+    isolate->factory()->BecomeJSFunction(proxy);
     // Code will be set on the JavaScript side.
   } else {
-    isolate->factory()->BecomeJSObject(self);
+    isolate->factory()->BecomeJSObject(proxy);
   }
-  ASSERT(self->IsJSObject());
+  ASSERT(proxy->IsJSObject());
 
   // Inherit identity, if it was present.
-  Object* hash;
-  if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) {
-    Handle<JSObject> new_self(JSObject::cast(*self));
-    isolate->factory()->SetIdentityHash(new_self, Smi::cast(hash));
+  if (hash->IsSmi()) {
+    JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), Smi::cast(*hash));
   }
 }
 
@@ -4716,17 +4712,16 @@
 }
 
 
-MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) {
-  MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_string(),
-                                         hash);
-  if (maybe->IsFailure()) return maybe;
-  return this;
+void JSObject::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
+  CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
+                          object->SetHiddenProperty(
+                              object->GetHeap()->identity_hash_string(), hash));
 }
 
 
-int JSObject::GetIdentityHash(Handle<JSObject> obj) {
-  CALL_AND_RETRY_OR_DIE(obj->GetIsolate(),
-                        obj->GetIdentityHash(ALLOW_CREATION),
+int JSObject::GetIdentityHash(Handle<JSObject> object) {
+  CALL_AND_RETRY_OR_DIE(object->GetIsolate(),
+                        object->GetIdentityHash(ALLOW_CREATION),
                         return Smi::cast(__object__)->value(),
                         return 0);
 }
@@ -4751,6 +4746,12 @@
 }
 
 
+Handle<Object> JSProxy::GetIdentityHash(Handle<JSProxy> proxy,
+                                        CreationFlag flag) {
+  CALL_HEAP_FUNCTION(proxy->GetIsolate(), proxy->GetIdentityHash(flag), Object);
+}
+
+
 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) {
   Object* hash = this->hash();
   if (!hash->IsSmi() && flag == ALLOW_CREATION) {
@@ -4843,30 +4844,27 @@
 }
 
 
-void JSObject::DeleteHiddenProperty(Name* key) {
+void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
+  Isolate* isolate = object->GetIsolate();
   ASSERT(key->IsUniqueName());
-  if (IsJSGlobalProxy()) {
-    // For a proxy, use the prototype as target object.
-    Object* proxy_parent = GetPrototype();
-    // If the proxy is detached, return immediately.
-    if (proxy_parent->IsNull()) return;
-    ASSERT(proxy_parent->IsJSGlobalObject());
-    JSObject::cast(proxy_parent)->DeleteHiddenProperty(key);
-    return;
+
+  if (object->IsJSGlobalProxy()) {
+    Handle<Object> proto(object->GetPrototype(), isolate);
+    if (proto->IsNull()) return;
+    ASSERT(proto->IsJSGlobalObject());
+    return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key);
   }
-  ASSERT(!IsJSGlobalProxy());
+
   MaybeObject* hidden_lookup =
-      GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
+      object->GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
   Object* inline_value = hidden_lookup->ToObjectUnchecked();
 
   // We never delete (inline-stored) identity hashes.
-  ASSERT(key != GetHeap()->identity_hash_string());
+  ASSERT(*key != isolate->heap()->identity_hash_string());
   if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
 
-  ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
-  MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value());
-  USE(delete_result);
-  ASSERT(!delete_result->IsFailure());  // Delete does not cause GC.
+  Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
+  PutIntoObjectHashTable(hashtable, key, isolate->factory()->the_hole_value());
 }
 
 
@@ -5968,8 +5966,7 @@
   accessors->SetComponents(*getter, *setter);
   accessors->set_access_flags(access_control);
 
-  CALL_HEAP_FUNCTION_VOID(
-      isolate, object->SetElementCallback(index, *accessors, attributes));
+  SetElementCallback(object, index, accessors, attributes);
 }
 
 
@@ -6018,9 +6015,7 @@
   accessors->SetComponents(*getter, *setter);
   accessors->set_access_flags(access_control);
 
-  CALL_HEAP_FUNCTION_VOID(
-      object->GetIsolate(),
-      object->SetPropertyCallback(*name, *accessors, attributes));
+  SetPropertyCallback(object, name, accessors, attributes);
 }
 
 
@@ -6049,72 +6044,64 @@
 }
 
 
-MaybeObject* JSObject::SetElementCallback(uint32_t index,
-                                          Object* structure,
-                                          PropertyAttributes attributes) {
+void JSObject::SetElementCallback(Handle<JSObject> object,
+                                  uint32_t index,
+                                  Handle<Object> structure,
+                                  PropertyAttributes attributes) {
+  Heap* heap = object->GetHeap();
   PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
 
   // Normalize elements to make this operation simple.
-  SeededNumberDictionary* dictionary;
-  { MaybeObject* maybe_dictionary = NormalizeElements();
-    if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
-  }
-  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
+  Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
+  ASSERT(object->HasDictionaryElements() ||
+         object->HasDictionaryArgumentsElements());
 
   // Update the dictionary with the new CALLBACKS property.
-  { MaybeObject* maybe_dictionary = dictionary->Set(index, structure, details);
-    if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
-  }
-
+  dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
+                                           details);
   dictionary->set_requires_slow_elements();
+
   // Update the dictionary backing store on the object.
-  if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
+  if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
     // Also delete any parameter alias.
     //
     // TODO(kmillikin): when deleting the last parameter alias we could
     // switch to a direct backing store without the parameter map.  This
     // would allow GC of the context.
-    FixedArray* parameter_map = FixedArray::cast(elements());
+    FixedArray* parameter_map = FixedArray::cast(object->elements());
     if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
-      parameter_map->set(index + 2, GetHeap()->the_hole_value());
+      parameter_map->set(index + 2, heap->the_hole_value());
     }
-    parameter_map->set(1, dictionary);
+    parameter_map->set(1, *dictionary);
   } else {
-    set_elements(dictionary);
+    object->set_elements(*dictionary);
   }
-
-  return GetHeap()->undefined_value();
 }
 
 
-MaybeObject* JSObject::SetPropertyCallback(Name* name,
-                                           Object* structure,
-                                           PropertyAttributes attributes) {
+void JSObject::SetPropertyCallback(Handle<JSObject> object,
+                                   Handle<Name> name,
+                                   Handle<Object> structure,
+                                   PropertyAttributes attributes) {
   // Normalize object to make this operation simple.
-  MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
-  if (maybe_ok->IsFailure()) return maybe_ok;
+  NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
 
   // For the global object allocate a new map to invalidate the global inline
   // caches which have a global property cell reference directly in the code.
-  if (IsGlobalObject()) {
-    Map* new_map;
-    MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
-    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+  if (object->IsGlobalObject()) {
+    Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
     ASSERT(new_map->is_dictionary_map());
+    object->set_map(*new_map);
 
-    set_map(new_map);
     // When running crankshaft, changing the map is not enough. We
     // need to deoptimize all functions that rely on this global
     // object.
-    Deoptimizer::DeoptimizeGlobalObject(this);
+    Deoptimizer::DeoptimizeGlobalObject(*object);
   }
 
   // Update the dictionary with the new CALLBACKS property.
   PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
-  maybe_ok = SetNormalizedProperty(name, structure, details);
-  if (maybe_ok->IsFailure()) return maybe_ok;
-
-  return GetHeap()->undefined_value();
+  SetNormalizedProperty(object, name, structure, details);
 }
 
 
@@ -6310,41 +6297,44 @@
 }
 
 
-MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
-  Isolate* isolate = GetIsolate();
-  Name* name = Name::cast(info->name());
+Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
+                                     Handle<AccessorInfo> info) {
+  Isolate* isolate = object->GetIsolate();
+  Factory* factory = isolate->factory();
+  Handle<Name> name(Name::cast(info->name()));
+
   // Check access rights if needed.
-  if (IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
-    isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
-    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
-    return isolate->heap()->undefined_value();
+  if (object->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
+    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+    return factory->undefined_value();
   }
 
-  if (IsJSGlobalProxy()) {
-    Object* proto = GetPrototype();
-    if (proto->IsNull()) return this;
+  if (object->IsJSGlobalProxy()) {
+    Handle<Object> proto(object->GetPrototype(), isolate);
+    if (proto->IsNull()) return object;
     ASSERT(proto->IsJSGlobalObject());
-    return JSObject::cast(proto)->DefineAccessor(info);
+    return SetAccessor(Handle<JSObject>::cast(proto), info);
   }
 
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
-  AssertNoContextChangeWithHandleScope ncc;
+  AssertNoContextChange ncc;
 
   // Try to flatten before operating on the string.
-  if (name->IsString()) String::cast(name)->TryFlatten();
+  if (name->IsString()) FlattenString(Handle<String>::cast(name));
 
-  if (!CanSetCallback(name)) return isolate->heap()->undefined_value();
+  if (!object->CanSetCallback(*name)) return factory->undefined_value();
 
   uint32_t index = 0;
   bool is_element = name->AsArrayIndex(&index);
 
   if (is_element) {
-    if (IsJSArray()) return isolate->heap()->undefined_value();
+    if (object->IsJSArray()) return factory->undefined_value();
 
     // Accessors overwrite previous callbacks (cf. with getters/setters).
-    switch (GetElementsKind()) {
+    switch (object->GetElementsKind()) {
       case FAST_SMI_ELEMENTS:
       case FAST_ELEMENTS:
       case FAST_DOUBLE_ELEMENTS:
@@ -6363,7 +6353,7 @@
       case EXTERNAL_DOUBLE_ELEMENTS:
         // Ignore getters and setters on pixel and external array
         // elements.
-        return isolate->heap()->undefined_value();
+        return factory->undefined_value();
       case DICTIONARY_ELEMENTS:
         break;
       case NON_STRICT_ARGUMENTS_ELEMENTS:
@@ -6371,25 +6361,21 @@
         break;
     }
 
-    MaybeObject* maybe_ok =
-        SetElementCallback(index, info, info->property_attributes());
-    if (maybe_ok->IsFailure()) return maybe_ok;
+    SetElementCallback(object, index, info, info->property_attributes());
   } else {
     // Lookup the name.
     LookupResult result(isolate);
-    LocalLookup(name, &result, true);
+    object->LocalLookup(*name, &result, true);
     // ES5 forbids turning a property into an accessor if it's not
     // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
     if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
-      return isolate->heap()->undefined_value();
+      return factory->undefined_value();
     }
 
-    MaybeObject* maybe_ok =
-        SetPropertyCallback(name, info, info->property_attributes());
-    if (maybe_ok->IsFailure()) return maybe_ok;
+    SetPropertyCallback(object, name, info, info->property_attributes());
   }
 
-  return this;
+  return object;
 }
 
 
@@ -9437,15 +9423,6 @@
 }
 
 
-void OptimizedCodeEntry::Kill() {
-  set_function(NULL, SKIP_WRITE_BARRIER);
-  set_code(NULL, SKIP_WRITE_BARRIER);
-  set_native_context(NULL, SKIP_WRITE_BARRIER);
-  set_literals(NULL, SKIP_WRITE_BARRIER);
-  set_cacheable(false);
-}
-
-
 bool JSFunction::CompileLazy(Handle<JSFunction> function,
                              ClearExceptionFlag flag) {
   bool result = true;
@@ -12111,18 +12088,17 @@
 }
 
 
-MaybeObject* JSReceiver::SetElement(uint32_t index,
-                                    Object* value,
-                                    PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
-                                    bool check_proto) {
-  if (IsJSProxy()) {
-    return JSProxy::cast(this)->SetElementWithHandler(
-        this, index, value, strict_mode);
-  } else {
-    return JSObject::cast(this)->SetElement(
-        index, value, attributes, strict_mode, check_proto);
+Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
+                                      uint32_t index,
+                                      Handle<Object> value,
+                                      PropertyAttributes attributes,
+                                      StrictModeFlag strict_mode) {
+  if (object->IsJSProxy()) {
+    return JSProxy::SetElementWithHandler(
+        Handle<JSProxy>::cast(object), object, index, value, strict_mode);
   }
+  return JSObject::SetElement(
+      Handle<JSObject>::cast(object), index, value, attributes, strict_mode);
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 657d245..bf0d240 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -131,7 +131,6 @@
 //       - Oddball
 //       - Foreign
 //       - SharedFunctionInfo
-//       - OptimizedCodeEntry
 //       - Struct
 //         - Box
 //         - DeclaredAccessorDescriptor
@@ -407,7 +406,6 @@
   V(FIXED_ARRAY_TYPE)                                                          \
   V(FIXED_DOUBLE_ARRAY_TYPE)                                                   \
   V(SHARED_FUNCTION_INFO_TYPE)                                                 \
-  V(OPTIMIZED_CODE_ENTRY_TYPE)                                                 \
                                                                                \
   V(JS_MESSAGE_OBJECT_TYPE)                                                    \
                                                                                \
@@ -758,7 +756,6 @@
 
   FIXED_ARRAY_TYPE,
   SHARED_FUNCTION_INFO_TYPE,
-  OPTIMIZED_CODE_ENTRY_TYPE,
 
   JS_MESSAGE_OBJECT_TYPE,
 
@@ -1020,7 +1017,6 @@
   V(Code)                                      \
   V(Oddball)                                   \
   V(SharedFunctionInfo)                        \
-  V(OptimizedCodeEntry)                        \
   V(JSValue)                                   \
   V(JSDate)                                    \
   V(JSMessageObject)                           \
@@ -1936,6 +1932,11 @@
                                     Handle<Object> value,
                                     PropertyAttributes attributes,
                                     StrictModeFlag strict_mode);
+  static Handle<Object> SetElement(Handle<JSReceiver> object,
+                                   uint32_t index,
+                                   Handle<Object> value,
+                                   PropertyAttributes attributes,
+                                   StrictModeFlag strict_mode);
 
   MUST_USE_RESULT static MaybeObject* SetPropertyOrFail(
       Handle<JSReceiver> object,
@@ -1969,14 +1970,6 @@
                                       uint32_t index,
                                       DeleteMode mode = NORMAL_DELETION);
 
-  // Set the index'th array element.
-  // Can cause GC, or return failure if GC is required.
-  MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
-                                          Object* value,
-                                          PropertyAttributes attributes,
-                                          StrictModeFlag strict_mode,
-                                          bool check_prototype);
-
   // Tests for the fast common case for property enumeration.
   bool IsSimpleEnum();
 
@@ -2246,7 +2239,8 @@
 
   MaybeObject* LookupAccessor(Name* name, AccessorComponent component);
 
-  MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
+  static Handle<Object> SetAccessor(Handle<JSObject> object,
+                                    Handle<AccessorInfo> info);
 
   // Used from Object::GetProperty().
   MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck(
@@ -2297,13 +2291,13 @@
   Object* GetHiddenProperty(Name* key);
   // Deletes a hidden property. Deleting a non-existing property is
   // considered successful.
-  void DeleteHiddenProperty(Name* key);
+  static void DeleteHiddenProperty(Handle<JSObject> object,
+                                   Handle<Name> key);
   // Returns true if the object has a property with the hidden string as name.
   bool HasHiddenProperties();
 
-  static int GetIdentityHash(Handle<JSObject> obj);
-  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
-  MUST_USE_RESULT MaybeObject* SetIdentityHash(Smi* hash, CreationFlag flag);
+  static int GetIdentityHash(Handle<JSObject> object);
+  static void SetIdentityHash(Handle<JSObject> object, Smi* hash);
 
   inline void ValidateElements();
 
@@ -2788,10 +2782,6 @@
   static Handle<Object> DeleteElementWithInterceptor(Handle<JSObject> object,
                                                      uint32_t index);
 
-  MUST_USE_RESULT MaybeObject* DeleteFastElement(uint32_t index);
-  MUST_USE_RESULT MaybeObject* DeleteDictionaryElement(uint32_t index,
-                                                       DeleteMode mode);
-
   bool ReferencesObjectFromElements(FixedArray* elements,
                                     ElementsKind kind,
                                     Object* object);
@@ -2803,14 +2793,14 @@
   void GetElementsCapacityAndUsage(int* capacity, int* used);
 
   bool CanSetCallback(Name* name);
-  MUST_USE_RESULT MaybeObject* SetElementCallback(
-      uint32_t index,
-      Object* structure,
-      PropertyAttributes attributes);
-  MUST_USE_RESULT MaybeObject* SetPropertyCallback(
-      Name* name,
-      Object* structure,
-      PropertyAttributes attributes);
+  static void SetElementCallback(Handle<JSObject> object,
+                                 uint32_t index,
+                                 Handle<Object> structure,
+                                 PropertyAttributes attributes);
+  static void SetPropertyCallback(Handle<JSObject> object,
+                                  Handle<Name> name,
+                                  Handle<Object> structure,
+                                  PropertyAttributes attributes);
   static void DefineElementAccessor(Handle<JSObject> object,
                                     uint32_t index,
                                     Handle<Object> getter,
@@ -2850,6 +2840,8 @@
   MUST_USE_RESULT MaybeObject* SetHiddenPropertiesHashTable(
       Object* value);
 
+  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
 };
 
@@ -6806,76 +6798,6 @@
 };
 
 
-// An optimized code entry represents an association between the native
-// context, a function, optimized code, and the literals. The entries
-// are linked into two lists for efficient lookup: by native context
-// (linked through next_by_native_context), or by shared function
-// info (linked through next_by_shared_info).
-// The references to the native context, function, and code are weak,
-// in order not to leak native contexts or functions through
-// SharedFunctionInfo. This means an entry can become "dead" through GC.
-// Entries are removed lazily as each list is traversed.
-class OptimizedCodeEntry: public HeapObject {
- public:
-  // [native_context]: The native context of this entry. (WEAK)
-  DECL_ACCESSORS(native_context, Context)
-
-  // [function]: The JSFunction of this entry. (WEAK)
-  DECL_ACCESSORS(function, JSFunction)
-
-  // [code]: The optimized code of this entry. (WEAK)
-  DECL_ACCESSORS(code, Code)
-
-  // [literals]: Array of literals for this entry.
-  DECL_ACCESSORS(literals, FixedArray)
-
-  // [next_by_shared_info]: The next link in the list, when traversing
-  // starting with a SharedFunctionInfo. (NULL if none).
-  DECL_ACCESSORS(next_by_shared_info, OptimizedCodeEntry)
-
-  // [next_by_native_context]: The next link in the list, when traversing
-  // starting with a native context. (NULL if none)
-  DECL_ACCESSORS(next_by_native_context, OptimizedCodeEntry)
-
-  // Casting.
-  static inline OptimizedCodeEntry* cast(Object* obj);
-
-  DECLARE_PRINTER(OptimizedCodeEntry)
-  DECLARE_VERIFIER(OptimizedCodeEntry)
-
-  // Layout description.
-  static const int kNativeContextOffset = JSObject::kHeaderSize;
-  static const int kFunctionOffset = kNativeContextOffset + kPointerSize;
-  static const int kCodeOffset = kFunctionOffset + kPointerSize;
-  static const int kLiteralsOffset = kCodeOffset + kPointerSize;
-  static const int kNextBySharedInfoOffset =
-      kLiteralsOffset + kPointerSize;
-  static const int kNextByNativeContextOffset =
-      kNextBySharedInfoOffset + kPointerSize;
-  static const int kCacheableOffset = kNextByNativeContextOffset + kPointerSize;
-  static const int kSize = kCacheableOffset + kIntSize;
-  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kSize);
-
-  typedef FixedBodyDescriptor<kLiteralsOffset,
-                              kNextByNativeContextOffset + kPointerSize,
-                              kSize> BodyDescriptor;
-
-  // Kills an entry, nulling out its references to native context, function,
-  // code, and literals.
-  void Kill();
-  inline bool cacheable();
-  inline void set_cacheable(bool val);
-
- private:
-  // Used internally during traversal to skip dead entries.
-  inline bool IsDead() {
-    return function() == NULL || code() == NULL;
-  }
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(OptimizedCodeEntry);
-};
-
-
 class JSGeneratorObject: public JSObject {
  public:
   // [function]: The function corresponding to this generator object.
@@ -9088,11 +9010,6 @@
       Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode);
-  MUST_USE_RESULT MaybeObject* SetElementWithHandler(
-      JSReceiver* receiver,
-      uint32_t index,
-      Object* value,
-      StrictModeFlag strict_mode);
 
   // If the handler defines an accessor property with a setter, invoke it.
   // If it defines an accessor property without a setter, or a data property
@@ -9113,10 +9030,8 @@
       JSReceiver* receiver,
       uint32_t index);
 
-  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
-
-  // Turn this into an (empty) JSObject.
-  void Fix();
+  // Turn the proxy into an (empty) JSObject.
+  static void Fix(Handle<JSProxy> proxy);
 
   // Initializes the body after the handler slot.
   inline void InitializeBody(int object_size, Object* value);
@@ -9151,13 +9066,23 @@
  private:
   friend class JSReceiver;
 
-  static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> object,
+  static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
+                                              Handle<JSReceiver> receiver,
+                                              uint32_t index,
+                                              Handle<Object> value,
+                                              StrictModeFlag strict_mode);
+
+  static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> proxy,
                                                   Handle<Name> name,
                                                   DeleteMode mode);
-  static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> object,
+  static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> proxy,
                                                  uint32_t index,
                                                  DeleteMode mode);
 
+  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
+  static Handle<Object> GetIdentityHash(Handle<JSProxy> proxy,
+                                        CreationFlag flag);
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
 };
 
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 1824efa..b1bac4c 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -38,11 +38,11 @@
 
 #ifdef DEBUG
 
-PrettyPrinter::PrettyPrinter() {
+PrettyPrinter::PrettyPrinter(Isolate* isolate) {
   output_ = NULL;
   size_ = 0;
   pos_ = 0;
-  InitializeAstVisitor();
+  InitializeAstVisitor(isolate);
 }
 
 
@@ -480,8 +480,8 @@
 }
 
 
-void PrettyPrinter::PrintOut(AstNode* node) {
-  PrettyPrinter printer;
+void PrettyPrinter::PrintOut(Isolate* isolate, AstNode* node) {
+  PrettyPrinter printer(isolate);
   PrintF("%s", printer.Print(node));
 }
 
@@ -658,7 +658,7 @@
 //-----------------------------------------------------------------------------
 
 
-AstPrinter::AstPrinter() : indent_(0) {
+AstPrinter::AstPrinter(Isolate* isolate) : PrettyPrinter(isolate), indent_(0) {
 }
 
 
diff --git a/src/prettyprinter.h b/src/prettyprinter.h
index 6657ecd..b7ff2af 100644
--- a/src/prettyprinter.h
+++ b/src/prettyprinter.h
@@ -38,7 +38,7 @@
 
 class PrettyPrinter: public AstVisitor {
  public:
-  PrettyPrinter();
+  explicit PrettyPrinter(Isolate* isolate);
   virtual ~PrettyPrinter();
 
   // The following routines print a node into a string.
@@ -50,7 +50,7 @@
   void Print(const char* format, ...);
 
   // Print a node to stdout.
-  static void PrintOut(AstNode* node);
+  static void PrintOut(Isolate* isolate, AstNode* node);
 
   // Individual nodes
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
@@ -82,7 +82,7 @@
 // Prints the AST structure
 class AstPrinter: public PrettyPrinter {
  public:
-  AstPrinter();
+  explicit AstPrinter(Isolate* isolate);
   virtual ~AstPrinter();
 
   const char* PrintProgram(FunctionLiteral* program);
diff --git a/src/rewriter.cc b/src/rewriter.cc
index df5c353..06335a8 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -43,8 +43,8 @@
         result_assigned_(false),
         is_set_(false),
         in_try_(false),
-        factory_(Isolate::Current(), zone) {
-    InitializeAstVisitor();
+        factory_(zone->isolate(), zone) {
+    InitializeAstVisitor(zone->isolate());
   }
 
   virtual ~Processor() { }
diff --git a/src/runtime.cc b/src/runtime.cc
index 5760982..4830faf 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -685,10 +685,10 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
-  proxy->Fix();
+  CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
+  JSProxy::Fix(proxy);
   return isolate->heap()->undefined_value();
 }
 
@@ -8992,7 +8992,7 @@
               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
           Handle<AccessorInfo> info =
               Accessors::MakeModuleExport(name, index, attr);
-          Handle<Object> result = SetAccessor(module, info);
+          Handle<Object> result = JSObject::SetAccessor(module, info);
           ASSERT(!(result.is_null() || result->IsUndefined()));
           USE(result);
           break;
@@ -14156,13 +14156,13 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
   HandleScope scope(isolate);
   ASSERT_EQ(args.length(), 1);
-  CONVERT_ARG_CHECKED(JSObject, error_object, 0);
-  String* key = isolate->heap()->hidden_stack_trace_string();
-  Object* result = error_object->GetHiddenProperty(key);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
+  Handle<String> key = isolate->factory()->hidden_stack_trace_string();
+  Handle<Object> result(error_object->GetHiddenProperty(*key), isolate);
   if (result->IsTheHole()) return isolate->heap()->undefined_value();
   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
-  error_object->DeleteHiddenProperty(key);
-  return result;
+  JSObject::DeleteHiddenProperty(error_object, key);
+  return *result;
 }
 
 
diff --git a/src/typing.cc b/src/typing.cc
index f8e2a7c..34bb64b 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -42,7 +42,7 @@
           info->isolate(),
           info->zone()),
       store_(info->zone()) {
-  InitializeAstVisitor();
+  InitializeAstVisitor(info->isolate());
 }
 
 
diff --git a/src/v8globals.h b/src/v8globals.h
index 95187e6..7fa2fd6 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -347,8 +347,9 @@
 
 // AccessorCallback
 struct AccessorDescriptor {
-  MaybeObject* (*getter)(Object* object, void* data);
-  MaybeObject* (*setter)(JSObject* object, Object* value, void* data);
+  MaybeObject* (*getter)(Isolate* isolate, Object* object, void* data);
+  MaybeObject* (*setter)(
+      Isolate* isolate, JSObject* object, Object* value, void* data);
   void* data;
 };
 
@@ -564,6 +565,11 @@
 };
 
 
+enum MinusZeroMode {
+  TREAT_MINUS_ZERO_AS_ZERO,
+  FAIL_ON_MINUS_ZERO
+};
+
 } }  // namespace v8::internal
 
 #endif  // V8_V8GLOBALS_H_
diff --git a/src/version.cc b/src/version.cc
index bad4b63..953f90f 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     21
-#define BUILD_NUMBER      7
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      8
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 9b8454a..93d9aac 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -44,8 +44,8 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  CodeGenerator() {
-    InitializeAstVisitor();
+  explicit CodeGenerator(Isolate* isolate) {
+    InitializeAstVisitor(isolate);
   }
 
   static bool MakeCode(CompilationInfo* info);
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index d316c8e..e6e3bd1 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -104,7 +104,7 @@
 }
 
 
-static MaybeObject* TestAccessorGet(Object* object, void*) {
+static MaybeObject* TestAccessorGet(Isolate* isolate, Object* object, void*) {
   return AllocateAfterFailures();
 }
 
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index ccf1cbd..91f377a 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -16665,6 +16665,42 @@
 }
 
 
+static int scriptIdInStack[2];
+
+void AnalyzeScriptIdInStack(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  v8::HandleScope scope(args.GetIsolate());
+  v8::Handle<v8::StackTrace> stackTrace =
+      v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kScriptId);
+  CHECK_EQ(2, stackTrace->GetFrameCount());
+  for (int i = 0; i < 2; i++) {
+    scriptIdInStack[i] = stackTrace->GetFrame(i)->GetScriptId();
+  }
+}
+
+
+TEST(ScriptIdInStackTrace) {
+  v8::HandleScope scope(v8::Isolate::GetCurrent());
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->Set(v8_str("AnalyzeScriptIdInStack"),
+             v8::FunctionTemplate::New(AnalyzeScriptIdInStack));
+  LocalContext context(0, templ);
+
+  v8::Handle<v8::String> scriptSource = v8::String::New(
+    "function foo() {\n"
+    "  AnalyzeScriptIdInStack();"
+    "}\n"
+    "foo();\n");
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
+  script->Run();
+  for (int i = 0; i < 2; i++) {
+    CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo);
+    CHECK_EQ(scriptIdInStack[i], script->GetId());
+  }
+}
+
+
 void AnalyzeStackOfInlineScriptWithSourceURL(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   v8::HandleScope scope(args.GetIsolate());
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-dictionary.cc
index 2bdf235..21c20bd 100644
--- a/test/cctest/test-dictionary.cc
+++ b/test/cctest/test-dictionary.cc
@@ -72,7 +72,7 @@
   // Keys should map back to their respective values and also should get
   // an identity hash code generated.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = factory->NewJSArray(7);
+    Handle<JSReceiver> key = factory->NewJSArray(7);
     Handle<JSObject> value = factory->NewJSArray(11);
     table = PutIntoObjectHashTable(table, key, value);
     CHECK_EQ(table->NumberOfElements(), i + 1);
@@ -84,7 +84,7 @@
   // Keys never added to the map which already have an identity hash
   // code should not be found.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = factory->NewJSArray(7);
+    Handle<JSReceiver> key = factory->NewJSArray(7);
     CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
     CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
     CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
@@ -94,7 +94,7 @@
   // Keys that don't have an identity hash should not be found and also
   // should not get an identity hash code generated.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = factory->NewJSArray(7);
+    Handle<JSReceiver> key = factory->NewJSArray(7);
     CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
     CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
   }
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 87598e2..fc6a1ec 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -2691,9 +2691,7 @@
     // In the first iteration, set hidden value first and identity hash second.
     // In the second iteration, reverse the order.
     if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
-    MaybeObject* maybe_obj = internal_obj->SetIdentityHash(hash,
-                                                           ALLOW_CREATION);
-    CHECK(!maybe_obj->IsFailure());
+    JSObject::SetIdentityHash(internal_obj, hash);
     if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
 
     // Check values.
diff --git a/test/mjsunit/external-array-no-sse2.js b/test/mjsunit/external-array-no-sse2.js
index 11e61ba..575a8b5 100644
--- a/test/mjsunit/external-array-no-sse2.js
+++ b/test/mjsunit/external-array-no-sse2.js
@@ -679,3 +679,37 @@
 assertEquals(2.5, goo(built_in_array, 0));
 %ClearFunctionTypeFeedback(goo);
 %ClearFunctionTypeFeedback(boo);
+
+// Check all int range edge cases
+function checkRange() {
+  var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
+  var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
+  var e8 = Math.pow(2,8);   var e7 = Math.pow(2,7);
+  var a7 = new Uint32Array(2);  var a71 = new Int32Array(2);
+  var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
+  var a74 = new Uint8Array(2);  var a75 = new Int8Array(2);
+  for (i = 1; i <= Math.pow(2,33); i *= 2) {
+    var j = i-1;
+    a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
+    a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
+
+    if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
+    if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
+    if (i < e31) { assertEquals(a71[0], i); } else {
+      assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
+    if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
+
+    if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
+    if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
+    if (i < e15) { assertEquals(a73[0], i); } else {
+      assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
+    if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
+
+    if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
+    if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
+    if (i < e7) { assertEquals(a75[0], i); } else {
+      assertEquals(a75[0], (i < e8) ? -e7 : 0); }
+    if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
+  }
+}
+checkRange();
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 3fcd544..ab5435e 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -678,3 +678,37 @@
 assertEquals(2.5, goo(built_in_array, 0));
 %ClearFunctionTypeFeedback(goo);
 %ClearFunctionTypeFeedback(boo);
+
+// Check all int range edge cases
+function checkRange() {
+  var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
+  var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
+  var e8 = Math.pow(2,8);   var e7 = Math.pow(2,7);
+  var a7 = new Uint32Array(2);  var a71 = new Int32Array(2);
+  var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
+  var a74 = new Uint8Array(2);  var a75 = new Int8Array(2);
+  for (i = 1; i <= Math.pow(2,33); i *= 2) {
+    var j = i-1;
+    a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
+    a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
+
+    if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
+    if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
+    if (i < e31) { assertEquals(a71[0], i); } else {
+      assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
+    if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
+
+    if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
+    if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
+    if (i < e15) { assertEquals(a73[0], i); } else {
+      assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
+    if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
+
+    if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
+    if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
+    if (i < e7) { assertEquals(a75[0], i); } else {
+      assertEquals(a75[0], (i < e8) ? -e7 : 0); }
+    if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
+  }
+}
+checkRange();
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index a73ece0..ca81736 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -742,7 +742,7 @@
                 'target_conditions': [
                   ['_toolset=="host"', {
                     'defines': [
-                      'V8_LIBRT_NOT_AVAILABLE',
+                      'V8_LIBRT_NOT_AVAILABLE=1',
                     ],
                   }],
                 ],