Version 3.21.5

Fixed compilation with recent MinGW64 versions. (issue 2300)

Added RemovePrototype to FunctionTemplate. (Chromium issue 272440)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@16383 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 37763eb..16b5126 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-08-28: Version 3.21.5
+
+        Fixed compilation with recent MinGW64 versions. (issue 2300)
+
+        Added RemovePrototype to FunctionTemplate. (Chromium issue 272440)
+
+        Performance and stability improvements on all platforms.
+
+
 2013-08-26: Version 3.21.4
 
         Lowered kInitialMaxFastElementArray constant to 95K (issue 2790).
diff --git a/include/v8-debug.h b/include/v8-debug.h
index bacccb6..a7d2198 100755
--- a/include/v8-debug.h
+++ b/include/v8-debug.h
@@ -150,21 +150,6 @@
     virtual ~EventDetails() {}
   };
 
-
-  /**
-   * Debug event callback function.
-   *
-   * \param event the type of the debug event that triggered the callback
-   *   (enum DebugEvent)
-   * \param exec_state execution state (JavaScript object)
-   * \param event_data event specific data (JavaScript object)
-   * \param data value passed by the user to SetDebugEventListener
-   */
-  typedef void (*EventCallback)(DebugEvent event,
-                                Handle<Object> exec_state,
-                                Handle<Object> event_data,
-                                Handle<Value> data);
-
   /**
    * Debug event callback function.
    *
@@ -179,23 +164,8 @@
    * Debug message callback function.
    *
    * \param message the debug message handler message object
-   * \param length length of the message
-   * \param client_data the data value passed when registering the message handler
-
-   * A MessageHandler does not take possession of the message string,
-   * and must not rely on the data persisting after the handler returns.
    *
-   * This message handler is deprecated. Use MessageHandler2 instead.
-   */
-  typedef void (*MessageHandler)(const uint16_t* message, int length,
-                                 ClientData* client_data);
-
-  /**
-   * Debug message callback function.
-   *
-   * \param message the debug message handler message object
-   *
-   * A MessageHandler does not take possession of the message data,
+   * A MessageHandler2 does not take possession of the message data,
    * and must not rely on the data persisting after the handler returns.
    */
   typedef void (*MessageHandler2)(const Message& message);
@@ -210,10 +180,6 @@
    */
   typedef void (*DebugMessageDispatchHandler)();
 
-  // Set a C debug event listener.
-  V8_DEPRECATED(static bool SetDebugEventListener(
-      EventCallback that,
-      Handle<Value> data = Handle<Value>()));
   static bool SetDebugEventListener2(EventCallback2 that,
                                      Handle<Value> data = Handle<Value>());
 
@@ -234,16 +200,12 @@
   // Break execution of JavaScript in the given isolate (this method
   // can be invoked from a non-VM thread) for further client command
   // execution on a VM thread. Client data is then passed in
-  // EventDetails to EventCallback at the moment when the VM actually
+  // EventDetails to EventCallback2 at the moment when the VM actually
   // stops. If no isolate is provided the default isolate is used.
   static void DebugBreakForCommand(ClientData* data = NULL,
                                    Isolate* isolate = NULL);
 
-  // Message based interface. The message protocol is JSON. NOTE the message
-  // handler thread is not supported any more parameter must be false.
-  V8_DEPRECATED(static void SetMessageHandler(
-      MessageHandler handler,
-      bool message_handler_thread = false));
+  // Message based interface. The message protocol is JSON.
   static void SetMessageHandler2(MessageHandler2 handler);
 
   // If no isolate is provided the default isolate is
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 936ea59..1932fb8 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -57,21 +57,6 @@
    */
   int GetLineNumber() const;
 
-  /**
-   * Returns total (self + children) execution time of the function,
-   * in milliseconds, estimated by samples count.
-   */
-  V8_DEPRECATED(double GetTotalTime() const);
-
-  /**
-   * Returns self execution time of the function, in milliseconds,
-   * estimated by samples count.
-   */
-  V8_DEPRECATED(double GetSelfTime() const);
-
-  /** Returns the count of samples where function exists. */
-  V8_DEPRECATED(double GetTotalSamplesCount() const);
-
   /** DEPRECATED. Please use GetHitCount instead.
     * Returns the count of samples where function was currently executing.
     */
diff --git a/include/v8.h b/include/v8.h
index dbf2b08..c29bba6 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -83,7 +83,6 @@
  */
 namespace v8 {
 
-class AccessorInfo;
 class AccessorSignature;
 class Array;
 class Boolean;
@@ -125,7 +124,6 @@
 class FunctionTemplate;
 class ObjectTemplate;
 class Data;
-class AccessorInfo;
 template<typename T> class PropertyCallbackInfo;
 class StackTrace;
 class StackFrame;
@@ -351,11 +349,9 @@
   friend class Utils;
   template<class F> friend class Persistent;
   template<class F> friend class Local;
-  friend class Arguments;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
   template<class F> friend class internal::CustomArguments;
-  friend class AccessorInfo;
   friend Handle<Primitive> Undefined(Isolate* isolate);
   friend Handle<Primitive> Null(Isolate* isolate);
   friend Handle<Boolean> True(Isolate* isolate);
@@ -439,12 +435,10 @@
   template<class F> friend class Eternal;
   template<class F> friend class Persistent;
   template<class F> friend class Handle;
-  friend class Arguments;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
   friend class String;
   friend class Object;
-  friend class AccessorInfo;
   friend class Context;
   template<class F> friend class internal::CustomArguments;
   friend class HandleScope;
@@ -2035,16 +2029,11 @@
  * setting|getting a particular property. See Object and ObjectTemplate's
  * method SetAccessor.
  */
-typedef Handle<Value> (*AccessorGetter)(Local<String> property,
-                                        const AccessorInfo& info);
 typedef void (*AccessorGetterCallback)(
     Local<String> property,
     const PropertyCallbackInfo<Value>& info);
 
 
-typedef void (*AccessorSetter)(Local<String> property,
-                               Local<Value> value,
-                               const AccessorInfo& info);
 typedef void (*AccessorSetterCallback)(
     Local<String> property,
     Local<Value> value,
@@ -2118,12 +2107,6 @@
 
   bool Delete(uint32_t index);
 
-  V8_DEPRECATED(bool SetAccessor(Handle<String> name,
-                                 AccessorGetter getter,
-                                 AccessorSetter setter = 0,
-                                 Handle<Value> data = Handle<Value>(),
-                                 AccessControl settings = DEFAULT,
-                                 PropertyAttribute attribute = None));
   bool SetAccessor(Handle<String> name,
                    AccessorGetterCallback getter,
                    AccessorSetterCallback setter = 0,
@@ -3072,15 +3055,6 @@
 };
 
 
-class V8_EXPORT Arguments : public FunctionCallbackInfo<Value> {
- private:
-  friend class internal::FunctionCallbackArguments;
-  V8_INLINE(Arguments(internal::Object** implicit_args,
-                      internal::Object** values,
-                      int length,
-                      bool is_construct_call));
-};
-
 /**
  * The information passed to a property callback about the context
  * of the property access.
@@ -3113,23 +3087,12 @@
 };
 
 
-class V8_EXPORT AccessorInfo : public PropertyCallbackInfo<Value> {
- private:
-  friend class internal::PropertyCallbackArguments;
-  V8_INLINE(AccessorInfo(internal::Object** args))
-      : PropertyCallbackInfo<Value>(args) { }
-};
-
-
-typedef Handle<Value> (*InvocationCallback)(const Arguments& args);
 typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
 
 /**
  * NamedProperty[Getter|Setter] are used as interceptors on object.
  * See ObjectTemplate::SetNamedPropertyHandler.
  */
-typedef Handle<Value> (*NamedPropertyGetter)(Local<String> property,
-                                             const AccessorInfo& info);
 typedef void (*NamedPropertyGetterCallback)(
     Local<String> property,
     const PropertyCallbackInfo<Value>& info);
@@ -3139,9 +3102,6 @@
  * Returns the value if the setter intercepts the request.
  * Otherwise, returns an empty handle.
  */
-typedef Handle<Value> (*NamedPropertySetter)(Local<String> property,
-                                             Local<Value> value,
-                                             const AccessorInfo& info);
 typedef void (*NamedPropertySetterCallback)(
     Local<String> property,
     Local<Value> value,
@@ -3153,8 +3113,6 @@
  * The result is an integer encoding property attributes (like v8::None,
  * v8::DontEnum, etc.)
  */
-typedef Handle<Integer> (*NamedPropertyQuery)(Local<String> property,
-                                              const AccessorInfo& info);
 typedef void (*NamedPropertyQueryCallback)(
     Local<String> property,
     const PropertyCallbackInfo<Integer>& info);
@@ -3165,8 +3123,6 @@
  * The return value is true if the property could be deleted and false
  * otherwise.
  */
-typedef Handle<Boolean> (*NamedPropertyDeleter)(Local<String> property,
-                                                const AccessorInfo& info);
 typedef void (*NamedPropertyDeleterCallback)(
     Local<String> property,
     const PropertyCallbackInfo<Boolean>& info);
@@ -3176,7 +3132,6 @@
  * Returns an array containing the names of the properties the named
  * property getter intercepts.
  */
-typedef Handle<Array> (*NamedPropertyEnumerator)(const AccessorInfo& info);
 typedef void (*NamedPropertyEnumeratorCallback)(
     const PropertyCallbackInfo<Array>& info);
 
@@ -3185,8 +3140,6 @@
  * Returns the value of the property if the getter intercepts the
  * request.  Otherwise, returns an empty handle.
  */
-typedef Handle<Value> (*IndexedPropertyGetter)(uint32_t index,
-                                               const AccessorInfo& info);
 typedef void (*IndexedPropertyGetterCallback)(
     uint32_t index,
     const PropertyCallbackInfo<Value>& info);
@@ -3196,9 +3149,6 @@
  * Returns the value if the setter intercepts the request.
  * Otherwise, returns an empty handle.
  */
-typedef Handle<Value> (*IndexedPropertySetter)(uint32_t index,
-                                               Local<Value> value,
-                                               const AccessorInfo& info);
 typedef void (*IndexedPropertySetterCallback)(
     uint32_t index,
     Local<Value> value,
@@ -3209,8 +3159,6 @@
  * Returns a non-empty handle if the interceptor intercepts the request.
  * The result is an integer encoding property attributes.
  */
-typedef Handle<Integer> (*IndexedPropertyQuery)(uint32_t index,
-                                                const AccessorInfo& info);
 typedef void (*IndexedPropertyQueryCallback)(
     uint32_t index,
     const PropertyCallbackInfo<Integer>& info);
@@ -3221,8 +3169,6 @@
  * The return value is true if the property could be deleted and false
  * otherwise.
  */
-typedef Handle<Boolean> (*IndexedPropertyDeleter)(uint32_t index,
-                                                  const AccessorInfo& info);
 typedef void (*IndexedPropertyDeleterCallback)(
     uint32_t index,
     const PropertyCallbackInfo<Boolean>& info);
@@ -3232,7 +3178,6 @@
  * Returns an array containing the indices of the properties the
  * indexed property getter intercepts.
  */
-typedef Handle<Array> (*IndexedPropertyEnumerator)(const AccessorInfo& info);
 typedef void (*IndexedPropertyEnumeratorCallback)(
     const PropertyCallbackInfo<Array>& info);
 
@@ -3364,11 +3309,6 @@
 class V8_EXPORT FunctionTemplate : public Template {
  public:
   /** Creates a function template.*/
-  V8_DEPRECATED(static Local<FunctionTemplate> New(
-      InvocationCallback callback,
-      Handle<Value> data = Handle<Value>(),
-      Handle<Signature> signature = Handle<Signature>(),
-      int length = 0));
   static Local<FunctionTemplate> New(
       FunctionCallback callback = 0,
       Handle<Value> data = Handle<Value>(),
@@ -3383,8 +3323,6 @@
    * callback is called whenever the function created from this
    * FunctionTemplate is called.
    */
-  V8_DEPRECATED(void SetCallHandler(InvocationCallback callback,
-                                    Handle<Value> data = Handle<Value>()));
   void SetCallHandler(FunctionCallback callback,
                       Handle<Value> data = Handle<Value>());
 
@@ -3431,6 +3369,12 @@
   void ReadOnlyPrototype();
 
   /**
+   * Removes the prototype property from functions created from this
+   * FunctionTemplate.
+   */
+  void RemovePrototype();
+
+  /**
    * Returns true if the given object is an instance of this function
    * template.
    */
@@ -3438,9 +3382,6 @@
 
  private:
   FunctionTemplate();
-  // TODO(dcarney): Remove with SetCallHandler.
-  friend class v8::CallHandlerHelper;
-  void SetCallHandlerInternal(InvocationCallback callback, Handle<Value> data);
   friend class Context;
   friend class ObjectTemplate;
 };
@@ -3489,14 +3430,6 @@
    *   defined by FunctionTemplate::HasInstance()), an implicit TypeError is
    *   thrown and no callback is invoked.
    */
-  V8_DEPRECATED(void SetAccessor(Handle<String> name,
-                                 AccessorGetter getter,
-                                 AccessorSetter setter = 0,
-                                 Handle<Value> data = Handle<Value>(),
-                                 AccessControl settings = DEFAULT,
-                                 PropertyAttribute attribute = None,
-                                 Handle<AccessorSignature> signature =
-                                     Handle<AccessorSignature>()));
   void SetAccessor(Handle<String> name,
                    AccessorGetterCallback getter,
                    AccessorSetterCallback setter = 0,
@@ -3531,13 +3464,6 @@
    * \param data A piece of data that will be passed to the callbacks
    *   whenever they are invoked.
    */
-  V8_DEPRECATED(void SetNamedPropertyHandler(
-      NamedPropertyGetter getter,
-      NamedPropertySetter setter = 0,
-      NamedPropertyQuery query = 0,
-      NamedPropertyDeleter deleter = 0,
-      NamedPropertyEnumerator enumerator = 0,
-      Handle<Value> data = Handle<Value>()));
   void SetNamedPropertyHandler(
       NamedPropertyGetterCallback getter,
       NamedPropertySetterCallback setter = 0,
@@ -3562,13 +3488,6 @@
    * \param data A piece of data that will be passed to the callbacks
    *   whenever they are invoked.
    */
-  V8_DEPRECATED(void SetIndexedPropertyHandler(
-      IndexedPropertyGetter getter,
-      IndexedPropertySetter setter = 0,
-      IndexedPropertyQuery query = 0,
-      IndexedPropertyDeleter deleter = 0,
-      IndexedPropertyEnumerator enumerator = 0,
-      Handle<Value> data = Handle<Value>()));
   void SetIndexedPropertyHandler(
       IndexedPropertyGetterCallback getter,
       IndexedPropertySetterCallback setter = 0,
@@ -3583,9 +3502,6 @@
    * behave like normal JavaScript objects that cannot be called as a
    * function.
    */
-  V8_DEPRECATED(void SetCallAsFunctionHandler(
-      InvocationCallback callback,
-      Handle<Value> data = Handle<Value>()));
   void SetCallAsFunctionHandler(FunctionCallback callback,
                                 Handle<Value> data = Handle<Value>());
 
@@ -5467,6 +5383,8 @@
 typedef SmiTagging<kApiPointerSize> PlatformSmiTagging;
 const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
 const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
+V8_INLINE(static bool SmiValuesAre31Bits()) { return kSmiValueSize == 31; }
+V8_INLINE(static bool SmiValuesAre32Bits()) { return kSmiValueSize == 32; }
 
 /**
  * This class exports constants and functionality from within v8 that
@@ -6007,13 +5925,6 @@
       is_construct_call_(is_construct_call) { }
 
 
-Arguments::Arguments(internal::Object** args,
-                     internal::Object** values,
-                     int length,
-                     bool is_construct_call)
-    : FunctionCallbackInfo<Value>(args, values, length, is_construct_call) { }
-
-
 template<typename T>
 Local<Value> FunctionCallbackInfo<T>::operator[](int i) const {
   if (i < 0 || length_ <= i) return Local<Value>(*Undefined());
diff --git a/include/v8config.h b/include/v8config.h
index 25eb480..2bf3b9d 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -91,7 +91,10 @@
 //
 //  V8_CC_CLANG   - Clang
 //  V8_CC_GNU     - GNU C++
+//  V8_CC_INTEL   - Intel C++
 //  V8_CC_MINGW   - Minimalist GNU for Windows
+//  V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
+//  V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
 //  V8_CC_MSVC    - Microsoft Visual C/C++
 //
 // C++11 feature detection
@@ -105,18 +108,29 @@
 //
 // Compiler-specific feature detection
 //
-//  V8_HAS___ALIGNOF                - __alignof(type) operator supported
-//  V8_HAS___ALIGNOF__              - __alignof__(type) operator supported
-//  V8_HAS_ATTRIBUTE_ALIGNED        - __attribute__((aligned(n))) supported
-//  V8_HAS_ATTRIBUTE_ALWAYS_INLINE  - __attribute__((always_inline)) supported
-//  V8_HAS_ATTRIBUTE_DEPRECATED     - __attribute__((deprecated)) supported
-//  V8_HAS_ATTRIBUTE_VISIBILITY     - __attribute__((visibility)) supported
-//  V8_HAS_BUILTIN_EXPECT           - __builtin_expect() supported
-//  V8_HAS_DECLSPEC_ALIGN           - __declspec(align(n)) supported
-//  V8_HAS_DECLSPEC_DEPRECATED      - __declspec(deprecated) supported
-//  V8_HAS___FINAL                  - __final supported in non-C++11 mode
-//  V8_HAS___FORCEINLINE            - __forceinline supported
-//  V8_HAS_SEALED                   - MSVC style sealed marker supported
+//  V8_HAS___ALIGNOF                    - __alignof(type) operator supported
+//  V8_HAS___ALIGNOF__                  - __alignof__(type) operator supported
+//  V8_HAS_ATTRIBUTE_ALIGNED            - __attribute__((aligned(n))) supported
+//  V8_HAS_ATTRIBUTE_ALWAYS_INLINE      - __attribute__((always_inline))
+//                                        supported
+//  V8_HAS_ATTRIBUTE_DEPRECATED         - __attribute__((deprecated)) supported
+//  V8_HAS_ATTRIBUTE_NOINLINE           - __attribute__((noinline)) supported
+//  V8_HAS_ATTRIBUTE_VISIBILITY         - __attribute__((visibility)) supported
+//  V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
+//                                        supported
+//  V8_HAS_BUILTIN_EXPECT               - __builtin_expect() supported
+//  V8_HAS_DECLSPEC_ALIGN               - __declspec(align(n)) supported
+//  V8_HAS_DECLSPEC_DEPRECATED          - __declspec(deprecated) supported
+//  V8_HAS_DECLSPEC_NOINLINE            - __declspec(noinline) supported
+//  V8_HAS___FINAL                      - __final supported in non-C++11 mode
+//  V8_HAS___FORCEINLINE                - __forceinline supported
+//  V8_HAS_SEALED                       - MSVC style sealed marker supported
+//
+// Note that testing for compilers and/or features must be done using #if
+// not #ifdef. For example, to test for Intel C++ Compiler, use:
+//  #if V8_CC_INTEL
+//   ...
+//  #endif
 
 #if defined(__clang__)
 
@@ -132,7 +146,10 @@
 # define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned))
 # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
 # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated))
+# define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline))
 # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
+# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
+    (__has_attribute(warn_unused_result))
 
 # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
 
@@ -149,9 +166,11 @@
      ((major) * 10000 + (minor) * 100 + (patchlevel)))
 
 # define V8_CC_GNU 1
-# if defined(__MINGW32__)
-#  define V8_CC_MINGW 1
-# endif
+// Intel C++ also masquerades as GCC 3.2.0
+# define V8_CC_INTEL (defined(__INTEL_COMPILER))
+# define V8_CC_MINGW32 (defined(__MINGW32__))
+# define V8_CC_MINGW64 (defined(__MINGW64__))
+# define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64)
 
 # define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0))
 
@@ -161,7 +180,10 @@
 // older compilers.
 # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 4, 0))
 # define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0))
+# define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0))
 # define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
+# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
+    (!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
 
 # define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0))
 
@@ -199,6 +221,7 @@
 
 # define V8_HAS_DECLSPEC_ALIGN 1
 # define V8_HAS_DECLSPEC_DEPRECATED (_MSC_VER >= 1300)
+# define V8_HAS_DECLSPEC_NOINLINE 1
 
 # define V8_HAS___FORCEINLINE 1
 
@@ -218,6 +241,17 @@
 #endif
 
 
+// A macro used to tell the compiler to never inline a particular function.
+// Don't bother for debug builds.
+#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
+# define V8_NOINLINE(declarator) __attribute__((noinline)) declarator
+#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
+# define V8_NOINLINE(declarator) __declspec(noinline) declarator
+#else
+# define V8_NOINLINE(declarator) declarator
+#endif
+
+
 // A macro to mark classes or functions as deprecated.
 #if !V8_DISABLE_DEPRECATIONS && V8_HAS_ATTRIBUTE_DEPRECATED
 # define V8_DEPRECATED(declarator) declarator __attribute__((deprecated))
@@ -228,6 +262,16 @@
 #endif
 
 
+// Annotate a function indicating the caller must examine the return value.
+// Use like:
+//   int foo() V8_WARN_UNUSED_RESULT;
+#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
+# define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
+#endif
+
+
 // A macro to provide the compiler with branch prediction information.
 #if V8_HAS_BUILTIN_EXPECT
 # define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
diff --git a/src/api.cc b/src/api.cc
index 61cc520..9c0ac7b 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1049,25 +1049,8 @@
 }
 
 
-// TODO(dcarney): Remove this abstraction when old callbacks are removed.
-class CallHandlerHelper {
- public:
-  static inline void Set(Local<FunctionTemplate> function_template,
-                         InvocationCallback callback,
-                         v8::Handle<Value> data) {
-    function_template->SetCallHandlerInternal(callback, data);
-  }
-  static inline void Set(Local<FunctionTemplate> function_template,
-                         FunctionCallback callback,
-                         v8::Handle<Value> data) {
-    function_template->SetCallHandler(callback, data);
-  }
-};
-
-
-template<typename Callback>
-static Local<FunctionTemplate> FunctionTemplateNew(
-    Callback callback,
+Local<FunctionTemplate> FunctionTemplate::New(
+    FunctionCallback callback,
     v8::Handle<Value> data,
     v8::Handle<Signature> signature,
     int length) {
@@ -1085,7 +1068,7 @@
   obj->set_serial_number(i::Smi::FromInt(next_serial_number));
   if (callback != 0) {
     if (data.IsEmpty()) data = v8::Undefined();
-    CallHandlerHelper::Set(Utils::ToLocal(obj), callback, data);
+    Utils::ToLocal(obj)->SetCallHandler(callback, data);
   }
   obj->set_length(length);
   obj->set_undetectable(false);
@@ -1097,24 +1080,6 @@
 }
 
 
-Local<FunctionTemplate> FunctionTemplate::New(
-    InvocationCallback callback,
-    v8::Handle<Value> data,
-    v8::Handle<Signature> signature,
-    int length) {
-  return FunctionTemplateNew(callback, data, signature, length);
-}
-
-
-Local<FunctionTemplate> FunctionTemplate::New(
-    FunctionCallback callback,
-    v8::Handle<Value> data,
-    v8::Handle<Signature> signature,
-    int length) {
-  return FunctionTemplateNew(callback, data, signature, length);
-}
-
-
 Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
       int argc, Handle<FunctionTemplate> argv[]) {
   i::Isolate* isolate = i::Isolate::Current();
@@ -1304,11 +1269,9 @@
   } while (false)
 
 
-template<typename Callback>
-static void FunctionTemplateSetCallHandler(FunctionTemplate* function_template,
-                                           Callback callback_in,
-                                           v8::Handle<Value> data) {
-  i::Isolate* isolate = Utils::OpenHandle(function_template)->GetIsolate();
+void FunctionTemplate::SetCallHandler(FunctionCallback callback,
+                                      v8::Handle<Value> data) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
@@ -1316,28 +1279,12 @@
       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
   i::Handle<i::CallHandlerInfo> obj =
       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
-  FunctionCallback callback =
-      i::CallbackTable::Register(isolate, callback_in);
   SET_FIELD_WRAPPED(obj, set_callback, callback);
   if (data.IsEmpty()) data = v8::Undefined();
   obj->set_data(*Utils::OpenHandle(*data));
-  Utils::OpenHandle(function_template)->set_call_code(*obj);
+  Utils::OpenHandle(this)->set_call_code(*obj);
 }
 
-void FunctionTemplate::SetCallHandler(InvocationCallback callback,
-                                      v8::Handle<Value> data) {
-  FunctionTemplateSetCallHandler(this, callback, data);
-}
-
-void FunctionTemplate::SetCallHandlerInternal(InvocationCallback callback,
-                                              v8::Handle<Value> data) {
-  FunctionTemplateSetCallHandler(this, callback, data);
-}
-
-void FunctionTemplate::SetCallHandler(FunctionCallback callback,
-                                      v8::Handle<Value> data) {
-  FunctionTemplateSetCallHandler(this, callback, data);
-}
 
 static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
     i::Handle<i::AccessorInfo> obj,
@@ -1360,8 +1307,8 @@
 template<typename Getter, typename Setter>
 static i::Handle<i::AccessorInfo> MakeAccessorInfo(
       v8::Handle<String> name,
-      Getter getter_in,
-      Setter setter_in,
+      Getter getter,
+      Setter setter,
       v8::Handle<Value> data,
       v8::AccessControl settings,
       v8::PropertyAttribute attributes,
@@ -1369,11 +1316,7 @@
   i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
   i::Handle<i::ExecutableAccessorInfo> obj =
       isolate->factory()->NewExecutableAccessorInfo();
-  AccessorGetterCallback getter =
-      i::CallbackTable::Register(isolate, getter_in);
   SET_FIELD_WRAPPED(obj, set_getter, getter);
-  AccessorSetterCallback setter =
-      i::CallbackTable::Register(isolate, setter_in);
   SET_FIELD_WRAPPED(obj, set_setter, setter);
   if (data.IsEmpty()) data = v8::Undefined();
   obj->set_data(*Utils::OpenHandle(*data));
@@ -1451,124 +1394,14 @@
   Utils::OpenHandle(this)->set_read_only_prototype(true);
 }
 
-template<
-    typename Getter,
-    typename Setter,
-    typename Query,
-    typename Deleter,
-    typename Enumerator>
-static void SetNamedInstancePropertyHandler(
-      i::Handle<i::FunctionTemplateInfo> function_template,
-      Getter getter_in,
-      Setter setter_in,
-      Query query_in,
-      Deleter remover_in,
-      Enumerator enumerator_in,
-      Handle<Value> data) {
-  i::Isolate* isolate = function_template->GetIsolate();
-  if (IsDeadCheck(isolate,
-                  "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
+
+void FunctionTemplate::RemovePrototype() {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::FunctionTemplate::RemovePrototype()")) {
     return;
   }
   ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
-  i::Handle<i::InterceptorInfo> obj =
-      i::Handle<i::InterceptorInfo>::cast(struct_obj);
-
-  NamedPropertyGetterCallback getter =
-      i::CallbackTable::Register(isolate, getter_in);
-  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
-  NamedPropertySetterCallback setter =
-      i::CallbackTable::Register(isolate, setter_in);
-  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
-  NamedPropertyQueryCallback query =
-      i::CallbackTable::Register(isolate, query_in);
-  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
-  NamedPropertyDeleterCallback remover =
-      i::CallbackTable::Register(isolate, remover_in);
-  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
-  NamedPropertyEnumeratorCallback enumerator =
-      i::CallbackTable::Register(isolate, enumerator_in);
-  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
-
-  if (data.IsEmpty()) data = v8::Undefined();
-  obj->set_data(*Utils::OpenHandle(*data));
-  function_template->set_named_property_handler(*obj);
-}
-
-
-template<
-    typename Getter,
-    typename Setter,
-    typename Query,
-    typename Deleter,
-    typename Enumerator>
-static void SetIndexedInstancePropertyHandler(
-      i::Handle<i::FunctionTemplateInfo> function_template,
-      Getter getter_in,
-      Setter setter_in,
-      Query query_in,
-      Deleter remover_in,
-      Enumerator enumerator_in,
-      Handle<Value> data) {
-  i::Isolate* isolate = function_template->GetIsolate();
-  if (IsDeadCheck(isolate,
-        "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
-    return;
-  }
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
-  i::Handle<i::InterceptorInfo> obj =
-      i::Handle<i::InterceptorInfo>::cast(struct_obj);
-
-  IndexedPropertyGetterCallback getter =
-      i::CallbackTable::Register(isolate, getter_in);
-  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
-  IndexedPropertySetterCallback setter =
-      i::CallbackTable::Register(isolate, setter_in);
-  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
-  IndexedPropertyQueryCallback query =
-      i::CallbackTable::Register(isolate, query_in);
-  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
-  IndexedPropertyDeleterCallback remover =
-      i::CallbackTable::Register(isolate, remover_in);
-  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
-  IndexedPropertyEnumeratorCallback enumerator =
-      i::CallbackTable::Register(isolate, enumerator_in);
-  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
-
-  if (data.IsEmpty()) data = v8::Undefined();
-  obj->set_data(*Utils::OpenHandle(*data));
-  function_template->set_indexed_property_handler(*obj);
-}
-
-
-template<typename Callback>
-static void SetInstanceCallAsFunctionHandler(
-      i::Handle<i::FunctionTemplateInfo> function_template,
-      Callback callback_in,
-      Handle<Value> data) {
-  i::Isolate* isolate = function_template->GetIsolate();
-  if (IsDeadCheck(isolate,
-                  "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
-    return;
-  }
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
-  i::Handle<i::CallHandlerInfo> obj =
-      i::Handle<i::CallHandlerInfo>::cast(struct_obj);
-  FunctionCallback callback =
-      i::CallbackTable::Register(isolate, callback_in);
-  SET_FIELD_WRAPPED(obj, set_callback, callback);
-  if (data.IsEmpty()) data = v8::Undefined();
-  obj->set_data(*Utils::OpenHandle(*data));
-  function_template->set_instance_call_handler(*obj);
+  Utils::OpenHandle(this)->set_remove_prototype(true);
 }
 
 
@@ -1653,18 +1486,6 @@
 
 
 void ObjectTemplate::SetAccessor(v8::Handle<String> name,
-                                 AccessorGetter getter,
-                                 AccessorSetter setter,
-                                 v8::Handle<Value> data,
-                                 AccessControl settings,
-                                 PropertyAttribute attribute,
-                                 v8::Handle<AccessorSignature> signature) {
-  ObjectTemplateSetAccessor(
-      this, name, getter, setter, data, settings, attribute, signature);
-}
-
-
-void ObjectTemplate::SetAccessor(v8::Handle<String> name,
                                  AccessorGetterCallback getter,
                                  AccessorSetterCallback setter,
                                  v8::Handle<Value> data,
@@ -1687,52 +1508,6 @@
 }
 
 
-template<
-    typename Getter,
-    typename Setter,
-    typename Query,
-    typename Deleter,
-    typename Enumerator>
-static void ObjectTemplateSetNamedPropertyHandler(
-    ObjectTemplate* object_template,
-    Getter getter,
-    Setter setter,
-    Query query,
-    Deleter remover,
-    Enumerator enumerator,
-    Handle<Value> data) {
-  i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
-  if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
-    return;
-  }
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  EnsureConstructor(object_template);
-  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
-      Utils::OpenHandle(object_template)->constructor());
-  i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  SetNamedInstancePropertyHandler(cons,
-                                  getter,
-                                  setter,
-                                  query,
-                                  remover,
-                                  enumerator,
-                                  data);
-}
-
-
-void ObjectTemplate::SetNamedPropertyHandler(
-    NamedPropertyGetter getter,
-    NamedPropertySetter setter,
-    NamedPropertyQuery query,
-    NamedPropertyDeleter remover,
-    NamedPropertyEnumerator enumerator,
-    Handle<Value> data) {
-  ObjectTemplateSetNamedPropertyHandler(
-      this, getter, setter, query, remover, enumerator, data);
-}
-
-
 void ObjectTemplate::SetNamedPropertyHandler(
     NamedPropertyGetterCallback getter,
     NamedPropertySetterCallback setter,
@@ -1740,8 +1515,30 @@
     NamedPropertyDeleterCallback remover,
     NamedPropertyEnumeratorCallback enumerator,
     Handle<Value> data) {
-  ObjectTemplateSetNamedPropertyHandler(
-      this, getter, setter, query, remover, enumerator, data);
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
+    return;
+  }
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  EnsureConstructor(this);
+  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
+      Utils::OpenHandle(this)->constructor());
+  i::Handle<i::FunctionTemplateInfo> cons(constructor);
+  i::Handle<i::Struct> struct_obj =
+      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
+  i::Handle<i::InterceptorInfo> obj =
+      i::Handle<i::InterceptorInfo>::cast(struct_obj);
+
+  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
+  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
+  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
+  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
+  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+
+  if (data.IsEmpty()) data = v8::Undefined();
+  obj->set_data(*Utils::OpenHandle(*data));
+  cons->set_named_property_handler(*obj);
 }
 
 
@@ -1790,52 +1587,6 @@
 }
 
 
-template<
-    typename Getter,
-    typename Setter,
-    typename Query,
-    typename Deleter,
-    typename Enumerator>
-void ObjectTemplateSetIndexedPropertyHandler(
-      ObjectTemplate* object_template,
-      Getter getter,
-      Setter setter,
-      Query query,
-      Deleter remover,
-      Enumerator enumerator,
-      Handle<Value> data) {
-  i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
-  if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
-    return;
-  }
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  EnsureConstructor(object_template);
-  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
-      Utils::OpenHandle(object_template)->constructor());
-  i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  SetIndexedInstancePropertyHandler(cons,
-                                    getter,
-                                    setter,
-                                    query,
-                                    remover,
-                                    enumerator,
-                                    data);
-}
-
-
-void ObjectTemplate::SetIndexedPropertyHandler(
-      IndexedPropertyGetter getter,
-      IndexedPropertySetter setter,
-      IndexedPropertyQuery query,
-      IndexedPropertyDeleter remover,
-      IndexedPropertyEnumerator enumerator,
-      Handle<Value> data) {
-  ObjectTemplateSetIndexedPropertyHandler(
-      this, getter, setter, query, remover, enumerator, data);
-}
-
-
 void ObjectTemplate::SetIndexedPropertyHandler(
       IndexedPropertyGetterCallback getter,
       IndexedPropertySetterCallback setter,
@@ -1843,40 +1594,54 @@
       IndexedPropertyDeleterCallback remover,
       IndexedPropertyEnumeratorCallback enumerator,
       Handle<Value> data) {
-  ObjectTemplateSetIndexedPropertyHandler(
-      this, getter, setter, query, remover, enumerator, data);
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
+    return;
+  }
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  EnsureConstructor(this);
+  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
+      Utils::OpenHandle(this)->constructor());
+  i::Handle<i::FunctionTemplateInfo> cons(constructor);
+  i::Handle<i::Struct> struct_obj =
+      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
+  i::Handle<i::InterceptorInfo> obj =
+      i::Handle<i::InterceptorInfo>::cast(struct_obj);
+
+  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
+  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
+  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
+  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
+  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+
+  if (data.IsEmpty()) data = v8::Undefined();
+  obj->set_data(*Utils::OpenHandle(*data));
+  cons->set_indexed_property_handler(*obj);
 }
 
 
-template<typename Callback>
-static void ObjectTemplateSetCallAsFunctionHandler(
-    ObjectTemplate* object_template,
-    Callback callback,
-    Handle<Value> data) {
-  i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
+void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
+                                              Handle<Value> data) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
                   "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
     return;
   }
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(object_template);
+  EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
-      Utils::OpenHandle(object_template)->constructor());
+      Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  SetInstanceCallAsFunctionHandler(cons, callback, data);
-}
-
-
-void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
-                                              Handle<Value> data) {
-  return ObjectTemplateSetCallAsFunctionHandler(this, callback, data);
-}
-
-
-void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
-                                              Handle<Value> data) {
-  return ObjectTemplateSetCallAsFunctionHandler(this, callback, data);
+  i::Handle<i::Struct> struct_obj =
+      isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
+  i::Handle<i::CallHandlerInfo> obj =
+      i::Handle<i::CallHandlerInfo>::cast(struct_obj);
+  SET_FIELD_WRAPPED(obj, set_callback, callback);
+  if (data.IsEmpty()) data = v8::Undefined();
+  obj->set_data(*Utils::OpenHandle(*data));
+  cons->set_instance_call_handler(*obj);
 }
 
 
@@ -3843,17 +3608,6 @@
 
 
 bool Object::SetAccessor(Handle<String> name,
-                         AccessorGetter getter,
-                         AccessorSetter setter,
-                         v8::Handle<Value> data,
-                         AccessControl settings,
-                         PropertyAttribute attributes) {
-  return ObjectSetAccessor(
-      this, name, getter, setter, data, settings, attributes);
-}
-
-
-bool Object::SetAccessor(Handle<String> name,
                          AccessorGetterCallback getter,
                          AccessorSetterCallback setter,
                          v8::Handle<Value> data,
@@ -7255,37 +7009,6 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
-static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (isolate->debug_event_callback() != NULL) {
-    isolate->debug_event_callback()(event_details.GetEvent(),
-                                    event_details.GetExecutionState(),
-                                    event_details.GetEventData(),
-                                    event_details.GetCallbackData());
-  }
-}
-
-
-bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
-  ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
-  ENTER_V8(isolate);
-
-  isolate->set_debug_event_callback(that);
-
-  i::HandleScope scope(isolate);
-  i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
-  if (that != NULL) {
-    foreign =
-        isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
-  }
-  isolate->debugger()->SetEventListener(foreign,
-                                        Utils::OpenHandle(*data, true));
-  return true;
-}
-
-
 bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
@@ -7345,35 +7068,6 @@
 }
 
 
-static void MessageHandlerWrapper(const v8::Debug::Message& message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (isolate->message_handler()) {
-    v8::String::Value json(message.GetJSON());
-    (isolate->message_handler())(*json, json.length(), message.GetClientData());
-  }
-}
-
-
-void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
-                              bool message_handler_thread) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
-  ENTER_V8(isolate);
-
-  // Message handler thread not supported any more. Parameter temporally left in
-  // the API for client compatibility reasons.
-  CHECK(!message_handler_thread);
-
-  // TODO(sgjesse) support the old message handler API through a simple wrapper.
-  isolate->set_message_handler(handler);
-  if (handler != NULL) {
-    isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
-  } else {
-    isolate->debugger()->SetMessageHandler(NULL);
-  }
-}
-
-
 void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
@@ -7541,27 +7235,6 @@
 }
 
 
-double CpuProfileNode::GetTotalTime() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
-  return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
-}
-
-
-double CpuProfileNode::GetSelfTime() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
-  return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
-}
-
-
-double CpuProfileNode::GetTotalSamplesCount() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
-  return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
-}
-
-
 double CpuProfileNode::GetSelfSamplesCount() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
@@ -8172,20 +7845,6 @@
 }
 
 
-v8::Handle<v8::Value> InvokeAccessorGetter(
-    v8::Local<v8::String> property,
-    const v8::AccessorInfo& info,
-    v8::AccessorGetter getter) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
-  Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
-      getter));
-  // Leaving JavaScript.
-  VMState<EXTERNAL> state(isolate);
-  ExternalCallbackScope call_scope(isolate, getter_address);
-  return getter(property, info);
-}
-
-
 void InvokeAccessorGetterCallback(
     v8::Local<v8::String> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
@@ -8200,18 +7859,6 @@
 }
 
 
-v8::Handle<v8::Value> InvokeInvocationCallback(
-    const v8::Arguments& args,
-    v8::InvocationCallback callback) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate());
-  Address callback_address =
-      reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
-  VMState<EXTERNAL> state(isolate);
-  ExternalCallbackScope call_scope(isolate, callback_address);
-  return callback(args);
-}
-
-
 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
                             v8::FunctionCallback callback) {
   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
diff --git a/src/api.h b/src/api.h
index 0f33bc8..63a29e4 100644
--- a/src/api.h
+++ b/src/api.h
@@ -690,19 +690,11 @@
 
 // Interceptor functions called from generated inline caches to notify
 // CPU profiler that external callbacks are invoked.
-v8::Handle<v8::Value> InvokeAccessorGetter(
-    v8::Local<v8::String> property,
-    const v8::AccessorInfo& info,
-    v8::AccessorGetter getter);
-
-
 void InvokeAccessorGetterCallback(
     v8::Local<v8::String> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
     v8::AccessorGetterCallback getter);
 
-v8::Handle<v8::Value> InvokeInvocationCallback(const v8::Arguments& args,
-                                              v8::InvocationCallback callback);
 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
                             v8::FunctionCallback callback);
 
diff --git a/src/apinatives.js b/src/apinatives.js
index ace882b..7adeb7e 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -75,22 +75,26 @@
       var fun = %CreateApiFunction(data);
       if (name) %FunctionSetName(fun, name);
       cache[serialNumber] = fun;
-      var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
       var flags = %GetTemplateField(data, kApiFlagOffset);
-      // Note: Do not directly use an object template as a condition, our
-      // internal ToBoolean doesn't handle that!
-      fun.prototype = typeof prototype === 'undefined' ?
-          {} : Instantiate(prototype);
-      if (flags & (1 << kReadOnlyPrototypeBit)) {
-        %FunctionSetReadOnlyPrototype(fun);
-      }
-      %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
-      var parent = %GetTemplateField(data, kApiParentTemplateOffset);
-      // Note: Do not directly use a function template as a condition, our
-      // internal ToBoolean doesn't handle that!
-      if (!(typeof parent === 'undefined')) {
-        var parent_fun = Instantiate(parent);
-        %SetPrototype(fun.prototype, parent_fun.prototype);
+      if (flags & (1 << kRemovePrototypeBit)) {
+        %FunctionRemovePrototype(fun);
+      } else {
+        var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+        // Note: Do not directly use an object template as a condition, our
+        // internal ToBoolean doesn't handle that!
+        fun.prototype = typeof prototype === 'undefined' ?
+            {} : Instantiate(prototype);
+        if (flags & (1 << kReadOnlyPrototypeBit)) {
+          %FunctionSetReadOnlyPrototype(fun);
+        }
+        %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
+        var parent = %GetTemplateField(data, kApiParentTemplateOffset);
+        // Note: Do not directly use a function template as a condition, our
+        // internal ToBoolean doesn't handle that!
+        if (!(typeof parent === 'undefined')) {
+          var parent_fun = Instantiate(parent);
+          %SetPrototype(fun.prototype, parent_fun.prototype);
+        }
       }
       ConfigureTemplateInstance(fun, data);
     } catch (e) {
diff --git a/src/arguments.cc b/src/arguments.cc
index 11d9279..2878057 100644
--- a/src/arguments.cc
+++ b/src/arguments.cc
@@ -34,49 +34,6 @@
 namespace internal {
 
 
-static bool Match(void* a, void* b) {
-  return a == b;
-}
-
-
-static uint32_t Hash(void* function) {
-  uintptr_t as_int = reinterpret_cast<uintptr_t>(function);
-  if (sizeof(function) == 4) return static_cast<uint32_t>(as_int);
-  uint64_t as_64 = static_cast<uint64_t>(as_int);
-  return
-      static_cast<uint32_t>(as_64 >> 32) ^
-      static_cast<uint32_t>(as_64);
-}
-
-
-CallbackTable::CallbackTable(): map_(Match, 64) {}
-
-
-bool CallbackTable::Contains(void* function) {
-  ASSERT(function != NULL);
-  return map_.Lookup(function, Hash(function), false) != NULL;
-}
-
-
-void CallbackTable::InsertCallback(Isolate* isolate,
-                           void* function,
-                           bool returns_void) {
-  if (function == NULL) return;
-  // Don't store for performance.
-  if (kStoreVoidFunctions != returns_void) return;
-  CallbackTable* table = isolate->callback_table();
-  if (table == NULL) {
-    table = new CallbackTable();
-    isolate->set_callback_table(table);
-  }
-  typedef HashMap::Entry Entry;
-  Entry* entry = table->map_.Lookup(function, Hash(function), true);
-  ASSERT(entry != NULL);
-  ASSERT(entry->value == NULL || entry->value == function);
-  entry->value = function;
-}
-
-
 template<typename T>
 template<typename V>
 v8::Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
@@ -88,110 +45,67 @@
 }
 
 
-v8::Handle<v8::Value> FunctionCallbackArguments::Call(InvocationCallback f) {
+v8::Handle<v8::Value> FunctionCallbackArguments::Call(FunctionCallback f) {
   Isolate* isolate = this->isolate();
-  void* f_as_void = CallbackTable::FunctionToVoidPtr(f);
-  bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);
   VMState<EXTERNAL> state(isolate);
   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
-  if (new_style) {
-    FunctionCallback c = reinterpret_cast<FunctionCallback>(f);
-    FunctionCallbackInfo<v8::Value> info(end(),
-                                         argv_,
-                                         argc_,
-                                         is_construct_call_);
-    c(info);
-  } else {
-    v8::Arguments args(end(),
-                       argv_,
-                       argc_,
-                       is_construct_call_);
-    v8::Handle<v8::Value> return_value = f(args);
-    if (!return_value.IsEmpty()) return return_value;
-  }
+  FunctionCallbackInfo<v8::Value> info(end(),
+                                       argv_,
+                                       argc_,
+                                       is_construct_call_);
+  f(info);
   return GetReturnValue<v8::Value>(isolate);
 }
 
 
-#define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue)                    \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f) {       \
+#define WRITE_CALL_0(Function, ReturnValue)                                    \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f) {          \
   Isolate* isolate = this->isolate();                                          \
-  void* f_as_void = CallbackTable::FunctionToVoidPtr(f);                       \
-  bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);             \
   VMState<EXTERNAL> state(isolate);                                            \
   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));                 \
-  if (new_style) {                                                             \
-    NewFunction c = reinterpret_cast<NewFunction>(f);                          \
-    PropertyCallbackInfo<ReturnValue> info(end());                             \
-    c(info);                                                                   \
-  } else {                                                                     \
-    v8::AccessorInfo info(end());                                              \
-    v8::Handle<ReturnValue> return_value = f(info);                            \
-    if (!return_value.IsEmpty()) return return_value;                          \
-  }                                                                            \
+  PropertyCallbackInfo<ReturnValue> info(end());                               \
+  f(info);                                                                     \
   return GetReturnValue<ReturnValue>(isolate);                                 \
 }
 
-#define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1)              \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f,         \
+
+#define WRITE_CALL_1(Function, ReturnValue, Arg1)                              \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f,            \
                                                         Arg1 arg1) {           \
   Isolate* isolate = this->isolate();                                          \
-  void* f_as_void = CallbackTable::FunctionToVoidPtr(f);                       \
-  bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);             \
   VMState<EXTERNAL> state(isolate);                                            \
   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));                 \
-  if (new_style) {                                                             \
-    NewFunction c = reinterpret_cast<NewFunction>(f);                          \
-    PropertyCallbackInfo<ReturnValue> info(end());                             \
-    c(arg1, info);                                                             \
-  } else {                                                                     \
-    v8::AccessorInfo info(end());                                              \
-    v8::Handle<ReturnValue> return_value = f(arg1, info);                      \
-    if (!return_value.IsEmpty()) return return_value;                          \
-  }                                                                            \
+  PropertyCallbackInfo<ReturnValue> info(end());                               \
+  f(arg1, info);                                                               \
   return GetReturnValue<ReturnValue>(isolate);                                 \
 }
 
-#define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2)        \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f,         \
+
+#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2)                        \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f,            \
                                                         Arg1 arg1,             \
                                                         Arg2 arg2) {           \
   Isolate* isolate = this->isolate();                                          \
-  void* f_as_void = CallbackTable::FunctionToVoidPtr(f);                       \
-  bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);             \
   VMState<EXTERNAL> state(isolate);                                            \
   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));                 \
-  if (new_style) {                                                             \
-    NewFunction c = reinterpret_cast<NewFunction>(f);                          \
-    PropertyCallbackInfo<ReturnValue> info(end());                             \
-    c(arg1, arg2, info);                                                       \
-  } else {                                                                     \
-    v8::AccessorInfo info(end());                                              \
-    v8::Handle<ReturnValue> return_value = f(arg1, arg2, info);                \
-    if (!return_value.IsEmpty()) return return_value;                          \
-  }                                                                            \
+  PropertyCallbackInfo<ReturnValue> info(end());                               \
+  f(arg1, arg2, info);                                                         \
   return GetReturnValue<ReturnValue>(isolate);                                 \
 }
 
-#define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2)   \
-void PropertyCallbackArguments::Call(OldFunction f,                            \
+
+#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2)                   \
+void PropertyCallbackArguments::Call(Function f,                               \
                                      Arg1 arg1,                                \
                                      Arg2 arg2) {                              \
   Isolate* isolate = this->isolate();                                          \
-  void* f_as_void = CallbackTable::FunctionToVoidPtr(f);                       \
-  bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);             \
   VMState<EXTERNAL> state(isolate);                                            \
   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));                 \
-  if (new_style) {                                                             \
-    NewFunction c = reinterpret_cast<NewFunction>(f);                          \
-    PropertyCallbackInfo<ReturnValue> info(end());                             \
-    c(arg1, arg2, info);                                                       \
-  } else {                                                                     \
-    v8::AccessorInfo info(end());                                              \
-    f(arg1, arg2, info);                                                       \
-  }                                                                            \
+  PropertyCallbackInfo<ReturnValue> info(end());                               \
+  f(arg1, arg2, info);                                                         \
 }
 
+
 FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
 FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
 FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2)
diff --git a/src/arguments.h b/src/arguments.h
index f9dca11..169528b 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -83,116 +83,49 @@
 };
 
 
-// mappings from old property callbacks to new ones
-// F(old name, new name, return value, parameters...)
-//
+// For each type of callback, we have a list of arguments
+// They are used to generate the Call() functions below
 // These aren't included in the list as they have duplicate signatures
-// F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback, ...)
-// F(NamedPropertyGetter, NamedPropertyGetterCallback, ...)
+// F(NamedPropertyEnumeratorCallback, ...)
+// F(NamedPropertyGetterCallback, ...)
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
-  F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback, v8::Array) \
+  F(IndexedPropertyEnumeratorCallback, v8::Array) \
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
-  F(AccessorGetter, AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
-  F(NamedPropertyQuery, \
-    NamedPropertyQueryCallback, \
+  F(AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
+  F(NamedPropertyQueryCallback, \
     v8::Integer, \
     v8::Local<v8::String>) \
-  F(NamedPropertyDeleter, \
-    NamedPropertyDeleterCallback, \
+  F(NamedPropertyDeleterCallback, \
     v8::Boolean, \
     v8::Local<v8::String>) \
-  F(IndexedPropertyGetter, \
-    IndexedPropertyGetterCallback, \
+  F(IndexedPropertyGetterCallback, \
     v8::Value, \
     uint32_t) \
-  F(IndexedPropertyQuery, \
-    IndexedPropertyQueryCallback, \
+  F(IndexedPropertyQueryCallback, \
     v8::Integer, \
     uint32_t) \
-  F(IndexedPropertyDeleter, \
-    IndexedPropertyDeleterCallback, \
+  F(IndexedPropertyDeleterCallback, \
     v8::Boolean, \
     uint32_t) \
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
-  F(NamedPropertySetter, \
-    NamedPropertySetterCallback, \
+  F(NamedPropertySetterCallback, \
     v8::Value, \
     v8::Local<v8::String>, \
     v8::Local<v8::Value>) \
-  F(IndexedPropertySetter, \
-    IndexedPropertySetterCallback, \
+  F(IndexedPropertySetterCallback, \
     v8::Value, \
     uint32_t, \
     v8::Local<v8::Value>) \
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
-  F(AccessorSetter, \
-    AccessorSetterCallback, \
+  F(AccessorSetterCallback, \
     void, \
     v8::Local<v8::String>, \
     v8::Local<v8::Value>) \
 
-// All property callbacks as well as invocation callbacks
-#define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \
-  F(InvocationCallback, FunctionCallback) \
-  F(AccessorGetter, AccessorGetterCallback) \
-  F(AccessorSetter, AccessorSetterCallback) \
-  F(NamedPropertySetter, NamedPropertySetterCallback) \
-  F(NamedPropertyQuery, NamedPropertyQueryCallback) \
-  F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \
-  F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \
-  F(IndexedPropertySetter, IndexedPropertySetterCallback) \
-  F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \
-  F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \
-  F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \
-
-
-// TODO(dcarney): Remove this class when old callbacks are gone.
-class CallbackTable {
- public:
-  static const bool kStoreVoidFunctions = false;
-  static inline bool ReturnsVoid(Isolate* isolate, void* function) {
-    CallbackTable* table = isolate->callback_table();
-    bool contains =
-        table != NULL &&
-        table->map_.occupancy() != 0 &&
-        table->Contains(function);
-    return contains == kStoreVoidFunctions;
-  }
-
-  STATIC_ASSERT(sizeof(intptr_t) == sizeof(AccessorGetterCallback));
-
-  template<typename F>
-  static inline void* FunctionToVoidPtr(F function) {
-    return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(function));
-  }
-
-#define WRITE_REGISTER(OldFunction, NewFunction)                    \
-  static NewFunction Register(Isolate* isolate, OldFunction f) {    \
-    InsertCallback(isolate, FunctionToVoidPtr(f), false);           \
-    return reinterpret_cast<NewFunction>(f);                        \
-  }                                                                 \
-                                                                    \
-  static NewFunction Register(Isolate* isolate, NewFunction f) {    \
-    InsertCallback(isolate, FunctionToVoidPtr(f), true);            \
-    return f;                                                       \
-  }
-  FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
-#undef WRITE_REGISTER
-
- private:
-  CallbackTable();
-  bool Contains(void* function);
-  static void InsertCallback(Isolate* isolate,
-                             void* function,
-                             bool returns_void);
-  HashMap map_;
-  DISALLOW_COPY_AND_ASSIGN(CallbackTable);
-};
-
 
 // Custom arguments replicate a small segment of stack that can be
 // accessed through an Arguments object the same way the actual stack
@@ -218,7 +151,6 @@
 
   typedef CustomArgumentsBase<T::kArgsLength> Super;
   ~CustomArguments() {
-    // TODO(dcarney): create a new zap value for this.
     this->end()[kReturnValueOffset] =
         reinterpret_cast<Object*>(kHandleZapValue);
   }
@@ -271,17 +203,17 @@
    * and used if it's been set to anything inside the callback.
    * New style callbacks always use the return value.
    */
-#define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue)                  \
-  v8::Handle<ReturnValue> Call(OldFunction f);                               \
+#define WRITE_CALL_0(Function, ReturnValue)                                  \
+  v8::Handle<ReturnValue> Call(Function f);                                  \
 
-#define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1)            \
-  v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1);                    \
+#define WRITE_CALL_1(Function, ReturnValue, Arg1)                            \
+  v8::Handle<ReturnValue> Call(Function f, Arg1 arg1);                       \
 
-#define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2)      \
-  v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1, Arg2 arg2);         \
+#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2)                      \
+  v8::Handle<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2);            \
 
-#define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
-  void Call(OldFunction f, Arg1 arg1, Arg2 arg2);                            \
+#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2)                 \
+  void Call(Function f, Arg1 arg1, Arg2 arg2);                               \
 
 FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
 FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
@@ -336,7 +268,7 @@
    * and used if it's been set to anything inside the callback.
    * New style callbacks always use the return value.
    */
-  v8::Handle<v8::Value> Call(InvocationCallback f);
+  v8::Handle<v8::Value> Call(FunctionCallback f);
 
  private:
   internal::Object** argv_;
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 3dbdb2f..9a4d6e5 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -38,6 +38,17 @@
 namespace internal {
 
 
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { r2 };
+  descriptor->register_param_count_ = 1;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ =
+      Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
 void ToNumberStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -309,134 +320,6 @@
 }
 
 
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
-  // Create a new closure from the given function info in new
-  // space. Set the context to the current context in cp.
-  Counters* counters = masm->isolate()->counters();
-
-  Label gc;
-
-  // Pop the function info from the stack.
-  __ pop(r3);
-
-  // Attempt to allocate new JSFunction in new space.
-  __ Allocate(JSFunction::kSize, r0, r1, r2, &gc, TAG_OBJECT);
-
-  __ IncrementCounter(counters->fast_new_closure_total(), 1, r6, r7);
-
-  int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
-  // Compute the function map in the current native context and set that
-  // as the map of the allocated object.
-  __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
-  __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
-  __ ldr(r5, MemOperand(r2, Context::SlotOffset(map_index)));
-  __ str(r5, FieldMemOperand(r0, HeapObject::kMapOffset));
-
-  // Initialize the rest of the function. We don't have to update the
-  // write barrier because the allocated object is in new space.
-  __ LoadRoot(r1, Heap::kEmptyFixedArrayRootIndex);
-  __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
-  __ str(r1, FieldMemOperand(r0, JSObject::kPropertiesOffset));
-  __ str(r1, FieldMemOperand(r0, JSObject::kElementsOffset));
-  __ str(r5, FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
-  __ str(r3, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
-  __ str(cp, FieldMemOperand(r0, JSFunction::kContextOffset));
-  __ str(r1, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
-
-  // Initialize the code pointer in the function to be the one
-  // found in the shared function info object.
-  // But first check if there is an optimized version for our context.
-  Label check_optimized;
-  Label install_unoptimized;
-  if (FLAG_cache_optimized_code) {
-    __ ldr(r1,
-           FieldMemOperand(r3, SharedFunctionInfo::kOptimizedCodeMapOffset));
-    __ tst(r1, r1);
-    __ b(ne, &check_optimized);
-  }
-  __ bind(&install_unoptimized);
-  __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
-  __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
-  __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
-  __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ str(r3, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
-
-  // Return result. The argument function info has been popped already.
-  __ Ret();
-
-  __ bind(&check_optimized);
-
-  __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, r6, r7);
-
-  // r2 holds native context, r1 points to fixed array of 3-element entries
-  // (native context, optimized code, literals).
-  // The optimized code map must never be empty, so check the first elements.
-  Label install_optimized;
-  // Speculatively move code object into r4.
-  __ ldr(r4, FieldMemOperand(r1, SharedFunctionInfo::kFirstCodeSlot));
-  __ ldr(r5, FieldMemOperand(r1, SharedFunctionInfo::kFirstContextSlot));
-  __ cmp(r2, r5);
-  __ b(eq, &install_optimized);
-
-  // Iterate through the rest of map backwards.  r4 holds an index as a Smi.
-  Label loop;
-  __ ldr(r4, FieldMemOperand(r1, FixedArray::kLengthOffset));
-  __ bind(&loop);
-  // Do not double check first entry.
-  __ cmp(r4, Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
-  __ b(eq, &install_unoptimized);
-  __ sub(r4, r4, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
-  __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
-  __ ldr(r5, MemOperand(r5));
-  __ cmp(r2, r5);
-  __ b(ne, &loop);
-  // Hit: fetch the optimized code.
-  __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
-  __ add(r5, r5, Operand(kPointerSize));
-  __ ldr(r4, MemOperand(r5));
-
-  __ bind(&install_optimized);
-  __ IncrementCounter(counters->fast_new_closure_install_optimized(),
-                      1, r6, r7);
-
-  // TODO(fschneider): Idea: store proper code pointers in the map and either
-  // unmangle them on marking or do nothing as the whole map is discarded on
-  // major GC anyway.
-  __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ str(r4, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
-
-  // Now link a function into a list of optimized functions.
-  __ ldr(r4, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
-
-  __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
-  // No need for write barrier as JSFunction (eax) is in the new space.
-
-  __ str(r0, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
-  // Store JSFunction (eax) into edx before issuing write barrier as
-  // it clobbers all the registers passed.
-  __ mov(r4, r0);
-  __ RecordWriteContextSlot(
-      r2,
-      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
-      r4,
-      r1,
-      kLRHasNotBeenSaved,
-      kDontSaveFPRegs);
-
-  // Return result. The argument function info has been popped already.
-  __ Ret();
-
-  // Create a new closure through the slower runtime call.
-  __ bind(&gc);
-  __ LoadRoot(r4, Heap::kFalseValueRootIndex);
-  __ Push(cp, r3, r4);
-  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
 void FastNewContextStub::Generate(MacroAssembler* masm) {
   // Try to allocate the context in new space.
   Label gc;
@@ -4530,6 +4413,7 @@
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
+    __ SmiTag(r0);
     __ push(r0);
     __ push(r1);
     __ push(r2);
@@ -4540,6 +4424,7 @@
     __ pop(r2);
     __ pop(r1);
     __ pop(r0);
+    __ SmiUntag(r0);
   }
   __ b(&done);
 
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index ecdf638..acffaa3 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -50,9 +50,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
-#ifndef WIN32
-#include <stdint.h>
-#endif
 
 #include "v8.h"
 
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2243296..3400248 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1330,8 +1330,7 @@
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
     FastNewClosureStub stub(info->language_mode(), info->is_generator());
-    __ mov(r0, Operand(info));
-    __ push(r0);
+    __ mov(r2, Operand(info));
     __ CallStub(&stub);
   } else {
     __ mov(r0, Operand(info));
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 7c02a62..5978fad 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -260,6 +260,14 @@
 }
 
 
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  function()->PrintTo(stream);
+  stream->Add(".code_entry = ");
+  code_object()->PrintTo(stream);
+}
+
+
 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
   stream->Add(" = ");
   base_object()->PrintTo(stream);
@@ -1079,6 +1087,14 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+    HStoreCodeEntry* store_code_entry) {
+  LOperand* function = UseRegister(store_code_entry->function());
+  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+  return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
     HInnerAllocatedObject* inner_object) {
   LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1909,11 +1925,12 @@
       ASSERT(to.IsInteger32());
       LOperand* value = NULL;
       LInstruction* res = NULL;
-      if (instr->value()->type().IsSmi()) {
-        value = UseRegisterAtStart(instr->value());
+      HValue* val = instr->value();
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        value = UseRegisterAtStart(val);
         res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
-        value = UseRegister(instr->value());
+        value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = FixedTemp(d11);
         res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
@@ -2435,8 +2452,7 @@
 
 
 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  instr->ReplayEnvironment(env);
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // There are no real uses of a captured object.
   return NULL;
@@ -2484,20 +2500,7 @@
 
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  ASSERT(env != NULL);
-
-  env->set_ast_id(instr->ast_id());
-
-  env->Drop(instr->pop_count());
-  for (int i = instr->values()->length() - 1; i >= 0; --i) {
-    HValue* value = instr->values()->at(i);
-    if (instr->HasAssignedIndexAt(i)) {
-      env->Bind(instr->GetAssignedIndexAt(i), value);
-    } else {
-      env->Push(value);
-    }
-  }
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 316df7d..90fb117 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -162,6 +162,7 @@
   V(SmiTag)                                     \
   V(SmiUntag)                                   \
   V(StackCheck)                                 \
+  V(StoreCodeEntry)                             \
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
@@ -1753,7 +1754,24 @@
 };
 
 
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+    inputs_[0] = function;
+    temps_[0] = code_object;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* code_object() { return temps_[0]; }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LInnerAllocatedObject(LOperand* base_object) {
     inputs_[0] = base_object;
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index f3f8b50..e34e15b 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -431,7 +431,7 @@
     } else if (r.IsDouble()) {
       Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
     } else {
-      ASSERT(r.IsTagged());
+      ASSERT(r.IsSmiOrTagged());
       __ LoadObject(scratch, literal);
     }
     return scratch;
@@ -1584,10 +1584,7 @@
     instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
 
   if (right_op->IsConstantOperand() && !can_overflow) {
-    // Use optimized code for specific constants.
-    int32_t constant = ToRepresentation(
-        LConstantOperand::cast(right_op),
-        instr->hydrogen()->right()->representation());
+    int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
 
     if (bailout_on_minus_zero && (constant < 0)) {
       // The case of a null constant will be handled separately.
@@ -4146,6 +4143,15 @@
 }
 
 
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+  Register function = ToRegister(instr->function());
+  Register code_object = ToRegister(instr->code_object());
+  __ add(code_object, code_object, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ str(code_object,
+         FieldMemOperand(function, JSFunction::kCodeEntryOffset));
+}
+
+
 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
   Register result = ToRegister(instr->result());
   Register base = ToRegister(instr->base_object());
@@ -5417,8 +5423,7 @@
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
     FastNewClosureStub stub(instr->hydrogen()->language_mode(),
                             instr->hydrogen()->is_generator());
-    __ mov(r1, Operand(instr->hydrogen()->shared_info()));
-    __ push(r1);
+    __ mov(r2, Operand(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   } else {
     __ mov(r2, Operand(instr->hydrogen()->shared_info()));
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 16ba89c..7628f23 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -2285,7 +2285,6 @@
                                               ExternalReference thunk_ref,
                                               Register thunk_last_arg,
                                               int stack_space,
-                                              bool returns_handle,
                                               int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
@@ -2354,15 +2353,6 @@
   Label leave_exit_frame;
   Label return_value_loaded;
 
-  if (returns_handle) {
-    Label load_return_value;
-    cmp(r0, Operand::Zero());
-    b(eq, &load_return_value);
-    // derefernce returned value
-    ldr(r0, MemOperand(r0));
-    b(&return_value_loaded);
-    bind(&load_return_value);
-  }
   // load value from ReturnValue
   ldr(r0, MemOperand(fp, return_value_offset*kPointerSize));
   bind(&return_value_loaded);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index f3716c2..cff9ac7 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1111,7 +1111,6 @@
                                 ExternalReference thunk_ref,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                bool returns_handle,
                                 int return_value_offset_from_fp);
 
   // Jump to a runtime routine.
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index c9e3616..def1818 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -1686,20 +1686,12 @@
 
 // This signature supports direct call in to API function native callback
 // (refer to InvocationCallback in v8.h).
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
-    int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
 
 // This signature supports direct call to accessor getter callback.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
-                                                                  int32_t arg1);
-typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
-                                                    int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
-    int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(
     int32_t arg0, int32_t arg1, int32_t arg2);
 
 // Software interrupt instructions are used by the simulator to call into the
@@ -1839,9 +1831,7 @@
             break;
           }
         }
-      } else if (
-          redirection->type() == ExternalReference::DIRECT_API_CALL ||
-          redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
+      } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
           PrintF("Call to host function at %p args %08x",
               reinterpret_cast<void*>(external), arg0);
@@ -1851,22 +1841,11 @@
           PrintF("\n");
         }
         CHECK(stack_aligned);
-        if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
-          SimulatorRuntimeDirectApiCall target =
-              reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
-          v8::Handle<v8::Value> result = target(arg0);
-          if (::v8::internal::FLAG_trace_sim) {
-            PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
-          }
-          set_register(r0, reinterpret_cast<int32_t>(*result));
-        } else {
-          SimulatorRuntimeDirectApiCallNew target =
-              reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
-          target(arg0);
-        }
+        SimulatorRuntimeDirectApiCall target =
+            reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+        target(arg0);
       } else if (
-          redirection->type() == ExternalReference::PROFILING_API_CALL ||
-          redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
+          redirection->type() == ExternalReference::PROFILING_API_CALL) {
         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
           PrintF("Call to host function at %p args %08x %08x",
               reinterpret_cast<void*>(external), arg0, arg1);
@@ -1876,22 +1855,11 @@
           PrintF("\n");
         }
         CHECK(stack_aligned);
-        if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
-          SimulatorRuntimeProfilingApiCall target =
-              reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
-          v8::Handle<v8::Value> result = target(arg0, arg1);
-          if (::v8::internal::FLAG_trace_sim) {
-            PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
-          }
-          set_register(r0, reinterpret_cast<int32_t>(*result));
-        } else {
-          SimulatorRuntimeProfilingApiCallNew target =
-              reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
-          target(arg0, arg1);
-        }
+        SimulatorRuntimeProfilingApiCall target =
+            reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+        target(arg0, arg1);
       } else if (
-          redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
-          redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
+          redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
           PrintF("Call to host function at %p args %08x %08x",
               reinterpret_cast<void*>(external), arg0, arg1);
@@ -1901,22 +1869,11 @@
           PrintF("\n");
         }
         CHECK(stack_aligned);
-        if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
-          SimulatorRuntimeDirectGetterCall target =
-              reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
-          v8::Handle<v8::Value> result = target(arg0, arg1);
-          if (::v8::internal::FLAG_trace_sim) {
-            PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
-          }
-          set_register(r0, reinterpret_cast<int32_t>(*result));
-        } else {
-          SimulatorRuntimeDirectGetterCallNew target =
-              reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
-          target(arg0, arg1);
-        }
+        SimulatorRuntimeDirectGetterCall target =
+            reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+        target(arg0, arg1);
       } else if (
-          redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
-          redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
+          redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
           PrintF("Call to host function at %p args %08x %08x %08x",
               reinterpret_cast<void*>(external), arg0, arg1, arg2);
@@ -1926,20 +1883,10 @@
           PrintF("\n");
         }
         CHECK(stack_aligned);
-        if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
-          SimulatorRuntimeProfilingGetterCall target =
-              reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
-          v8::Handle<v8::Value> result = target(arg0, arg1, arg2);
-          if (::v8::internal::FLAG_trace_sim) {
-            PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
-          }
-          set_register(r0, reinterpret_cast<int32_t>(*result));
-        } else {
-          SimulatorRuntimeProfilingGetterCallNew target =
-              reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(
-                  external);
-          target(arg0, arg1, arg2);
-        }
+        SimulatorRuntimeProfilingGetterCall target =
+            reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
+                external);
+        target(arg0, arg1, arg2);
       } else {
         // builtin call.
         ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index ea28a34..7605525 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -903,23 +903,13 @@
 
   const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
   ApiFunction fun(function_address);
-  ExternalReference::Type type =
-      returns_handle ?
-          ExternalReference::DIRECT_API_CALL :
-          ExternalReference::DIRECT_API_CALL_NEW;
+  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
   ExternalReference ref = ExternalReference(&fun,
                                             type,
                                             masm->isolate());
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeInvocationCallback)
-      : FUNCTION_ADDR(&InvokeFunctionCallback);
-  ExternalReference::Type thunk_type =
-      returns_handle ?
-          ExternalReference::PROFILING_API_CALL :
-          ExternalReference::PROFILING_API_CALL_NEW;
+  Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+  ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
   ApiFunction thunk_fun(thunk_address);
   ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
       masm->isolate());
@@ -930,7 +920,6 @@
                               thunk_ref,
                               r1,
                               kStackUnwindSpace,
-                              returns_handle,
                               kFastApiCallArguments + 1);
 }
 
@@ -1424,23 +1413,14 @@
 
   const int kStackUnwindSpace = kFastApiCallArguments + 1;
   Address getter_address = v8::ToCData<Address>(callback->getter());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(isolate(), getter_address);
 
   ApiFunction fun(getter_address);
-  ExternalReference::Type type =
-      returns_handle ?
-          ExternalReference::DIRECT_GETTER_CALL :
-          ExternalReference::DIRECT_GETTER_CALL_NEW;
+  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
   ExternalReference ref = ExternalReference(&fun, type, isolate());
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeAccessorGetter)
-      : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
   ExternalReference::Type thunk_type =
-      returns_handle ?
-          ExternalReference::PROFILING_GETTER_CALL :
-          ExternalReference::PROFILING_GETTER_CALL_NEW;
+      ExternalReference::PROFILING_GETTER_CALL;
   ApiFunction thunk_fun(thunk_address);
   ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
       isolate());
@@ -1449,7 +1429,6 @@
                               thunk_ref,
                               r2,
                               kStackUnwindSpace,
-                              returns_handle,
                               5);
 }
 
diff --git a/src/assembler.h b/src/assembler.h
index d70d5aa..b358136 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -644,38 +644,21 @@
     BUILTIN_FP_INT_CALL,
 
     // Direct call to API function callback.
-    // Handle<Value> f(v8::Arguments&)
+    // void f(v8::FunctionCallbackInfo&)
     DIRECT_API_CALL,
 
-    // Call to invocation callback via InvokeInvocationCallback.
-    // Handle<Value> f(v8::Arguments&, v8::InvocationCallback)
+    // Call to function callback via InvokeFunctionCallback.
+    // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
     PROFILING_API_CALL,
 
-    // Direct call to API function callback.
-    // void f(v8::Arguments&)
-    DIRECT_API_CALL_NEW,
-
-    // Call to function callback via InvokeFunctionCallback.
-    // void f(v8::Arguments&, v8::FunctionCallback)
-    PROFILING_API_CALL_NEW,
-
     // Direct call to accessor getter callback.
-    // Handle<value> f(Local<String> property, AccessorInfo& info)
+    // void f(Local<String> property, PropertyCallbackInfo& info)
     DIRECT_GETTER_CALL,
 
-    // Call to accessor getter callback via InvokeAccessorGetter.
-    // Handle<value> f(Local<String> property, AccessorInfo& info,
-    //     AccessorGetter getter)
-    PROFILING_GETTER_CALL,
-
-    // Direct call to accessor getter callback.
-    // void f(Local<String> property, AccessorInfo& info)
-    DIRECT_GETTER_CALL_NEW,
-
     // Call to accessor getter callback via InvokeAccessorGetterCallback.
-    // void f(Local<String> property, AccessorInfo& info,
+    // void f(Local<String> property, PropertyCallbackInfo& info,
     //     AccessorGetterCallback callback)
-    PROFILING_GETTER_CALL_NEW
+    PROFILING_GETTER_CALL
   };
 
   static void SetUp();
diff --git a/src/ast.h b/src/ast.h
index f61f495..bf76cfa 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -123,10 +123,6 @@
   STATEMENT_NODE_LIST(V)                        \
   EXPRESSION_NODE_LIST(V)
 
-#ifdef WIN32
-#undef Yield
-#endif
-
 // Forward declarations
 class AstConstructionVisitor;
 template<class> class AstNodeFactory;
@@ -1963,7 +1959,7 @@
   Expression* expression() const { return expression_; }
   virtual int position() const V8_OVERRIDE { return pos_; }
 
-  void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe);
+  void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
   virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
   virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
     return &receiver_types_;
diff --git a/src/builtins.cc b/src/builtins.cc
index 4a5cd03..1bc0a72 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1253,8 +1253,8 @@
   if (!raw_call_data->IsUndefined()) {
     CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
     Object* callback_obj = call_data->callback();
-    v8::InvocationCallback callback =
-        v8::ToCData<v8::InvocationCallback>(callback_obj);
+    v8::FunctionCallback callback =
+        v8::ToCData<v8::FunctionCallback>(callback_obj);
     Object* data_obj = call_data->data();
     Object* result;
 
@@ -1322,8 +1322,8 @@
   ASSERT(!handler->IsUndefined());
   CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
   Object* callback_obj = call_data->callback();
-  v8::InvocationCallback callback =
-      v8::ToCData<v8::InvocationCallback>(callback_obj);
+  v8::FunctionCallback callback =
+      v8::ToCData<v8::FunctionCallback>(callback_obj);
 
   // Get the data for the call and perform the callback.
   Object* result;
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 3e18138..35927f4 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -112,6 +112,13 @@
   HValue* BuildInternalArrayConstructor(ElementsKind kind,
                                         ArgumentClass argument_class);
 
+  void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
+                                 HValue* code_object);
+  void BuildInstallCode(HValue* js_function, HValue* shared_info);
+  void BuildInstallFromOptimizedCodeMap(HValue* js_function,
+                                        HValue* shared_info,
+                                        HValue* native_context);
+
  private:
   HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
   HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
@@ -904,4 +911,194 @@
 }
 
 
+void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(
+    HValue* js_function,
+    HValue* native_context,
+    HValue* code_object) {
+  Counters* counters = isolate()->counters();
+  AddIncrementCounter(counters->fast_new_closure_install_optimized(),
+                      context());
+
+  // TODO(fschneider): Idea: store proper code pointers in the optimized code
+  // map and either unmangle them on marking or do nothing as the whole map is
+  // discarded on major GC anyway.
+  Add<HStoreCodeEntry>(js_function, code_object);
+
+  // Now link a function into a list of optimized functions.
+  HValue* optimized_functions_list = Add<HLoadNamedField>(native_context,
+      HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
+  Add<HStoreNamedField>(js_function,
+                        HObjectAccess::ForNextFunctionLinkPointer(),
+                        optimized_functions_list);
+
+  // This store is the only one that should have a write barrier.
+  Add<HStoreNamedField>(native_context,
+           HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
+           js_function);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
+                                                HValue* shared_info) {
+  Add<HStoreNamedField>(js_function,
+                        HObjectAccess::ForNextFunctionLinkPointer(),
+                        graph()->GetConstantUndefined());
+  HValue* code_object = Add<HLoadNamedField>(shared_info,
+                                             HObjectAccess::ForCodeOffset());
+  Add<HStoreCodeEntry>(js_function, code_object);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
+    HValue* js_function,
+    HValue* shared_info,
+    HValue* native_context) {
+  Counters* counters = isolate()->counters();
+  IfBuilder is_optimized(this);
+  HInstruction* optimized_map = Add<HLoadNamedField>(shared_info,
+      HObjectAccess::ForOptimizedCodeMap());
+  HValue* null_constant = Add<HConstant>(0);
+  is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
+  is_optimized.Then();
+  {
+    BuildInstallCode(js_function, shared_info);
+  }
+  is_optimized.Else();
+  {
+    AddIncrementCounter(counters->fast_new_closure_try_optimized(), context());
+    // optimized_map points to fixed array of 3-element entries
+    // (native context, optimized code, literals).
+    // Map must never be empty, so check the first elements.
+    Label install_optimized;
+    HValue* first_context_slot = Add<HLoadNamedField>(optimized_map,
+        HObjectAccess::ForFirstContextSlot());
+    IfBuilder already_in(this);
+    already_in.If<HCompareObjectEqAndBranch>(native_context,
+                                             first_context_slot);
+    already_in.Then();
+    {
+      HValue* code_object = Add<HLoadNamedField>(optimized_map,
+        HObjectAccess::ForFirstCodeSlot());
+      BuildInstallOptimizedCode(js_function, native_context, code_object);
+    }
+    already_in.Else();
+    {
+      HValue* shared_function_entry_length =
+          Add<HConstant>(SharedFunctionInfo::kEntryLength);
+      LoopBuilder loop_builder(this,
+                               context(),
+                               LoopBuilder::kPostDecrement,
+                               shared_function_entry_length);
+      HValue* array_length = Add<HLoadNamedField>(optimized_map,
+          HObjectAccess::ForFixedArrayLength());
+      HValue* key = loop_builder.BeginBody(array_length,
+                                           graph()->GetConstant0(),
+                                           Token::GT);
+      {
+        // Iterate through the rest of map backwards.
+        // Do not double check first entry.
+        HValue* second_entry_index =
+            Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex);
+        IfBuilder restore_check(this);
+        restore_check.If<HCompareNumericAndBranch>(key, second_entry_index,
+                                                   Token::EQ);
+        restore_check.Then();
+        {
+          // Store the unoptimized code
+          BuildInstallCode(js_function, shared_info);
+          loop_builder.Break();
+        }
+        restore_check.Else();
+        {
+          HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key,
+              shared_function_entry_length));
+          HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map,
+              keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+          IfBuilder done_check(this);
+          done_check.If<HCompareObjectEqAndBranch>(native_context,
+                                                   keyed_lookup);
+          done_check.Then();
+          {
+            // Hit: fetch the optimized code.
+            HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(),
+                keyed_minus, graph()->GetConstant1()));
+            HValue* code_object = Add<HLoadKeyed>(optimized_map,
+                keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+            BuildInstallOptimizedCode(js_function, native_context, code_object);
+
+            // Fall out of the loop
+            loop_builder.Break();
+          }
+          done_check.Else();
+          done_check.End();
+        }
+        restore_check.End();
+      }
+      loop_builder.EndBody();
+    }
+    already_in.End();
+  }
+  is_optimized.End();
+}
+
+
+template<>
+HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
+  Counters* counters = isolate()->counters();
+  Factory* factory = isolate()->factory();
+  HInstruction* empty_fixed_array =
+      Add<HConstant>(factory->empty_fixed_array());
+  HValue* shared_info = GetParameter(0);
+
+  // Create a new closure from the given function info in new space
+  HValue* size = Add<HConstant>(JSFunction::kSize);
+  HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
+                                             NOT_TENURED, JS_FUNCTION_TYPE);
+  AddIncrementCounter(counters->fast_new_closure_total(), context());
+
+  int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
+                                            casted_stub()->is_generator());
+
+  // Compute the function map in the current native context and set that
+  // as the map of the allocated object.
+  HInstruction* native_context = BuildGetNativeContext();
+  HInstruction* map_slot_value = Add<HLoadNamedField>(native_context,
+      HObjectAccess::ForContextSlot(map_index));
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
+
+  // Initialize the rest of the function.
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
+                        empty_fixed_array);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
+                        empty_fixed_array);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
+                        empty_fixed_array);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
+                        graph()->GetConstantHole());
+  Add<HStoreNamedField>(js_function,
+                        HObjectAccess::ForSharedFunctionInfoPointer(),
+                        shared_info);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+                        shared_info);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+                        context());
+
+  // Initialize the code pointer in the function to be the one
+  // found in the shared function info object.
+  // But first check if there is an optimized version for our context.
+  if (FLAG_cache_optimized_code) {
+    BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
+  } else {
+    BuildInstallCode(js_function, shared_info);
+  }
+
+  return js_function;
+}
+
+
+Handle<Code> FastNewClosureStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index dd70127..01456ee 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -759,6 +759,12 @@
 }
 
 
+void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
+  FastNewClosureStub stub(STRICT_MODE, false);
+  InstallDescriptor(isolate, &stub);
+}
+
+
 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
     : argument_count_(ANY) {
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 4be914d..ccd2caf 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -489,20 +489,29 @@
 };
 
 
-class FastNewClosureStub : public PlatformCodeStub {
+class FastNewClosureStub : public HydrogenCodeStub {
  public:
   explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator)
     : language_mode_(language_mode),
       is_generator_(is_generator) { }
 
-  void Generate(MacroAssembler* masm);
+  virtual Handle<Code> GenerateCode();
+
+  virtual void InitializeInterfaceDescriptor(
+      Isolate* isolate,
+      CodeStubInterfaceDescriptor* descriptor);
+
+  static void InstallDescriptors(Isolate* isolate);
+
+  LanguageMode language_mode() const { return language_mode_; }
+  bool is_generator() const { return is_generator_; }
 
  private:
   class StrictModeBits: public BitField<bool, 0, 1> {};
   class IsGeneratorBits: public BitField<bool, 1, 1> {};
 
   Major MajorKey() { return FastNewClosure; }
-  int MinorKey() {
+  int NotMissMinorKey() {
     return StrictModeBits::encode(language_mode_ != CLASSIC_MODE) |
       IsGeneratorBits::encode(is_generator_);
   }
diff --git a/src/compiler.cc b/src/compiler.cc
index c14234f..6c2bdce 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1262,6 +1262,7 @@
 bool CompilationPhase::ShouldProduceTraceOutput() const {
   // Trace if the appropriate trace flag is set and the phase name's first
   // character is in the FLAG_trace_phase command line parameter.
+  AllowHandleDereference allow_deref;
   bool tracing_on = info()->IsStub()
       ? FLAG_trace_hydrogen_stubs
       : (FLAG_trace_hydrogen &&
diff --git a/src/cpu.cc b/src/cpu.cc
index d7c32dd..1bae001 100644
--- a/src/cpu.cc
+++ b/src/cpu.cc
@@ -58,7 +58,7 @@
 
 #else  // !V8_CC_MSVC || (!defined(__i386__) && !defined(__pic__))
 
-static void V8_INLINE(__cpuid(int cpu_info[4], int info_type)) {
+static V8_INLINE(void __cpuid(int cpu_info[4], int info_type)) {
   __asm__ volatile (
     "cpuid \n\t"
     : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
diff --git a/src/d8.h b/src/d8.h
index 3b06985..6008d35 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -400,8 +400,8 @@
   static void RunShell(Isolate* isolate);
   static bool SetOptions(int argc, char* argv[]);
   static Handle<ObjectTemplate> CreateGlobalTemplate(Isolate* isolate);
-  static Handle<FunctionTemplate> CreateArrayBufferTemplate(InvocationCallback);
-  static Handle<FunctionTemplate> CreateArrayTemplate(InvocationCallback);
+  static Handle<FunctionTemplate> CreateArrayBufferTemplate(FunctionCallback);
+  static Handle<FunctionTemplate> CreateArrayTemplate(FunctionCallback);
   static Handle<Value> CreateExternalArrayBuffer(Isolate* isolate,
                                                  Handle<Object> buffer,
                                                  int32_t size);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 2d6863b..0ea5a32 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -620,7 +620,7 @@
 DEFINE_float(testing_float_flag, 2.5, "float-flag")
 DEFINE_string(testing_string_flag, "Hello, world!", "string-flag")
 DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness")
-#ifdef WIN32
+#ifdef _WIN32
 DEFINE_string(testing_serialization_file, "C:\\Windows\\Temp\\serdes",
               "file in which to testing_serialize heap")
 #else
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index 74db807..664673f 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -1872,7 +1872,7 @@
 static void RegisterCodeEntry(JITCodeEntry* entry,
                               bool dump_if_enabled,
                               const char* name_hint) {
-#if defined(DEBUG) && !defined(WIN32)
+#if defined(DEBUG) && !V8_OS_WIN
   static int file_num = 0;
   if (FLAG_gdbjit_dump && dump_if_enabled) {
     static const int kMaxFileNameSize = 64;
diff --git a/src/globals.h b/src/globals.h
index 2d072a0..d0a57a4 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -171,27 +171,32 @@
 // Define our own macros for writing 64-bit constants.  This is less fragile
 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
 // works on compilers that don't have it (like MSVC).
-#if V8_HOST_ARCH_64_BIT
-#if defined(_MSC_VER)
-#define V8_UINT64_C(x)  (x ## UI64)
-#define V8_INT64_C(x)   (x ## I64)
-#define V8_INTPTR_C(x)  (x ## I64)
-#define V8_PTR_PREFIX "ll"
-#elif defined(__MINGW64__)
-#define V8_UINT64_C(x)  (x ## ULL)
-#define V8_INT64_C(x)   (x ## LL)
-#define V8_INTPTR_C(x)  (x ## LL)
-#define V8_PTR_PREFIX "I64"
+#if V8_CC_MSVC
+# define V8_UINT64_C(x)   (x ## UI64)
+# define V8_INT64_C(x)    (x ## I64)
+# if V8_HOST_ARCH_64_BIT
+#  define V8_INTPTR_C(x)  (x ## I64)
+#  define V8_PTR_PREFIX   "ll"
+# else
+#  define V8_INTPTR_C(x)  (x)
+#  define V8_PTR_PREFIX   ""
+# endif  // V8_HOST_ARCH_64_BIT
+#elif V8_CC_MINGW64
+# define V8_UINT64_C(x)   (x ## ULL)
+# define V8_INT64_C(x)    (x ## LL)
+# define V8_INTPTR_C(x)   (x ## LL)
+# define V8_PTR_PREFIX    "I64"
+#elif V8_HOST_ARCH_64_BIT
+# define V8_UINT64_C(x)   (x ## UL)
+# define V8_INT64_C(x)    (x ## L)
+# define V8_INTPTR_C(x)   (x ## L)
+# define V8_PTR_PREFIX    "l"
 #else
-#define V8_UINT64_C(x)  (x ## UL)
-#define V8_INT64_C(x)   (x ## L)
-#define V8_INTPTR_C(x)  (x ## L)
-#define V8_PTR_PREFIX "l"
+# define V8_UINT64_C(x)   (x ## ULL)
+# define V8_INT64_C(x)    (x ## LL)
+# define V8_INTPTR_C(x)   (x)
+# define V8_PTR_PREFIX    ""
 #endif
-#else  // V8_HOST_ARCH_64_BIT
-#define V8_INTPTR_C(x)  (x)
-#define V8_PTR_PREFIX ""
-#endif  // V8_HOST_ARCH_64_BIT
 
 // The following macro works on both 32 and 64-bit platforms.
 // Usage: instead of writing 0x1234567890123456
@@ -337,31 +342,13 @@
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
 
-// Define used for helping GCC to make better inlining. Don't bother for debug
-// builds. On GCC 3.4.5 using __attribute__((always_inline)) causes compilation
-// errors in debug build.
-#if defined(__GNUC__) && !defined(DEBUG)
-#if (__GNUC__ >= 4)
-#define INLINE(header) inline header  __attribute__((always_inline))
-#define NO_INLINE(header) header __attribute__((noinline))
-#else
-#define INLINE(header) inline __attribute__((always_inline)) header
-#define NO_INLINE(header) __attribute__((noinline)) header
-#endif
-#elif defined(_MSC_VER) && !defined(DEBUG)
-#define INLINE(header) __forceinline header
-#define NO_INLINE(header) header
-#else
-#define INLINE(header) inline header
-#define NO_INLINE(header) header
-#endif
+// Newly written code should use V8_INLINE() and V8_NOINLINE() directly.
+#define INLINE(declarator)    V8_INLINE(declarator)
+#define NO_INLINE(declarator) V8_NOINLINE(declarator)
 
 
-#if defined(__GNUC__) && __GNUC__ >= 4
-#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
-#else
-#define MUST_USE_RESULT
-#endif
+// Newly written code should use V8_WARN_UNUSED_RESULT.
+#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
 
 
 // Define DISABLE_ASAN macros.
diff --git a/src/handles.cc b/src/handles.cc
index b173edc..9d47690 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -532,8 +532,9 @@
       args(isolate, interceptor->data(), *receiver, *object);
   v8::Handle<v8::Array> result;
   if (!interceptor->enumerator()->IsUndefined()) {
-    v8::NamedPropertyEnumerator enum_fun =
-        v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
+    v8::NamedPropertyEnumeratorCallback enum_fun =
+        v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
+            interceptor->enumerator());
     LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
     result = args.Call(enum_fun);
   }
@@ -554,8 +555,9 @@
       args(isolate, interceptor->data(), *receiver, *object);
   v8::Handle<v8::Array> result;
   if (!interceptor->enumerator()->IsUndefined()) {
-    v8::IndexedPropertyEnumerator enum_fun =
-        v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
+    v8::IndexedPropertyEnumeratorCallback enum_fun =
+        v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
+            interceptor->enumerator());
     LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
     result = args.Call(enum_fun);
 #if ENABLE_EXTRA_CHECKS
diff --git a/src/heap.cc b/src/heap.cc
index ad352bc..b1096b3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4971,7 +4971,7 @@
   int object_size = map->instance_size();
   Object* clone;
 
-  ASSERT(map->CanTrackAllocationSite());
+  ASSERT(AllocationSite::CanTrack(map->instance_type()));
   ASSERT(map->instance_type() == JS_ARRAY_TYPE);
   WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
 
diff --git a/src/hydrogen-bch.cc b/src/hydrogen-bch.cc
index 137d629..a0a0fee 100644
--- a/src/hydrogen-bch.cc
+++ b/src/hydrogen-bch.cc
@@ -102,10 +102,11 @@
     int current_dominated_block_;
   };
 
-  HGraph* graph() { return graph_; }
-  HBasicBlock* loop_header() { return loop_header_; }
-  Element* at(int index) { return &(elements_.at(index)); }
-  Element* at(HBasicBlock* block) { return at(block->block_id()); }
+  HGraph* graph() const { return graph_; }
+  Counters* counters() const { return graph()->isolate()->counters(); }
+  HBasicBlock* loop_header() const { return loop_header_; }
+  Element* at(int index) const { return &(elements_.at(index)); }
+  Element* at(HBasicBlock* block) const { return at(block->block_id()); }
 
   void AddCheckAt(HBasicBlock* block) {
     at(block->block_id())->set_has_check();
@@ -258,23 +259,17 @@
     // all checks are done on constants: if all check are done against the same
     // constant limit we will use that instead of the induction limit.
     bool has_upper_constant_limit = true;
-    InductionVariableData::InductionVariableCheck* current_check = check;
     int32_t upper_constant_limit =
-        current_check != NULL && current_check->HasUpperLimit() ?
-        current_check->upper_limit() : 0;
-    while (current_check != NULL) {
-      if (check->HasUpperLimit()) {
-        if (check->upper_limit() != upper_constant_limit) {
-          has_upper_constant_limit = false;
-        }
-      } else {
-        has_upper_constant_limit = false;
-      }
-
-      current_check->check()->block()->graph()->isolate()->counters()->
-          bounds_checks_eliminated()->Increment();
+        check != NULL && check->HasUpperLimit() ? check->upper_limit() : 0;
+    for (InductionVariableData::InductionVariableCheck* current_check = check;
+         current_check != NULL;
+         current_check = current_check->next()) {
+      has_upper_constant_limit =
+          has_upper_constant_limit &&
+          check->HasUpperLimit() &&
+          check->upper_limit() == upper_constant_limit;
+      counters()->bounds_checks_eliminated()->Increment();
       current_check->check()->set_skip_check();
-      current_check = current_check->next();
     }
 
     // Choose the appropriate limit.
@@ -303,8 +298,7 @@
         zone, context, limit, check->check()->length());
     hoisted_check->InsertBefore(pre_header->end());
     hoisted_check->set_allow_equality(true);
-    hoisted_check->block()->graph()->isolate()->counters()->
-        bounds_checks_hoisted()->Increment();
+    counters()->bounds_checks_hoisted()->Increment();
   }
 
   void CollectInductionVariableData(HBasicBlock* bb) {
@@ -341,8 +335,7 @@
       // TODO(mmassi): skip OSR values for check->length().
       if (check->length() == data->limit() ||
           check->length() == data->additional_upper_limit()) {
-        check->block()->graph()->isolate()->counters()->
-            bounds_checks_eliminated()->Increment();
+        counters()->bounds_checks_eliminated()->Increment();
         check->set_skip_check();
         continue;
       }
@@ -407,4 +400,3 @@
 }
 
 } }  // namespace v8::internal
-
diff --git a/src/hydrogen-canonicalize.cc b/src/hydrogen-canonicalize.cc
index 6432343..4d96415 100644
--- a/src/hydrogen-canonicalize.cc
+++ b/src/hydrogen-canonicalize.cc
@@ -48,6 +48,10 @@
           if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
                   HInstruction::kTruncatingToSmi)) {
             instr->SetFlag(HInstruction::kAllUsesTruncatingToSmi);
+          } else if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
+                         HInstruction::kTruncatingToInt32)) {
+            // Avoid redundant minus zero check
+            instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
           }
         }
       }
diff --git a/src/hydrogen-infer-representation.cc b/src/hydrogen-infer-representation.cc
index 95c3412..1b3ab6f 100644
--- a/src/hydrogen-infer-representation.cc
+++ b/src/hydrogen-infer-representation.cc
@@ -82,24 +82,36 @@
       if (done.Contains(i)) continue;
 
       // Check if all uses of all connected phis in this group are truncating.
-      bool all_uses_everywhere_truncating = true;
+      bool all_uses_everywhere_truncating_int32 = true;
+      bool all_uses_everywhere_truncating_smi = true;
       for (BitVector::Iterator it(connected_phis[i]);
            !it.Done();
            it.Advance()) {
         int index = it.Current();
-        all_uses_everywhere_truncating &=
+        all_uses_everywhere_truncating_int32 &=
             phi_list->at(index)->CheckFlag(HInstruction::kTruncatingToInt32);
+        all_uses_everywhere_truncating_smi &=
+            phi_list->at(index)->CheckFlag(HInstruction::kTruncatingToSmi);
         done.Add(index);
       }
-      if (all_uses_everywhere_truncating) {
-        continue;  // Great, nothing to do.
+
+      if (!all_uses_everywhere_truncating_int32) {
+        // Clear truncation flag of this group of connected phis.
+        for (BitVector::Iterator it(connected_phis[i]);
+             !it.Done();
+             it.Advance()) {
+          int index = it.Current();
+          phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToInt32);
+        }
       }
-      // Clear truncation flag of this group of connected phis.
-      for (BitVector::Iterator it(connected_phis[i]);
-           !it.Done();
-           it.Advance()) {
-        int index = it.Current();
-        phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToInt32);
+      if (!all_uses_everywhere_truncating_smi) {
+        // Clear truncation flag of this group of connected phis.
+        for (BitVector::Iterator it(connected_phis[i]);
+             !it.Done();
+             it.Advance()) {
+          int index = it.Current();
+          phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToSmi);
+        }
       }
     }
   }
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 90cf017..0bd7b79 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -397,6 +397,18 @@
 }
 
 
+bool HValue::CheckUsesForFlag(Flag f, HValue** value) const {
+  for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
+    if (it.value()->IsSimulate()) continue;
+    if (!it.value()->CheckFlag(f)) {
+      *value = it.value();
+      return false;
+    }
+  }
+  return true;
+}
+
+
 bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const {
   bool return_value = false;
   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
@@ -1231,6 +1243,7 @@
 
 
 HValue* HDiv::Canonicalize() {
+  if (IsIdentityOperation(left(), right(), 1)) return left();
   return this;
 }
 
@@ -2289,6 +2302,21 @@
 }
 
 
+void HSimulate::ReplayEnvironment(HEnvironment* env) {
+  ASSERT(env != NULL);
+  env->set_ast_id(ast_id());
+  env->Drop(pop_count());
+  for (int i = values()->length() - 1; i >= 0; --i) {
+    HValue* value = values()->at(i);
+    if (HasAssignedIndexAt(i)) {
+      env->Bind(GetAssignedIndexAt(i), value);
+    } else {
+      env->Push(value);
+    }
+  }
+}
+
+
 // Replay captured objects by replacing all captured objects with the
 // same capture id in the current and all outer environments.
 void HCapturedObject::ReplayEnvironment(HEnvironment* env) {
@@ -2468,7 +2496,7 @@
 
 void HConstant::Initialize(Representation r) {
   if (r.IsNone()) {
-    if (has_smi_value_ && kSmiValueSize == 31) {
+    if (has_smi_value_ && SmiValuesAre31Bits()) {
       r = Representation::Smi();
     } else if (has_int32_value_) {
       r = Representation::Integer32();
@@ -3255,8 +3283,9 @@
 
   // First update the size of the dominator allocate instruction.
   dominator_size = dominator_allocate->size();
-  int32_t dominator_size_constant =
+  int32_t original_object_size =
       HConstant::cast(dominator_size)->GetInteger32Constant();
+  int32_t dominator_size_constant = original_object_size;
   int32_t current_size_constant =
       HConstant::cast(current_size)->GetInteger32Constant();
   int32_t new_dominator_size = dominator_size_constant + current_size_constant;
@@ -3291,9 +3320,19 @@
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
     dominator_allocate->MakePrefillWithFiller();
+  } else {
+    // TODO(hpayer): This is a short-term hack to make allocation mementos
+    // work again in new space.
+    ClearNextMapWord(original_object_size);
   }
+#else
+  // TODO(hpayer): This is a short-term hack to make allocation mementos
+  // work again in new space.
+  ClearNextMapWord(original_object_size);
 #endif
 
+  dominator_allocate->clear_next_map_word_ = clear_next_map_word_;
+
   // After that replace the dominated allocate instruction.
   HInstruction* dominated_allocate_instr =
       HInnerAllocatedObject::New(zone,
@@ -3429,6 +3468,19 @@
 }
 
 
+void HAllocate::ClearNextMapWord(int offset) {
+  if (clear_next_map_word_) {
+    Zone* zone = block()->zone();
+    HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+    HStoreNamedField* clear_next_map =
+        HStoreNamedField::New(zone, context(), this, access,
+            block()->graph()->GetConstantNull());
+    clear_next_map->ClearAllSideEffects();
+    clear_next_map->InsertAfter(this);
+  }
+}
+
+
 void HAllocate::PrintDataTo(StringStream* stream) {
   size()->PrintNameTo(stream);
   stream->Add(" (");
@@ -4030,6 +4082,15 @@
 }
 
 
+HObjectAccess HObjectAccess::ForContextSlot(int index) {
+  ASSERT(index >= 0);
+  Portion portion = kInobject;
+  int offset = Context::kHeaderSize + index * kPointerSize;
+  ASSERT_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag);
+  return HObjectAccess(portion, offset, Representation::Tagged());
+}
+
+
 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
   ASSERT(offset >= 0);
   Portion portion = kInobject;
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 5dee185..8f79edf 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -164,6 +164,7 @@
   V(Shr)                                       \
   V(Simulate)                                  \
   V(StackCheck)                                \
+  V(StoreCodeEntry)                            \
   V(StoreContextSlot)                          \
   V(StoreGlobalCell)                           \
   V(StoreGlobalGeneric)                        \
@@ -806,6 +807,8 @@
 
   // Returns true if the flag specified is set for all uses, false otherwise.
   bool CheckUsesForFlag(Flag f) const;
+  // Same as before and the first one without the flag is returned in value.
+  bool CheckUsesForFlag(Flag f, HValue** value) const;
   // Returns true if the flag specified is set for all uses, and this set
   // of uses is non-empty.
   bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
@@ -1544,7 +1547,10 @@
     ASSERT(!value->representation().Equals(to));
     set_representation(to);
     SetFlag(kUseGVN);
-    if (is_truncating_to_smi) SetFlag(kTruncatingToSmi);
+    if (is_truncating_to_smi) {
+      SetFlag(kTruncatingToSmi);
+      SetFlag(kTruncatingToInt32);
+    }
     if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
     if (value->representation().IsSmi() || value->type().IsSmi()) {
       set_type(HType::Smi());
@@ -1676,6 +1682,9 @@
   void MergeWith(ZoneList<HSimulate*>* list);
   bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
 
+  // Replay effects of this instruction on the given environment.
+  void ReplayEnvironment(HEnvironment* env);
+
   DECLARE_CONCRETE_INSTRUCTION(Simulate)
 
 #ifdef DEBUG
@@ -3326,7 +3335,7 @@
   }
 
   virtual Representation KnownOptimalRepresentation() V8_OVERRIDE {
-    if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
+    if (HasSmiValue() && SmiValuesAre31Bits()) return Representation::Smi();
     if (HasInteger32Value()) return Representation::Integer32();
     if (HasNumberValue()) return Representation::Double();
     if (HasExternalReferenceValue()) return Representation::External();
@@ -4510,7 +4519,6 @@
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
                                     const char* reason) V8_OVERRIDE {
-    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
     HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
   }
 
@@ -4720,6 +4728,7 @@
           right->representation().IsSmi() &&
           HConstant::cast(right)->Integer32Value() >= 0))) {
       SetFlag(kTruncatingToSmi);
+      SetFlag(kTruncatingToInt32);
     // BIT_OR with a smi-range negative value will always set the entire
     // sign-extension of the smi-sign.
     } else if (op == Token::BIT_OR &&
@@ -4730,6 +4739,7 @@
           right->representation().IsSmi() &&
           HConstant::cast(right)->Integer32Value() < 0))) {
       SetFlag(kTruncatingToSmi);
+      SetFlag(kTruncatingToInt32);
     }
   }
 
@@ -5156,7 +5166,8 @@
             InstanceType instance_type)
       : HTemplateInstruction<2>(type),
         dominating_allocate_(NULL),
-        filler_free_space_size_(NULL) {
+        filler_free_space_size_(NULL),
+        clear_next_map_word_(false) {
     SetOperandAt(0, context);
     SetOperandAt(1, size);
     set_representation(Representation::Tagged());
@@ -5168,9 +5179,18 @@
             ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE)
         : ALLOCATE_IN_NEW_SPACE;
     if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
-      flags_ = static_cast<HAllocate::Flags>(flags_ |
-          ALLOCATE_DOUBLE_ALIGNED);
+      flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
     }
+    // We have to fill the allocated object with one word fillers if we do
+    // not use allocation folding since some allocations may depend on each
+    // other, i.e., have a pointer to each other. A GC in between these
+    // allocations may leave such objects behind in a not completely initialized
+    // state.
+    if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
+      flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
+    }
+    clear_next_map_word_ = pretenure_flag == NOT_TENURED &&
+        AllocationSite::CanTrack(instance_type);
   }
 
   void UpdateSize(HValue* size) {
@@ -5190,14 +5210,43 @@
             allocate->IsOldPointerSpaceAllocation());
   }
 
+  void ClearNextMapWord(int offset);
+
   Flags flags_;
   Handle<Map> known_initial_map_;
   HAllocate* dominating_allocate_;
   HStoreNamedField* filler_free_space_size_;
+  bool clear_next_map_word_;
 };
 
 
-class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<1> {
+class HStoreCodeEntry V8_FINAL: public HTemplateInstruction<2> {
+ public:
+  static HStoreCodeEntry* New(Zone* zone,
+                              HValue* context,
+                              HValue* function,
+                              HValue* code) {
+    return new(zone) HStoreCodeEntry(function, code);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) {
+    return Representation::Tagged();
+  }
+
+  HValue* function() { return OperandAt(0); }
+  HValue* code_object() { return OperandAt(1); }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry)
+
+ private:
+  HStoreCodeEntry(HValue* function, HValue* code) {
+    SetOperandAt(0, function);
+    SetOperandAt(1, code);
+  }
+};
+
+
+class HInnerAllocatedObject V8_FINAL: public HTemplateInstruction<1> {
  public:
   static HInnerAllocatedObject* New(Zone* zone,
                                     HValue* context,
@@ -5506,6 +5555,14 @@
     return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
   }
 
+  static HObjectAccess ForLiteralsPointer() {
+    return HObjectAccess(kInobject, JSFunction::kLiteralsOffset);
+  }
+
+  static HObjectAccess ForNextFunctionLinkPointer() {
+    return HObjectAccess(kInobject, JSFunction::kNextFunctionLinkOffset);
+  }
+
   static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
     return HObjectAccess(
         kArrayLengths,
@@ -5550,6 +5607,35 @@
     return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
   }
 
+  static HObjectAccess ForSharedFunctionInfoPointer() {
+    return HObjectAccess(kInobject, JSFunction::kSharedFunctionInfoOffset);
+  }
+
+  static HObjectAccess ForCodeEntryPointer() {
+    return HObjectAccess(kInobject, JSFunction::kCodeEntryOffset);
+  }
+
+  static HObjectAccess ForCodeOffset() {
+    return HObjectAccess(kInobject, SharedFunctionInfo::kCodeOffset);
+  }
+
+  static HObjectAccess ForFirstCodeSlot() {
+    return HObjectAccess(kInobject, SharedFunctionInfo::kFirstCodeSlot);
+  }
+
+  static HObjectAccess ForFirstContextSlot() {
+    return HObjectAccess(kInobject, SharedFunctionInfo::kFirstContextSlot);
+  }
+
+  static HObjectAccess ForOptimizedCodeMap() {
+    return HObjectAccess(kInobject,
+                         SharedFunctionInfo::kOptimizedCodeMapOffset);
+  }
+
+  static HObjectAccess ForFunctionContextPointer() {
+    return HObjectAccess(kInobject, JSFunction::kContextOffset);
+  }
+
   static HObjectAccess ForMap() {
     return HObjectAccess(kMaps, JSObject::kMapOffset);
   }
@@ -5580,6 +5666,8 @@
   // Create an access to an in-object property in a JSArray.
   static HObjectAccess ForJSArrayOffset(int offset);
 
+  static HObjectAccess ForContextSlot(int index);
+
   // Create an access to the backing store of an object.
   static HObjectAccess ForBackingStoreOffset(int offset,
       Representation representation = Representation::Tagged());
@@ -5759,7 +5847,7 @@
   virtual ~ArrayInstructionInterface() { };
 
   static Representation KeyedAccessIndexRequirement(Representation r) {
-    return r.IsInteger32() || kSmiValueSize != 31
+    return r.IsInteger32() || SmiValuesAre32Bits()
         ? Representation::Integer32() : Representation::Smi();
   }
 };
diff --git a/src/hydrogen-representation-changes.cc b/src/hydrogen-representation-changes.cc
index 862457d..9601137 100644
--- a/src/hydrogen-representation-changes.cc
+++ b/src/hydrogen-representation-changes.cc
@@ -99,7 +99,8 @@
   // int32-phis allow truncation and iteratively remove the ones that
   // are used in an operation that does not allow a truncating
   // conversion.
-  ZoneList<HPhi*> worklist(8, zone());
+  ZoneList<HPhi*> int_worklist(8, zone());
+  ZoneList<HPhi*> smi_worklist(8, zone());
 
   const ZoneList<HPhi*>* phi_list(graph()->phi_list());
   for (int i = 0; i < phi_list->length(); i++) {
@@ -108,51 +109,64 @@
       phi->SetFlag(HValue::kTruncatingToInt32);
     } else if (phi->representation().IsSmi()) {
       phi->SetFlag(HValue::kTruncatingToSmi);
+      phi->SetFlag(HValue::kTruncatingToInt32);
     }
   }
 
   for (int i = 0; i < phi_list->length(); i++) {
     HPhi* phi = phi_list->at(i);
-    for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
-      // If a Phi is used as a non-truncating int32 or as a double,
-      // clear its "truncating" flag.
-      HValue* use = it.value();
-      Representation input_representation =
-          use->RequiredInputRepresentation(it.index());
-      if ((phi->representation().IsInteger32() &&
-           !(input_representation.IsInteger32() &&
-             use->CheckFlag(HValue::kTruncatingToInt32))) ||
-          (phi->representation().IsSmi() &&
-           !(input_representation.IsSmi() &&
-             use->CheckFlag(HValue::kTruncatingToSmi)))) {
-        if (FLAG_trace_representation) {
-          PrintF("#%d Phi is not truncating because of #%d %s\n",
-                 phi->id(), it.value()->id(), it.value()->Mnemonic());
-        }
-        phi->ClearFlag(HValue::kTruncatingToInt32);
-        phi->ClearFlag(HValue::kTruncatingToSmi);
-        worklist.Add(phi, zone());
-        break;
+    HValue* value = NULL;
+    if (phi->representation().IsSmiOrInteger32() &&
+        !phi->CheckUsesForFlag(HValue::kTruncatingToInt32, &value)) {
+      int_worklist.Add(phi, zone());
+      phi->ClearFlag(HValue::kTruncatingToInt32);
+      if (FLAG_trace_representation) {
+        PrintF("#%d Phi is not truncating Int32 because of #%d %s\n",
+               phi->id(), value->id(), value->Mnemonic());
+      }
+    }
+
+    if (phi->representation().IsSmi() &&
+        !phi->CheckUsesForFlag(HValue::kTruncatingToSmi, &value)) {
+      smi_worklist.Add(phi, zone());
+      phi->ClearFlag(HValue::kTruncatingToSmi);
+      if (FLAG_trace_representation) {
+        PrintF("#%d Phi is not truncating Smi because of #%d %s\n",
+               phi->id(), value->id(), value->Mnemonic());
       }
     }
   }
 
-  while (!worklist.is_empty()) {
-    HPhi* current = worklist.RemoveLast();
+  while (!int_worklist.is_empty()) {
+    HPhi* current = int_worklist.RemoveLast();
     for (int i = 0; i < current->OperandCount(); ++i) {
       HValue* input = current->OperandAt(i);
       if (input->IsPhi() &&
-          ((input->representation().IsInteger32() &&
-            input->CheckFlag(HValue::kTruncatingToInt32)) ||
-           (input->representation().IsSmi() &&
-            input->CheckFlag(HValue::kTruncatingToSmi)))) {
+          input->representation().IsSmiOrInteger32() &&
+          input->CheckFlag(HValue::kTruncatingToInt32)) {
         if (FLAG_trace_representation) {
-          PrintF("#%d Phi is not truncating because of #%d %s\n",
+          PrintF("#%d Phi is not truncating Int32 because of #%d %s\n",
                  input->id(), current->id(), current->Mnemonic());
         }
         input->ClearFlag(HValue::kTruncatingToInt32);
+        int_worklist.Add(HPhi::cast(input), zone());
+      }
+    }
+  }
+
+  while (!smi_worklist.is_empty()) {
+    HPhi* current = smi_worklist.RemoveLast();
+    for (int i = 0; i < current->OperandCount(); ++i) {
+      HValue* input = current->OperandAt(i);
+      if (input->IsPhi() &&
+          input->representation().IsSmi() &&
+          input->CheckFlag(HValue::kTruncatingToSmi)) {
+        if (FLAG_trace_representation) {
+          PrintF("#%d Phi is not truncating Smi because of #%d %s\n",
+                 input->id(), current->id(), current->Mnemonic());
+        }
         input->ClearFlag(HValue::kTruncatingToSmi);
-        worklist.Add(HPhi::cast(input), zone());
+        smi_worklist.Add(HPhi::cast(input), zone());
       }
     }
   }
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 95090d5..4847f1a 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -828,7 +828,6 @@
   ASSERT(!captured_);
   ASSERT(!finished_);
   last_true_block_ = builder_->current_block();
-  ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished());
   builder_->set_current_block(first_false_block_);
   did_else_ = true;
 }
@@ -864,9 +863,11 @@
     if (!did_else_) {
       last_true_block_ = builder_->current_block();
     }
-    if (first_true_block_ == NULL) {
+    if (last_true_block_ == NULL || last_true_block_->IsFinished()) {
+      ASSERT(did_else_);
       // Return on true. Nothing to do, just continue the false block.
-    } else if (first_false_block_ == NULL) {
+    } else if (first_false_block_ == NULL ||
+               (did_else_ && builder_->current_block()->IsFinished())) {
       // Deopt on false. Nothing to do except switching to the true block.
       builder_->set_current_block(last_true_block_);
     } else {
@@ -906,6 +907,24 @@
   header_block_ = builder->CreateLoopHeaderBlock();
   body_block_ = NULL;
   exit_block_ = NULL;
+  exit_trampoline_block_ = NULL;
+  increment_amount_ = builder_->graph()->GetConstant1();
+}
+
+
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
+                                        HValue* context,
+                                        LoopBuilder::Direction direction,
+                                        HValue* increment_amount)
+    : builder_(builder),
+      context_(context),
+      direction_(direction),
+      finished_(false) {
+  header_block_ = builder->CreateLoopHeaderBlock();
+  body_block_ = NULL;
+  exit_block_ = NULL;
+  exit_trampoline_block_ = NULL;
+  increment_amount_ = increment_amount;
 }
 
 
@@ -921,12 +940,14 @@
 
   HEnvironment* body_env = env->Copy();
   HEnvironment* exit_env = env->Copy();
-  body_block_ = builder_->CreateBasicBlock(body_env);
-  exit_block_ = builder_->CreateBasicBlock(exit_env);
   // Remove the phi from the expression stack
   body_env->Pop();
+  exit_env->Pop();
+  body_block_ = builder_->CreateBasicBlock(body_env);
+  exit_block_ = builder_->CreateBasicBlock(exit_env);
 
   builder_->set_current_block(header_block_);
+  env->Pop();
   HCompareNumericAndBranch* compare =
       new(zone()) HCompareNumericAndBranch(phi_, terminating, token);
   compare->SetSuccessorAt(0, body_block_);
@@ -950,15 +971,26 @@
 }
 
 
+void HGraphBuilder::LoopBuilder::Break() {
+  if (exit_trampoline_block_ == NULL) {
+    // Its the first time we saw a break.
+    HEnvironment* env = exit_block_->last_environment()->Copy();
+    exit_trampoline_block_ = builder_->CreateBasicBlock(env);
+    exit_block_->GotoNoSimulate(exit_trampoline_block_);
+  }
+
+  builder_->current_block()->GotoNoSimulate(exit_trampoline_block_);
+}
+
+
 void HGraphBuilder::LoopBuilder::EndBody() {
   ASSERT(!finished_);
 
   if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
-    HValue* one = builder_->graph()->GetConstant1();
     if (direction_ == kPostIncrement) {
-      increment_ = HAdd::New(zone(), context_, phi_, one);
+      increment_ = HAdd::New(zone(), context_, phi_, increment_amount_);
     } else {
-      increment_ = HSub::New(zone(), context_, phi_, one);
+      increment_ = HSub::New(zone(), context_, phi_, increment_amount_);
     }
     increment_->ClearFlag(HValue::kCanOverflow);
     builder_->AddInstruction(increment_);
@@ -970,9 +1002,11 @@
   last_block->GotoNoSimulate(header_block_);
   header_block_->loop_information()->RegisterBackEdge(last_block);
 
-  builder_->set_current_block(exit_block_);
-  // Pop the phi from the expression stack
-  builder_->environment()->Pop();
+  if (exit_trampoline_block_ != NULL) {
+    builder_->set_current_block(exit_trampoline_block_);
+  } else {
+    builder_->set_current_block(exit_block_);
+  }
   finished_ = true;
 }
 
@@ -1674,22 +1708,12 @@
   if (mode == TRACK_ALLOCATION_SITE) {
     size += AllocationMemento::kSize;
   }
-  int elems_offset = size;
-  InstanceType instance_type = IsFastDoubleElementsKind(kind) ?
-      FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
-  if (length > 0) {
-    size += IsFastDoubleElementsKind(kind)
-        ? FixedDoubleArray::SizeFor(length)
-        : FixedArray::SizeFor(length);
-  }
 
-  // Allocate both the JS array and the elements array in one big
-  // allocation. This avoids multiple limit checks.
   HValue* size_in_bytes = Add<HConstant>(size);
   HInstruction* object = Add<HAllocate>(size_in_bytes,
                                         HType::JSObject(),
                                         NOT_TENURED,
-                                        instance_type);
+                                        JS_OBJECT_TYPE);
 
   // Copy the JS array part.
   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
@@ -1706,10 +1730,17 @@
   }
 
   if (length > 0) {
-    // Get hold of the elements array of the boilerplate and setup the
-    // elements pointer in the resulting object.
     HValue* boilerplate_elements = AddLoadElements(boilerplate);
-    HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
+    HValue* object_elements;
+    if (IsFastDoubleElementsKind(kind)) {
+      HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length));
+      object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
+          NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE);
+    } else {
+      HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length));
+      object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
+          NOT_TENURED, FIXED_ARRAY_TYPE);
+    }
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
                           object_elements);
 
@@ -7494,7 +7525,12 @@
   HConstant* delta = (expr->op() == Token::INC)
       ? graph()->GetConstant1()
       : graph()->GetConstantMinus1();
-  HInstruction* instr = Add<HAdd>(Top(), delta);
+  HInstruction* instr = AddUncasted<HAdd>(Top(), delta);
+  if (instr->IsAdd()) {
+    HAdd* add = HAdd::cast(instr);
+    add->set_observed_input_representation(1, rep);
+    add->set_observed_input_representation(2, Representation::Smi());
+  }
   instr->SetFlag(HInstruction::kCannotBeTagged);
   instr->ClearAllSideEffects();
   return instr;
@@ -8293,7 +8329,7 @@
     int* data_offset,
     AllocationSiteMode mode) {
   bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
-      boilerplate_object->map()->CanTrackAllocationSite();
+      AllocationSite::CanTrack(boilerplate_object->map()->instance_type());
 
   // If using allocation sites, then the payload on the site should already
   // be filled in as a valid (boilerplate) array.
@@ -8349,7 +8385,7 @@
 
   // Create allocation site info.
   if (mode == TRACK_ALLOCATION_SITE &&
-      boilerplate_object->map()->CanTrackAllocationSite()) {
+      AllocationSite::CanTrack(boilerplate_object->map()->instance_type())) {
     elements_offset += AllocationMemento::kSize;
     *offset += AllocationMemento::kSize;
     BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 2b9fd96..22bffd1 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1058,7 +1058,7 @@
 
   template<class I, class P1, class P2>
   I* Add(P1 p1, P2 p2) {
-    return static_cast<I*>(AddUncasted<I>(p1, p2));
+    return I::cast(AddUncasted<I>(p1, p2));
   }
 
   template<class I, class P1, class P2, class P3>
@@ -1412,6 +1412,11 @@
     LoopBuilder(HGraphBuilder* builder,
                 HValue* context,
                 Direction direction);
+    LoopBuilder(HGraphBuilder* builder,
+                HValue* context,
+                Direction direction,
+                HValue* increment_amount);
+
     ~LoopBuilder() {
       ASSERT(finished_);
     }
@@ -1420,6 +1425,9 @@
         HValue* initial,
         HValue* terminating,
         Token::Value token);
+
+    void Break();
+
     void EndBody();
 
    private:
@@ -1427,11 +1435,13 @@
 
     HGraphBuilder* builder_;
     HValue* context_;
+    HValue* increment_amount_;
     HInstruction* increment_;
     HPhi* phi_;
     HBasicBlock* header_block_;
     HBasicBlock* body_block_;
     HBasicBlock* exit_block_;
+    HBasicBlock* exit_trampoline_block_;
     Direction direction_;
     bool finished_;
   };
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index db50616..64f36b3 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -43,6 +43,17 @@
 namespace internal {
 
 
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { ebx };
+  descriptor->register_param_count_ = 1;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ =
+      Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
 void ToNumberStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -299,133 +310,6 @@
 }
 
 
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
-  // Create a new closure from the given function info in new
-  // space. Set the context to the current context in esi.
-  Counters* counters = masm->isolate()->counters();
-
-  Label gc;
-  __ Allocate(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
-
-  __ IncrementCounter(counters->fast_new_closure_total(), 1);
-
-  // Get the function info from the stack.
-  __ mov(edx, Operand(esp, 1 * kPointerSize));
-
-  int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
-  // Compute the function map in the current native context and set that
-  // as the map of the allocated object.
-  __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
-  __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset));
-  __ mov(ebx, Operand(ecx, Context::SlotOffset(map_index)));
-  __ mov(FieldOperand(eax, JSObject::kMapOffset), ebx);
-
-  // Initialize the rest of the function. We don't have to update the
-  // write barrier because the allocated object is in new space.
-  Factory* factory = masm->isolate()->factory();
-  __ mov(ebx, Immediate(factory->empty_fixed_array()));
-  __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx);
-  __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
-  __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset),
-         Immediate(factory->the_hole_value()));
-  __ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
-  __ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
-  __ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
-
-  // Initialize the code pointer in the function to be the one
-  // found in the shared function info object.
-  // But first check if there is an optimized version for our context.
-  Label check_optimized;
-  Label install_unoptimized;
-  if (FLAG_cache_optimized_code) {
-    __ mov(ebx, FieldOperand(edx, SharedFunctionInfo::kOptimizedCodeMapOffset));
-    __ test(ebx, ebx);
-    __ j(not_zero, &check_optimized, Label::kNear);
-  }
-  __ bind(&install_unoptimized);
-  __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
-         Immediate(factory->undefined_value()));
-  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
-  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-  __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
-
-  // Return and remove the on-stack parameter.
-  __ ret(1 * kPointerSize);
-
-  __ bind(&check_optimized);
-
-  __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
-
-  // ecx holds native context, ebx points to fixed array of 3-element entries
-  // (native context, optimized code, literals).
-  // Map must never be empty, so check the first elements.
-  Label install_optimized;
-  // Speculatively move code object into edx.
-  __ mov(edx, FieldOperand(ebx, SharedFunctionInfo::kFirstCodeSlot));
-  __ cmp(ecx, FieldOperand(ebx, SharedFunctionInfo::kFirstContextSlot));
-  __ j(equal, &install_optimized);
-
-  // Iterate through the rest of map backwards.  edx holds an index as a Smi.
-  Label loop;
-  Label restore;
-  __ mov(edx, FieldOperand(ebx, FixedArray::kLengthOffset));
-  __ bind(&loop);
-  // Do not double check first entry.
-  __ cmp(edx, Immediate(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
-  __ j(equal, &restore);
-  __ sub(edx, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
-  __ cmp(ecx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 0));
-  __ j(not_equal, &loop, Label::kNear);
-  // Hit: fetch the optimized code.
-  __ mov(edx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 1));
-
-  __ bind(&install_optimized);
-  __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
-
-  // TODO(fschneider): Idea: store proper code pointers in the optimized code
-  // map and either unmangle them on marking or do nothing as the whole map is
-  // discarded on major GC anyway.
-  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-  __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
-
-  // Now link a function into a list of optimized functions.
-  __ mov(edx, ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST));
-
-  __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset), edx);
-  // No need for write barrier as JSFunction (eax) is in the new space.
-
-  __ mov(ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST), eax);
-  // Store JSFunction (eax) into edx before issuing write barrier as
-  // it clobbers all the registers passed.
-  __ mov(edx, eax);
-  __ RecordWriteContextSlot(
-      ecx,
-      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
-      edx,
-      ebx,
-      kDontSaveFPRegs);
-
-  // Return and remove the on-stack parameter.
-  __ ret(1 * kPointerSize);
-
-  __ bind(&restore);
-  // Restore SharedFunctionInfo into edx.
-  __ mov(edx, Operand(esp, 1 * kPointerSize));
-  __ jmp(&install_unoptimized);
-
-  // Create a new closure through the slower runtime call.
-  __ bind(&gc);
-  __ pop(ecx);  // Temporarily remove return address.
-  __ pop(edx);
-  __ push(esi);
-  __ push(edx);
-  __ push(Immediate(factory->false_value()));
-  __ push(ecx);  // Restore return address.
-  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
 void FastNewContextStub::Generate(MacroAssembler* masm) {
   // Try to allocate the context in new space.
   Label gc;
@@ -4419,6 +4303,7 @@
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
+    __ SmiTag(eax);
     __ push(eax);
     __ push(edi);
     __ push(ebx);
@@ -4429,6 +4314,7 @@
     __ pop(ebx);
     __ pop(edi);
     __ pop(eax);
+    __ SmiUntag(eax);
   }
   __ jmp(&done);
 
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index bfe1f22..775a168 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1268,7 +1268,7 @@
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
     FastNewClosureStub stub(info->language_mode(), info->is_generator());
-    __ push(Immediate(info));
+    __ mov(ebx, Immediate(info));
     __ CallStub(&stub);
   } else {
     __ push(esi);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 81c22e2..ccd623c 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4349,6 +4349,14 @@
 }
 
 
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+  Register function = ToRegister(instr->function());
+  Register code_object = ToRegister(instr->code_object());
+  __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
+  __ mov(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
+}
+
+
 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
   Register result = ToRegister(instr->result());
   Register base = ToRegister(instr->base_object());
@@ -6209,7 +6217,7 @@
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
     FastNewClosureStub stub(instr->hydrogen()->language_mode(),
                             instr->hydrogen()->is_generator());
-    __ push(Immediate(instr->hydrogen()->shared_info()));
+    __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   } else {
     __ push(esi);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 2fdbb98..7ec1258 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -290,6 +290,14 @@
 }
 
 
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  function()->PrintTo(stream);
+  stream->Add(".code_entry = ");
+  code_object()->PrintTo(stream);
+}
+
+
 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
   stream->Add(" = ");
   base_object()->PrintTo(stream);
@@ -1150,6 +1158,14 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+    HStoreCodeEntry* store_code_entry) {
+  LOperand* function = UseRegister(store_code_entry->function());
+  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+  return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
     HInnerAllocatedObject* inner_object) {
   LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1929,13 +1945,14 @@
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      if (instr->value()->type().IsSmi()) {
-        LOperand* value = UseRegister(instr->value());
+      HValue* val = instr->value();
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        LOperand* value = UseRegister(val);
         return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
       } else {
         bool truncating = instr->CanTruncateToInt32();
         if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
-          LOperand* value = UseRegister(instr->value());
+          LOperand* value = UseRegister(val);
           LOperand* xmm_temp =
               (truncating && CpuFeatures::IsSupported(SSE3))
               ? NULL
@@ -1943,7 +1960,7 @@
           LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp);
           return AssignEnvironment(DefineSameAsFirst(res));
         } else {
-          LOperand* value = UseFixed(instr->value(), ecx);
+          LOperand* value = UseFixed(val, ecx);
           LTaggedToINoSSE2* res =
               new(zone()) LTaggedToINoSSE2(value, TempRegister(),
                                            TempRegister(), TempRegister());
@@ -2564,8 +2581,7 @@
 
 
 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  instr->ReplayEnvironment(env);
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // There are no real uses of a captured object.
   return NULL;
@@ -2615,20 +2631,7 @@
 
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  ASSERT(env != NULL);
-
-  env->set_ast_id(instr->ast_id());
-
-  env->Drop(instr->pop_count());
-  for (int i = instr->values()->length() - 1; i >= 0; --i) {
-    HValue* value = instr->values()->at(i);
-    if (instr->HasAssignedIndexAt(i)) {
-      env->Bind(instr->GetAssignedIndexAt(i), value);
-    } else {
-      env->Push(value);
-    }
-  }
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index a6a2526..e8a3baf 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -161,6 +161,7 @@
   V(SmiTag)                                     \
   V(SmiUntag)                                   \
   V(StackCheck)                                 \
+  V(StoreCodeEntry)                             \
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
@@ -1777,7 +1778,24 @@
 };
 
 
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+    inputs_[0] = function;
+    temps_[0] = code_object;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* code_object() { return temps_[0]; }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LInnerAllocatedObject(LOperand* base_object) {
     inputs_[0] = base_object;
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index bf785df..aaacbd9 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1977,50 +1977,15 @@
 }
 
 
-// If true, a Handle<T> returned by value from a function with cdecl calling
-// convention will be returned directly as a value of location_ field in a
-// register eax.
-// If false, it is returned as a pointer to a preallocated by caller memory
-// region. Pointer to this region should be passed to a function as an
-// implicit first argument.
-#if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__)
-static const bool kReturnHandlesDirectly = true;
-#else
-static const bool kReturnHandlesDirectly = false;
-#endif
-
-
-Operand ApiParameterOperand(int index, bool returns_handle) {
-  int offset = (index +(kReturnHandlesDirectly || !returns_handle ? 0 : 1));
-  return Operand(esp, offset * kPointerSize);
+Operand ApiParameterOperand(int index) {
+  return Operand(esp, index * kPointerSize);
 }
 
 
-void MacroAssembler::PrepareCallApiFunction(int argc, bool returns_handle) {
-  if (kReturnHandlesDirectly || !returns_handle) {
-    EnterApiExitFrame(argc);
-    // When handles are returned directly we don't have to allocate extra
-    // space for and pass an out parameter.
-    if (emit_debug_code()) {
-      mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
-    }
-  } else {
-    // We allocate two additional slots: return value and pointer to it.
-    EnterApiExitFrame(argc + 2);
-
-    // The argument slots are filled as follows:
-    //
-    //   n + 1: output slot
-    //   n: arg n
-    //   ...
-    //   1: arg1
-    //   0: pointer to the output slot
-
-    lea(esi, Operand(esp, (argc + 1) * kPointerSize));
-    mov(Operand(esp, 0 * kPointerSize), esi);
-    if (emit_debug_code()) {
-      mov(Operand(esi, 0), Immediate(0));
-    }
+void MacroAssembler::PrepareCallApiFunction(int argc) {
+  EnterApiExitFrame(argc);
+  if (emit_debug_code()) {
+    mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
   }
 }
 
@@ -2029,7 +1994,6 @@
                                               Address thunk_address,
                                               Operand thunk_last_arg,
                                               int stack_space,
-                                              bool returns_handle,
                                               int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
@@ -2085,21 +2049,6 @@
   }
 
   Label prologue;
-  if (returns_handle) {
-    if (!kReturnHandlesDirectly) {
-      // PrepareCallApiFunction saved pointer to the output slot into
-      // callee-save register esi.
-      mov(eax, Operand(esi, 0));
-    }
-    Label empty_handle;
-    // Check if the result handle holds 0.
-    test(eax, eax);
-    j(zero, &empty_handle);
-    // It was non-zero.  Dereference to get the result value.
-    mov(eax, Operand(eax, 0));
-    jmp(&prologue);
-    bind(&empty_handle);
-  }
   // Load the value from ReturnValue
   mov(eax, Operand(ebp, return_value_offset * kPointerSize));
 
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index d537b0b..4d9ebad 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -782,7 +782,7 @@
   // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
   // etc. Saves context (esi). If space was reserved for return value then
   // stores the pointer to the reserved slot into esi.
-  void PrepareCallApiFunction(int argc, bool returns_handle);
+  void PrepareCallApiFunction(int argc);
 
   // Calls an API function.  Allocates HandleScope, extracts returned value
   // from handle and propagates exceptions.  Clobbers ebx, edi and
@@ -792,7 +792,6 @@
                                 Address thunk_address,
                                 Operand thunk_last_arg,
                                 int stack_space,
-                                bool returns_handle,
                                 int return_value_offset_from_ebp);
 
   // Jump to a runtime routine.
@@ -1039,7 +1038,7 @@
 
 
 // Generates an Operand for saving parameters after PrepareCallApiFunction.
-Operand ApiParameterOperand(int index, bool returns_handle);
+Operand ApiParameterOperand(int index);
 
 
 #ifdef GENERATED_CODE_COVERAGE
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index dfcc869..7d9e2f7 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -711,7 +711,7 @@
   // position registers.
   __ mov(Operand(ebp, kInputStartMinusOne), eax);
 
-#ifdef WIN32
+#if V8_OS_WIN
   // Ensure that we write to each stack page, in order. Skipping a page
   // on Windows can cause segmentation faults. Assuming page size is 4k.
   const int kPageSize = 4096;
@@ -721,7 +721,7 @@
       i += kRegistersPerPage) {
     __ mov(register_location(i), eax);  // One write every page.
   }
-#endif  // WIN32
+#endif  // V8_OS_WIN
 
   Label load_char_start_regexp, start_regexp;
   // Load newline if index is at start, previous character otherwise.
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 93293a9..9aa7bae 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -516,34 +516,28 @@
 
   // Function address is a foreign pointer outside V8's heap.
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  bool returns_handle =
-    !CallbackTable::ReturnsVoid(masm->isolate(),
-                                reinterpret_cast<void*>(function_address));
-  __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle);
+  __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
 
   // v8::Arguments::implicit_args_.
-  __ mov(ApiParameterOperand(2, returns_handle), eax);
+  __ mov(ApiParameterOperand(2), eax);
   __ add(eax, Immediate(argc * kPointerSize));
   // v8::Arguments::values_.
-  __ mov(ApiParameterOperand(3, returns_handle), eax);
+  __ mov(ApiParameterOperand(3), eax);
   // v8::Arguments::length_.
-  __ Set(ApiParameterOperand(4, returns_handle), Immediate(argc));
+  __ Set(ApiParameterOperand(4), Immediate(argc));
   // v8::Arguments::is_construct_call_.
-  __ Set(ApiParameterOperand(5, returns_handle), Immediate(0));
+  __ Set(ApiParameterOperand(5), Immediate(0));
 
   // v8::InvocationCallback's argument.
-  __ lea(eax, ApiParameterOperand(2, returns_handle));
-  __ mov(ApiParameterOperand(0, returns_handle), eax);
+  __ lea(eax, ApiParameterOperand(2));
+  __ mov(ApiParameterOperand(0), eax);
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeInvocationCallback)
-      : FUNCTION_ADDR(&InvokeFunctionCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
-                              ApiParameterOperand(1, returns_handle),
+                              ApiParameterOperand(1),
                               argc + kFastApiCallArguments + 1,
-                              returns_handle,
                               kFastApiCallArguments + 1);
 }
 
@@ -1400,28 +1394,22 @@
   const int kApiArgc = 2 + 1;
 
   Address getter_address = v8::ToCData<Address>(callback->getter());
-  bool returns_handle =
-    !CallbackTable::ReturnsVoid(isolate(),
-                                reinterpret_cast<void*>(getter_address));
-  __ PrepareCallApiFunction(kApiArgc, returns_handle);
-  __ mov(ApiParameterOperand(0, returns_handle), ebx);  // name.
+  __ PrepareCallApiFunction(kApiArgc);
+  __ mov(ApiParameterOperand(0), ebx);  // name.
   __ add(ebx, Immediate(kPointerSize));
-  __ mov(ApiParameterOperand(1, returns_handle), ebx);  // arguments pointer.
+  __ mov(ApiParameterOperand(1), ebx);  // arguments pointer.
 
   // Emitting a stub call may try to allocate (if the code is not
   // already generated).  Do not allow the assembler to perform a
   // garbage collection but instead return the allocation failure
   // object.
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeAccessorGetter)
-      : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
 
   __ CallApiFunctionAndReturn(getter_address,
                               thunk_address,
-                              ApiParameterOperand(2, returns_handle),
+                              ApiParameterOperand(2),
                               kStackSpace,
-                              returns_handle,
                               6);
 }
 
diff --git a/src/ic.cc b/src/ic.cc
index a8d3527..2a1f83d 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2581,7 +2581,7 @@
   v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value);
   if (type.IsSmi()) return BinaryOpIC::SMI;
   if (type.IsInteger32()) {
-    if (kSmiValueSize == 32) return BinaryOpIC::SMI;
+    if (SmiValuesAre32Bits()) return BinaryOpIC::SMI;
     return BinaryOpIC::INT32;
   }
   if (type.IsNumber()) return BinaryOpIC::NUMBER;
@@ -2593,7 +2593,7 @@
         op == Token::SAR ||
         op == Token::SHL ||
         op == Token::SHR) {
-      if (kSmiValueSize == 32) return BinaryOpIC::SMI;
+      if (SmiValuesAre32Bits()) return BinaryOpIC::SMI;
       return BinaryOpIC::INT32;
     }
     return BinaryOpIC::ODDBALL;
@@ -2671,7 +2671,7 @@
       if (op == Token::DIV ||
           op == Token::MUL ||
           op == Token::SHR ||
-          kSmiValueSize == 32) {
+          SmiValuesAre32Bits()) {
         // Arithmetic on two Smi inputs has yielded a heap number.
         // That is the only way to get here from the Smi stub.
         // With 32-bit Smis, all overflows give heap numbers, but with
diff --git a/src/isolate.cc b/src/isolate.cc
index b70dd68..774ad5c 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1793,7 +1793,6 @@
       optimizing_compiler_thread_(this),
       marking_thread_(NULL),
       sweeper_thread_(NULL),
-      callback_table_(NULL),
       stress_deopt_count_(0) {
   id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1);
   TRACE_ISOLATE(constructor);
@@ -2063,9 +2062,6 @@
   delete external_reference_table_;
   external_reference_table_ = NULL;
 
-  delete callback_table_;
-  callback_table_ = NULL;
-
 #ifdef ENABLE_DEBUGGER_SUPPORT
   delete debugger_;
   debugger_ = NULL;
@@ -2329,6 +2325,7 @@
     ToBooleanStub::InitializeForIsolate(this);
     ArrayConstructorStubBase::InstallDescriptors(this);
     InternalArrayConstructorStubBase::InstallDescriptors(this);
+    FastNewClosureStub::InstallDescriptors(this);
   }
 
   if (FLAG_concurrent_recompilation) optimizing_compiler_thread_.Start();
diff --git a/src/isolate.h b/src/isolate.h
index 401505a..3d42cad 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -52,7 +52,6 @@
 namespace internal {
 
 class Bootstrapper;
-class CallbackTable;
 class CodeGenerator;
 class CodeRange;
 struct CodeStubInterfaceDescriptor;
@@ -321,7 +320,6 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
 #define ISOLATE_DEBUGGER_INIT_LIST(V)                                          \
-  V(v8::Debug::EventCallback, debug_event_callback, NULL)                      \
   V(DebuggerAgent*, debugger_agent_instance, NULL)
 #else
 
@@ -361,7 +359,6 @@
   V(byte*, assembler_spare_buffer, NULL)                                       \
   V(FatalErrorCallback, exception_behavior, NULL)                              \
   V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL)     \
-  V(v8::Debug::MessageHandler, message_handler, NULL)                          \
   /* To distinguish the function templates, so that we can find them in the */ \
   /* function cache of the native context. */                                  \
   V(int, next_serial_number, 0)                                                \
@@ -1111,13 +1108,6 @@
     return sweeper_thread_;
   }
 
-  CallbackTable* callback_table() {
-    return callback_table_;
-  }
-  void set_callback_table(CallbackTable* callback_table) {
-    callback_table_ = callback_table;
-  }
-
   int id() const { return static_cast<int>(id_); }
 
   HStatistics* GetHStatistics();
@@ -1363,7 +1353,6 @@
   OptimizingCompilerThread optimizing_compiler_thread_;
   MarkingThread** marking_thread_;
   SweeperThread** sweeper_thread_;
-  CallbackTable* callback_table_;
 
   // Counts deopt points if deopt_every_n_times is enabled.
   unsigned int stress_deopt_count_;
diff --git a/src/macros.py b/src/macros.py
index d50231d..f1a2130 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -67,7 +67,8 @@
 
 # For apinatives.js
 const kUninitialized = -1;
-const kReadOnlyPrototypeBit = 3;  # For FunctionTemplateInfo, matches objects.h
+const kReadOnlyPrototypeBit = 3;
+const kRemovePrototypeBit = 4;  # For FunctionTemplateInfo, matches objects.h
 
 # Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
 const kInvalidDate        = 'Invalid Date';
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 8a03a9a..2c42001 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -39,6 +39,17 @@
 namespace internal {
 
 
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { a2 };
+  descriptor->register_param_count_ = 1;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ =
+      Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
 void ToNumberStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -310,134 +321,6 @@
 }
 
 
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
-  // Create a new closure from the given function info in new
-  // space. Set the context to the current context in cp.
-  Counters* counters = masm->isolate()->counters();
-
-  Label gc;
-
-  // Pop the function info from the stack.
-  __ pop(a3);
-
-  // Attempt to allocate new JSFunction in new space.
-  __ Allocate(JSFunction::kSize, v0, a1, a2, &gc, TAG_OBJECT);
-
-  __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3);
-
-  int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
-  // Compute the function map in the current native context and set that
-  // as the map of the allocated object.
-  __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
-  __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
-  __ lw(t1, MemOperand(a2, Context::SlotOffset(map_index)));
-  __ sw(t1, FieldMemOperand(v0, HeapObject::kMapOffset));
-
-  // Initialize the rest of the function. We don't have to update the
-  // write barrier because the allocated object is in new space.
-  __ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex);
-  __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
-  __ sw(a1, FieldMemOperand(v0, JSObject::kPropertiesOffset));
-  __ sw(a1, FieldMemOperand(v0, JSObject::kElementsOffset));
-  __ sw(t1, FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
-  __ sw(a3, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset));
-  __ sw(cp, FieldMemOperand(v0, JSFunction::kContextOffset));
-  __ sw(a1, FieldMemOperand(v0, JSFunction::kLiteralsOffset));
-
-  // Initialize the code pointer in the function to be the one
-  // found in the shared function info object.
-  // But first check if there is an optimized version for our context.
-  Label check_optimized;
-  Label install_unoptimized;
-  if (FLAG_cache_optimized_code) {
-    __ lw(a1,
-          FieldMemOperand(a3, SharedFunctionInfo::kOptimizedCodeMapOffset));
-    __ And(at, a1, a1);
-    __ Branch(&check_optimized, ne, at, Operand(zero_reg));
-  }
-  __ bind(&install_unoptimized);
-  __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
-  __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
-  __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kCodeOffset));
-  __ Addu(a3, a3, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-  // Return result. The argument function info has been popped already.
-  __ Ret(USE_DELAY_SLOT);
-  __ sw(a3, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
-
-  __ bind(&check_optimized);
-
-  __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, t2, t3);
-
-  // a2 holds native context, a1 points to fixed array of 3-element entries
-  // (native context, optimized code, literals).
-  // The optimized code map must never be empty, so check the first elements.
-  Label install_optimized;
-  // Speculatively move code object into t0.
-  __ lw(t0, FieldMemOperand(a1, SharedFunctionInfo::kFirstCodeSlot));
-  __ lw(t1, FieldMemOperand(a1, SharedFunctionInfo::kFirstContextSlot));
-  __ Branch(&install_optimized, eq, a2, Operand(t1));
-
-  // Iterate through the rest of map backwards.  t0 holds an index as a Smi.
-  Label loop;
-  __ lw(t0, FieldMemOperand(a1, FixedArray::kLengthOffset));
-  __ bind(&loop);
-  // Do not double check first entry.
-  __ Branch(&install_unoptimized, eq, t0,
-            Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
-  __ Subu(t0, t0, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
-  __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
-  __ Addu(t1, t1, Operand(at));
-  __ lw(t1, MemOperand(t1));
-  __ Branch(&loop, ne, a2, Operand(t1));
-  // Hit: fetch the optimized code.
-  __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
-  __ Addu(t1, t1, Operand(at));
-  __ Addu(t1, t1, Operand(kPointerSize));
-  __ lw(t0, MemOperand(t1));
-
-  __ bind(&install_optimized);
-  __ IncrementCounter(counters->fast_new_closure_install_optimized(),
-                      1, t2, t3);
-
-  // TODO(fschneider): Idea: store proper code pointers in the map and either
-  // unmangle them on marking or do nothing as the whole map is discarded on
-  // major GC anyway.
-  __ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ sw(t0, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
-
-  // Now link a function into a list of optimized functions.
-  __ lw(t0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
-
-  __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
-  // No need for write barrier as JSFunction (eax) is in the new space.
-
-  __ sw(v0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
-  // Store JSFunction (eax) into edx before issuing write barrier as
-  // it clobbers all the registers passed.
-  __ mov(t0, v0);
-  __ RecordWriteContextSlot(
-      a2,
-      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
-      t0,
-      a1,
-      kRAHasNotBeenSaved,
-      kDontSaveFPRegs);
-
-  // Return result. The argument function info has been popped already.
-  __ Ret();
-
-  // Create a new closure through the slower runtime call.
-  __ bind(&gc);
-  __ LoadRoot(t0, Heap::kFalseValueRootIndex);
-  __ Push(cp, a3, t0);
-  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
 void FastNewContextStub::Generate(MacroAssembler* masm) {
   // Try to allocate the context in new space.
   Label gc;
@@ -4808,12 +4691,14 @@
         1 << 5  |  // a1
         1 << 6;    // a2
 
+    __ SmiTag(a0);
     __ MultiPush(kSavedRegs);
 
     CreateAllocationSiteStub create_stub;
     __ CallStub(&create_stub);
 
     __ MultiPop(kSavedRegs);
+    __ SmiUntag(a0);
   }
   __ Branch(&done);
 
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 708df39..691df94 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -50,9 +50,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
-#ifndef WIN32
-#include <stdint.h>
-#endif
 
 #include "v8.h"
 
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9da8e54..d59820f 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -1333,8 +1333,7 @@
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
     FastNewClosureStub stub(info->language_mode(), info->is_generator());
-    __ li(a0, Operand(info));
-    __ push(a0);
+    __ li(a2, Operand(info));
     __ CallStub(&stub);
   } else {
     __ li(a0, Operand(info));
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index aa56d72..80794c8 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -409,7 +409,7 @@
     } else if (r.IsDouble()) {
       Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
     } else {
-      ASSERT(r.IsTagged());
+      ASSERT(r.IsSmiOrTagged());
       __ LoadObject(scratch, literal);
     }
     return scratch;
@@ -1398,10 +1398,7 @@
     instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
 
   if (right_op->IsConstantOperand() && !can_overflow) {
-    // Use optimized code for specific constants.
-    int32_t constant = ToRepresentation(
-        LConstantOperand::cast(right_op),
-        instr->hydrogen()->right()->representation());
+    int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
 
     if (bailout_on_minus_zero && (constant < 0)) {
       // The case of a null constant will be handled separately.
@@ -4067,6 +4064,16 @@
 }
 
 
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+  Register function = ToRegister(instr->function());
+  Register code_object = ToRegister(instr->code_object());
+  __ Addu(code_object, code_object,
+          Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ sw(code_object,
+        FieldMemOperand(function, JSFunction::kCodeEntryOffset));
+}
+
+
 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
   Register result = ToRegister(instr->result());
   Register base = ToRegister(instr->base_object());
@@ -5407,8 +5414,7 @@
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
     FastNewClosureStub stub(instr->hydrogen()->language_mode(),
                             instr->hydrogen()->is_generator());
-    __ li(a1, Operand(instr->hydrogen()->shared_info()));
-    __ push(a1);
+    __ li(a2, Operand(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   } else {
     __ li(a2, Operand(instr->hydrogen()->shared_info()));
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 8025d8e..b11c9c2 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -265,6 +265,14 @@
 }
 
 
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  function()->PrintTo(stream);
+  stream->Add(".code_entry = ");
+  code_object()->PrintTo(stream);
+}
+
+
 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
   stream->Add(" = ");
   base_object()->PrintTo(stream);
@@ -1079,6 +1087,14 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+    HStoreCodeEntry* store_code_entry) {
+  LOperand* function = UseRegister(store_code_entry->function());
+  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+  return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
     HInnerAllocatedObject* inner_object) {
   LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1828,11 +1844,12 @@
       ASSERT(to.IsInteger32());
       LOperand* value = NULL;
       LInstruction* res = NULL;
-      if (instr->value()->type().IsSmi()) {
-        value = UseRegisterAtStart(instr->value());
+      HValue* val = instr->value();
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        value = UseRegisterAtStart(val);
         res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
-        value = UseRegister(instr->value());
+        value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                       : NULL;
@@ -2361,8 +2378,7 @@
 
 
 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  instr->ReplayEnvironment(env);
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // There are no real uses of a captured object.
   return NULL;
@@ -2410,20 +2426,7 @@
 
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  ASSERT(env != NULL);
-
-  env->set_ast_id(instr->ast_id());
-
-  env->Drop(instr->pop_count());
-  for (int i = instr->values()->length() - 1; i >= 0; --i) {
-    HValue* value = instr->values()->at(i);
-    if (instr->HasAssignedIndexAt(i)) {
-      env->Bind(instr->GetAssignedIndexAt(i), value);
-    } else {
-      env->Push(value);
-    }
-  }
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 479f75a..6498943 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -161,6 +161,7 @@
   V(SmiTag)                                     \
   V(SmiUntag)                                   \
   V(StackCheck)                                 \
+  V(StoreCodeEntry)                             \
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
@@ -1731,7 +1732,24 @@
 };
 
 
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+    inputs_[0] = function;
+    temps_[0] = code_object;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* code_object() { return temps_[0]; }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LInnerAllocatedObject(LOperand* base_object) {
     inputs_[0] = base_object;
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 5becf7c..ace7323 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3963,7 +3963,6 @@
                                               ExternalReference thunk_ref,
                                               Register thunk_last_arg,
                                               int stack_space,
-                                              bool returns_handle,
                                               int return_value_offset_from_fp) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
@@ -3992,14 +3991,6 @@
     PopSafepointRegisters();
   }
 
-  // The O32 ABI requires us to pass a pointer in a0 where the returned struct
-  // (4 bytes) will be placed. This is also built into the Simulator.
-  // Set up the pointer to the returned value (a0). It was allocated in
-  // EnterExitFrame.
-  if (returns_handle) {
-    addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
-  }
-
   Label profiler_disabled;
   Label end_profiler_check;
   bool* is_profiling_flag =
@@ -4039,19 +4030,6 @@
   Label leave_exit_frame;
   Label return_value_loaded;
 
-  if (returns_handle) {
-    Label load_return_value;
-
-    // As mentioned above, on MIPS a pointer is returned - we need to
-    // dereference it to get the actual return value (which is also a pointer).
-    lw(v0, MemOperand(v0));
-
-    Branch(&load_return_value, eq, v0, Operand(zero_reg));
-    // Dereference returned value.
-    lw(v0, MemOperand(v0));
-    Branch(&return_value_loaded);
-    bind(&load_return_value);
-  }
   // Load value from ReturnValue.
   lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
   bind(&return_value_loaded);
@@ -4477,6 +4455,11 @@
     RecordComment("Abort message: ");
     RecordComment(msg);
   }
+
+  if (FLAG_trap_on_abort) {
+    stop(msg);
+    return;
+  }
 #endif
 
   li(a0, Operand(p0));
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 3b3cfdb..9605038 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1233,7 +1233,6 @@
                                 ExternalReference thunk_ref,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                bool returns_handle,
                                 int return_value_offset_from_fp);
 
   // Jump to the builtin routine.
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 914a758..ea8b659 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1387,27 +1387,12 @@
 
 // This signature supports direct call in to API function native callback
 // (refer to InvocationCallback in v8.h).
-// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
-// struct from the function (which is currently the case). This means we pass
-// the first argument in a1 instead of a0.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-// Here, we pass the first argument in a0, because this function
-// does not return a struct.
-typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
-    int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
 
 // This signature supports direct call to accessor getter callback.
-// See comment at SimulatorRuntimeDirectApiCall.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
-                                                                  int32_t arg1);
-// See comment at SimulatorRuntimeDirectApiCallNew.
-typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
-                                                    int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
-    int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(
     int32_t arg0, int32_t arg1, int32_t arg2);
 
 // Software interrupt instructions are used by the simulator to call into the
@@ -1553,102 +1538,41 @@
           break;
         }
       }
-    } else if (
-        redirection->type() == ExternalReference::DIRECT_API_CALL ||
-        redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
-      if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
-        // See comment at type definition of SimulatorRuntimeDirectApiCall
-        // for explanation of register usage.
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x\n",
-              reinterpret_cast<void*>(external), arg1);
-        }
-        SimulatorRuntimeDirectApiCall target =
-            reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
-        v8::Handle<v8::Value> result = target(arg1);
-        *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
-        set_register(v0, arg0);
-      } else {
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x\n",
-              reinterpret_cast<void*>(external), arg0);
-        }
-        SimulatorRuntimeDirectApiCallNew target =
-            reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
-        target(arg0);
+    } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
+      if (::v8::internal::FLAG_trace_sim) {
+        PrintF("Call to host function at %p args %08x\n",
+            reinterpret_cast<void*>(external), arg0);
       }
+      SimulatorRuntimeDirectApiCall target =
+          reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+      target(arg0);
     } else if (
-        redirection->type() == ExternalReference::PROFILING_API_CALL ||
-        redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
-      if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
-        // See comment at type definition of SimulatorRuntimeDirectApiCall
-        // for explanation of register usage.
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x\n",
-              reinterpret_cast<void*>(external), arg1, arg2);
-        }
-        SimulatorRuntimeProfilingApiCall target =
-            reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
-        v8::Handle<v8::Value> result = target(arg1, arg2);
-        *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
-        set_register(v0, arg0);
-      } else {
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x\n",
-              reinterpret_cast<void*>(external), arg0, arg1);
-        }
-        SimulatorRuntimeProfilingApiCallNew target =
-            reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
-        target(arg0, arg1);
+        redirection->type() == ExternalReference::PROFILING_API_CALL) {
+      if (::v8::internal::FLAG_trace_sim) {
+        PrintF("Call to host function at %p args %08x %08x\n",
+            reinterpret_cast<void*>(external), arg0, arg1);
       }
+      SimulatorRuntimeProfilingApiCall target =
+          reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+      target(arg0, arg1);
     } else if (
-        redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
-        redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
-      if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
-        // See comment at type definition of SimulatorRuntimeDirectGetterCall
-        // for explanation of register usage.
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x\n",
-              reinterpret_cast<void*>(external), arg1, arg2);
-        }
-        SimulatorRuntimeDirectGetterCall target =
-            reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
-        v8::Handle<v8::Value> result = target(arg1, arg2);
-        *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
-        set_register(v0, arg0);
-      } else {
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x\n",
-              reinterpret_cast<void*>(external), arg0, arg1);
-        }
-        SimulatorRuntimeDirectGetterCallNew target =
-            reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
-        target(arg0, arg1);
+        redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
+      if (::v8::internal::FLAG_trace_sim) {
+        PrintF("Call to host function at %p args %08x %08x\n",
+            reinterpret_cast<void*>(external), arg0, arg1);
       }
+      SimulatorRuntimeDirectGetterCall target =
+          reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+      target(arg0, arg1);
     } else if (
-        redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
-        redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
-      if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
-        // See comment at type definition of SimulatorRuntimeProfilingGetterCall
-        // for explanation of register usage.
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x %08x\n",
-              reinterpret_cast<void*>(external), arg1, arg2, arg3);
-        }
-        SimulatorRuntimeProfilingGetterCall target =
-            reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
-        v8::Handle<v8::Value> result = target(arg1, arg2, arg3);
-        *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
-        set_register(v0, arg0);
-      } else {
-        if (::v8::internal::FLAG_trace_sim) {
-          PrintF("Call to host function at %p args %08x %08x %08x\n",
-              reinterpret_cast<void*>(external), arg0, arg1, arg2);
-        }
-        SimulatorRuntimeProfilingGetterCallNew target =
-            reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(external);
-        target(arg0, arg1, arg2);
+        redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
+      if (::v8::internal::FLAG_trace_sim) {
+        PrintF("Call to host function at %p args %08x %08x %08x\n",
+            reinterpret_cast<void*>(external), arg0, arg1, arg2);
       }
+      SimulatorRuntimeProfilingGetterCall target =
+          reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
+      target(arg0, arg1, arg2);
     } else {
       SimulatorRuntimeCall target =
                   reinterpret_cast<SimulatorRuntimeCall>(external);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index b84aca7..ccbe86a 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -879,51 +879,31 @@
   FrameScope frame_scope(masm, StackFrame::MANUAL);
   __ EnterExitFrame(false, kApiStackSpace);
 
-  // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
-  // struct from the function (which is currently the case). This means we pass
-  // the first argument in a1 instead of a0, if returns_handle is true.
-  // CallApiFunctionAndReturn will set up a0.
-
-  Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
-
-  Register first_arg = returns_handle ? a1 : a0;
-  Register second_arg = returns_handle ? a2 : a1;
-
-  // first_arg = v8::Arguments&
+  // a0 = v8::Arguments&
   // Arguments is built at sp + 1 (sp is a reserved spot for ra).
-  __ Addu(first_arg, sp, kPointerSize);
+  __ Addu(a0, sp, kPointerSize);
 
   // v8::Arguments::implicit_args_
-  __ sw(a2, MemOperand(first_arg, 0 * kPointerSize));
+  __ sw(a2, MemOperand(a0, 0 * kPointerSize));
   // v8::Arguments::values_
   __ Addu(t0, a2, Operand(argc * kPointerSize));
-  __ sw(t0, MemOperand(first_arg, 1 * kPointerSize));
+  __ sw(t0, MemOperand(a0, 1 * kPointerSize));
   // v8::Arguments::length_ = argc
   __ li(t0, Operand(argc));
-  __ sw(t0, MemOperand(first_arg, 2 * kPointerSize));
+  __ sw(t0, MemOperand(a0, 2 * kPointerSize));
   // v8::Arguments::is_construct_call = 0
-  __ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize));
+  __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
 
   const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
+  Address function_address = v8::ToCData<Address>(api_call_info->callback());
   ApiFunction fun(function_address);
-  ExternalReference::Type type =
-      returns_handle ?
-          ExternalReference::DIRECT_API_CALL :
-          ExternalReference::DIRECT_API_CALL_NEW;
+  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
   ExternalReference ref =
       ExternalReference(&fun,
                         type,
                         masm->isolate());
-
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeInvocationCallback)
-      : FUNCTION_ADDR(&InvokeFunctionCallback);
-  ExternalReference::Type thunk_type =
-      returns_handle ?
-          ExternalReference::PROFILING_API_CALL :
-          ExternalReference::PROFILING_API_CALL_NEW;
+  Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+  ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
   ApiFunction thunk_fun(thunk_address);
   ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
       masm->isolate());
@@ -932,9 +912,8 @@
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
-                              second_arg,
+                              a1,
                               kStackUnwindSpace,
-                              returns_handle,
                               kFastApiCallArguments + 1);
 }
 
@@ -1419,21 +1398,8 @@
   __ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
   __ sw(name(), MemOperand(sp, 0 * kPointerSize));
 
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(isolate(), getter_address);
-
-  Register first_arg = returns_handle ? a1 : a0;
-  Register second_arg = returns_handle ? a2 : a1;
-  Register third_arg = returns_handle ? a3 : a2;
-
   __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
-  __ mov(first_arg, sp);  // (first argument - see note below) = Handle<Name>
-
-  // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
-  // struct from the function (which is currently the case). This means we pass
-  // the arguments in a1-a2 instead of a0-a1, if returns_handle is true.
-  // CallApiFunctionAndReturn will set up a0.
+  __ mov(a0, sp);  // (first argument - a0) = Handle<Name>
 
   const int kApiStackSpace = 1;
   FrameScope frame_scope(masm(), StackFrame::MANUAL);
@@ -1442,34 +1408,26 @@
   // Create AccessorInfo instance on the stack above the exit frame with
   // scratch2 (internal::Object** args_) as the data.
   __ sw(a2, MemOperand(sp, kPointerSize));
-  // (second argument - see note above) = AccessorInfo&
-  __ Addu(second_arg, sp, kPointerSize);
+  // (second argument - a1) = AccessorInfo&
+  __ Addu(a1, sp, kPointerSize);
 
   const int kStackUnwindSpace = kFastApiCallArguments + 1;
-
+  Address getter_address = v8::ToCData<Address>(callback->getter());
   ApiFunction fun(getter_address);
-  ExternalReference::Type type =
-      returns_handle ?
-          ExternalReference::DIRECT_GETTER_CALL :
-          ExternalReference::DIRECT_GETTER_CALL_NEW;
+  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
   ExternalReference ref = ExternalReference(&fun, type, isolate());
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeAccessorGetter)
-      : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
   ExternalReference::Type thunk_type =
-      returns_handle ?
-          ExternalReference::PROFILING_GETTER_CALL :
-          ExternalReference::PROFILING_GETTER_CALL_NEW;
+      ExternalReference::PROFILING_GETTER_CALL;
   ApiFunction thunk_fun(thunk_address);
   ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
       isolate());
   __ CallApiFunctionAndReturn(ref,
                               getter_address,
                               thunk_ref,
-                              third_arg,
+                              a2,
                               kStackUnwindSpace,
-                              returns_handle,
                               5);
 }
 
@@ -1803,25 +1761,25 @@
                   &call_builtin,
                   DONT_DO_SMI_CHECK);
 
-      // Get the array's length into r0 and calculate new length.
-      __ lw(a0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+      // Get the array's length into v0 and calculate new length.
+      __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
       STATIC_ASSERT(kSmiTagSize == 1);
       STATIC_ASSERT(kSmiTag == 0);
-      __ Addu(a0, a0, Operand(Smi::FromInt(argc)));
+      __ Addu(v0, v0, Operand(Smi::FromInt(argc)));
 
       // Get the elements' length.
       __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
 
       // Check if we could survive without allocation.
-      __ Branch(&call_builtin, gt, a0, Operand(t0));
+      __ Branch(&call_builtin, gt, v0, Operand(t0));
 
       __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
       __ StoreNumberToDoubleElements(
-          t0, a0, elements, a3, t1, a2, t5,
+          t0, v0, elements, a3, t1, a2, t5,
           &call_builtin, argc * kDoubleSize);
 
       // Save new length.
-      __ sw(a0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+      __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
 
       // Check for a smi.
       __ DropAndRet(argc + 1);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 22d1ac3..b165ad4 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1312,7 +1312,7 @@
 
 
 bool JSObject::ShouldTrackAllocationInfo() {
-  if (map()->CanTrackAllocationSite()) {
+  if (AllocationSite::CanTrack(map()->instance_type())) {
     if (!IsJSArray()) {
       return true;
     }
@@ -1349,6 +1349,11 @@
 }
 
 
+inline bool AllocationSite::CanTrack(InstanceType type) {
+  return type == JS_ARRAY_TYPE;
+}
+
+
 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
   ValidateElements();
   ElementsKind elements_kind = map()->elements_kind();
@@ -3593,11 +3598,6 @@
 }
 
 
-inline bool Map::CanTrackAllocationSite() {
-  return instance_type() == JS_ARRAY_TYPE;
-}
-
-
 void Map::set_owns_descriptors(bool is_shared) {
   set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
 }
@@ -4576,6 +4576,8 @@
                kNeedsAccessCheckBit)
 BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
                kReadOnlyPrototypeBit)
+BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
+               kRemovePrototypeBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
diff --git a/src/objects.cc b/src/objects.cc
index d8a05eb..3e4601a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -368,7 +368,8 @@
     }
     ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure);
     Object* fun_obj = data->getter();
-    v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+    v8::AccessorGetterCallback call_fun =
+        v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
     if (call_fun == NULL) return isolate->heap()->undefined_value();
     HandleScope scope(isolate);
     JSObject* self = JSObject::cast(receiver);
@@ -2772,8 +2773,8 @@
   if (!interceptor->setter()->IsUndefined()) {
     LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
     PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
-    v8::NamedPropertySetter setter =
-        v8::ToCData<v8::NamedPropertySetter>(interceptor->setter());
+    v8::NamedPropertySetterCallback setter =
+        v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
     Handle<Object> value_unhole(value->IsTheHole() ?
                                 isolate->heap()->undefined_value() :
                                 value,
@@ -2874,7 +2875,8 @@
     // TODO(rossberg): Support symbols in the API.
     if (name->IsSymbol()) return value;
     Object* call_obj = data->setter();
-    v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
+    v8::AccessorSetterCallback call_fun =
+        v8::ToCData<v8::AccessorSetterCallback>(call_obj);
     if (call_fun == NULL) return value;
     Handle<String> key(String::cast(name));
     LOG(isolate, ApiNamedPropertyAccess("store", this, name));
@@ -4230,8 +4232,8 @@
   Handle<String> name_handle(String::cast(name));
   PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
   if (!interceptor->query()->IsUndefined()) {
-    v8::NamedPropertyQuery query =
-        v8::ToCData<v8::NamedPropertyQuery>(interceptor->query());
+    v8::NamedPropertyQueryCallback query =
+        v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
     v8::Handle<v8::Integer> result =
@@ -4241,8 +4243,8 @@
       return static_cast<PropertyAttributes>(result->Int32Value());
     }
   } else if (!interceptor->getter()->IsUndefined()) {
-    v8::NamedPropertyGetter getter =
-        v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
+    v8::NamedPropertyGetterCallback getter =
+        v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-get-has", this, name));
     v8::Handle<v8::Value> result =
@@ -4362,16 +4364,16 @@
   Handle<JSObject> holder(this);
   PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
   if (!interceptor->query()->IsUndefined()) {
-    v8::IndexedPropertyQuery query =
-        v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query());
+    v8::IndexedPropertyQueryCallback query =
+        v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
     LOG(isolate,
         ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
     v8::Handle<v8::Integer> result = args.Call(query, index);
     if (!result.IsEmpty())
       return static_cast<PropertyAttributes>(result->Int32Value());
   } else if (!interceptor->getter()->IsUndefined()) {
-    v8::IndexedPropertyGetter getter =
-        v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
+    v8::IndexedPropertyGetterCallback getter =
+        v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
     LOG(isolate,
         ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index));
     v8::Handle<v8::Value> result = args.Call(getter, index);
@@ -5038,8 +5040,8 @@
 
   Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
   if (!interceptor->deleter()->IsUndefined()) {
-    v8::NamedPropertyDeleter deleter =
-        v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter());
+    v8::NamedPropertyDeleterCallback deleter =
+        v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-delete", *object, *name));
     PropertyCallbackArguments args(
@@ -5071,8 +5073,8 @@
   HandleScope scope(isolate);
   Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
   if (interceptor->deleter()->IsUndefined()) return heap->false_value();
-  v8::IndexedPropertyDeleter deleter =
-      v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter());
+  v8::IndexedPropertyDeleterCallback deleter =
+      v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
   Handle<JSObject> this_handle(this);
   LOG(isolate,
       ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
@@ -11577,8 +11579,8 @@
   Handle<JSObject> this_handle(this);
   Handle<Object> value_handle(value, isolate);
   if (!interceptor->setter()->IsUndefined()) {
-    v8::IndexedPropertySetter setter =
-        v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter());
+    v8::IndexedPropertySetterCallback setter =
+        v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
     LOG(isolate,
         ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
     PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
@@ -11611,7 +11613,8 @@
     Handle<ExecutableAccessorInfo> data(
         ExecutableAccessorInfo::cast(structure));
     Object* fun_obj = data->getter();
-    v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+    v8::AccessorGetterCallback call_fun =
+        v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
     if (call_fun == NULL) return isolate->heap()->undefined_value();
     HandleScope scope(isolate);
     Handle<JSObject> self(JSObject::cast(receiver));
@@ -11676,7 +11679,8 @@
     Handle<ExecutableAccessorInfo> data(
         ExecutableAccessorInfo::cast(structure));
     Object* call_obj = data->setter();
-    v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
+    v8::AccessorSetterCallback call_fun =
+        v8::ToCData<v8::AccessorSetterCallback>(call_obj);
     if (call_fun == NULL) return value;
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
     Handle<String> key(isolate->factory()->NumberToString(number));
@@ -12585,8 +12589,8 @@
   Handle<Object> this_handle(receiver, isolate);
   Handle<JSObject> holder_handle(this, isolate);
   if (!interceptor->getter()->IsUndefined()) {
-    v8::IndexedPropertyGetter getter =
-        v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
+    v8::IndexedPropertyGetterCallback getter =
+        v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
     LOG(isolate,
         ApiIndexedPropertyAccess("interceptor-indexed-get", this, index));
     PropertyCallbackArguments
@@ -12890,8 +12894,8 @@
   Handle<String> name_handle(String::cast(name));
 
   if (!interceptor->getter()->IsUndefined()) {
-    v8::NamedPropertyGetter getter =
-        v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
+    v8::NamedPropertyGetterCallback getter =
+        v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name));
     PropertyCallbackArguments
diff --git a/src/objects.h b/src/objects.h
index 411908c..988f1ab 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5776,7 +5776,6 @@
     set_bit_field3(EnumLengthBits::update(bit_field3(), length));
   }
 
-  inline bool CanTrackAllocationSite();
   inline bool owns_descriptors();
   inline void set_owns_descriptors(bool is_shared);
   inline bool is_observed();
@@ -7845,6 +7844,7 @@
   static inline AllocationSiteMode GetMode(
       ElementsKind boilerplate_elements_kind);
   static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
+  static inline bool CanTrack(InstanceType type);
 
   static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
   static const int kWeakNextOffset = kTransitionInfoOffset + kPointerSize;
@@ -9874,6 +9874,7 @@
   // requires access check.
   DECL_BOOLEAN_ACCESSORS(needs_access_check)
   DECL_BOOLEAN_ACCESSORS(read_only_prototype)
+  DECL_BOOLEAN_ACCESSORS(remove_prototype)
 
   static inline FunctionTemplateInfo* cast(Object* obj);
 
@@ -9909,6 +9910,7 @@
   static const int kUndetectableBit      = 1;
   static const int kNeedsAccessCheckBit  = 2;
   static const int kReadOnlyPrototypeBit = 3;
+  static const int kRemovePrototypeBit   = 4;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
 };
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
deleted file mode 100644
index dc7adb6..0000000
--- a/src/platform-nullos.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Platform specific code for NULLOS goes here
-
-// Minimal include to get access to abort, fprintf and friends for bootstrapping
-// messages.
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "v8.h"
-
-#include "platform.h"
-#include "vm-state-inl.h"
-
-
-namespace v8 {
-namespace internal {
-
-// Give V8 the opportunity to override the default ceil behaviour.
-double ceiling(double x) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Give V8 the opportunity to override the default fmod behavior.
-double modulo(double x, double y) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-double fast_sin(double x) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-double fast_cos(double x) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-double fast_tan(double x) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-double fast_log(double x) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Initialize OS class early in the V8 startup.
-void OS::SetUp() {
-  // Seed the random number generator.
-  UNIMPLEMENTED();
-}
-
-
-void OS::PostSetUp() {
-  UNIMPLEMENTED();
-}
-
-
-void OS::TearDown() {
-  UNIMPLEMENTED();
-}
-
-
-// Returns the accumulated user time for thread.
-int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
-  UNIMPLEMENTED();
-  *secs = 0;
-  *usecs = 0;
-  return 0;
-}
-
-
-// Returns current time as the number of milliseconds since
-// 00:00:00 UTC, January 1, 1970.
-double OS::TimeCurrentMillis() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Returns ticks in microsecond resolution.
-int64_t OS::Ticks() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Returns a string identifying the current timezone taking into
-// account daylight saving.
-const char* OS::LocalTimezone(double time) {
-  UNIMPLEMENTED();
-  return "<none>";
-}
-
-
-// Returns the daylight savings offset in milliseconds for the given time.
-double OS::DaylightSavingsOffset(double time) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-int OS::GetLastError() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Returns the local time offset in milliseconds east of UTC without
-// taking daylight savings time into account.
-double OS::LocalTimeOffset() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-// Print (debug) message to console.
-void OS::Print(const char* format, ...) {
-  UNIMPLEMENTED();
-}
-
-
-// Print (debug) message to console.
-void OS::VPrint(const char* format, va_list args) {
-  // Minimalistic implementation for bootstrapping.
-  vfprintf(stdout, format, args);
-}
-
-
-void OS::FPrint(FILE* out, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  VFPrint(out, format, args);
-  va_end(args);
-}
-
-
-void OS::VFPrint(FILE* out, const char* format, va_list args) {
-  vfprintf(out, format, args);
-}
-
-
-// Print error message to console.
-void OS::PrintError(const char* format, ...) {
-  // Minimalistic implementation for bootstrapping.
-  va_list args;
-  va_start(args, format);
-  VPrintError(format, args);
-  va_end(args);
-}
-
-
-// Print error message to console.
-void OS::VPrintError(const char* format, va_list args) {
-  // Minimalistic implementation for bootstrapping.
-  vfprintf(stderr, format, args);
-}
-
-
-int OS::SNPrintF(char* str, size_t size, const char* format, ...) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-int OS::VSNPrintF(char* str, size_t size, const char* format, va_list args) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-uint64_t OS::CpuFeaturesImpliedByPlatform() {
-  return 0;
-}
-
-
-double OS::nan_value() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-bool OS::ArmUsingHardFloat() {
-  UNIMPLEMENTED();
-}
-
-
-bool OS::IsOutsideAllocatedSpace(void* address) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-size_t OS::AllocateAlignment() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-void* OS::Allocate(const size_t requested,
-                   size_t* allocated,
-                   bool executable) {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void OS::Free(void* buf, const size_t length) {
-  // TODO(1240712): potential system call return value which is ignored here.
-  UNIMPLEMENTED();
-}
-
-
-void OS::Guard(void* address, const size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Sleep(int milliseconds) {
-  UNIMPLEMENTED();
-}
-
-
-int OS::NumberOfCores() {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-void OS::Abort() {
-  // Minimalistic implementation for bootstrapping.
-  abort();
-}
-
-
-void OS::DebugBreak() {
-  UNIMPLEMENTED();
-}
-
-
-void OS::DumpBacktrace() {
-  // Currently unsupported.
-}
-
-
-OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
-    void* initial) {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void OS::LogSharedLibraryAddresses() {
-  UNIMPLEMENTED();
-}
-
-
-void OS::SignalCodeMovingGC() {
-  UNIMPLEMENTED();
-}
-
-
-int OS::StackWalk(Vector<OS::StackFrame> frames) {
-  UNIMPLEMENTED();
-  return 0;
-}
-
-
-VirtualMemory::VirtualMemory() {
-  UNIMPLEMENTED();
-}
-
-
-VirtualMemory::VirtualMemory(size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-VirtualMemory::VirtualMemory(size_t size, void* address_hint) {
-  UNIMPLEMENTED();
-}
-
-
-VirtualMemory::~VirtualMemory() {
-  UNIMPLEMENTED();
-}
-
-
-bool VirtualMemory::IsReserved() {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-void VirtualMemory::Reset() {
-  UNIMPLEMENTED();
-}
-
-
-bool VirtualMemory::Commit(void* address, size_t size, bool executable) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool VirtualMemory::Uncommit(void* address, size_t size) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool VirtualMemory::Guard(void* address) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-void* VirtualMemory::ReserveRegion(size_t size) {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool VirtualMemory::UncommitRegion(void* base, size_t size) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool VirtualMemory::HasLazyCommits() {
-  // TODO(alph): implement for the platform.
-  return false;
-}
-
-
-class Thread::PlatformData : public Malloced {
- public:
-  PlatformData() {
-    UNIMPLEMENTED();
-  }
-
-  void* pd_data_;
-};
-
-
-Thread::Thread(const Options& options)
-    : data_(new PlatformData()),
-      stack_size_(options.stack_size),
-      start_semaphore_(NULL) {
-  set_name(options.name);
-  UNIMPLEMENTED();
-}
-
-
-Thread::Thread(const char* name)
-    : data_(new PlatformData()),
-      stack_size_(0) {
-  set_name(name);
-  UNIMPLEMENTED();
-}
-
-
-Thread::~Thread() {
-  delete data_;
-  UNIMPLEMENTED();
-}
-
-
-void Thread::set_name(const char* name) {
-  strncpy(name_, name, sizeof(name_));
-  name_[sizeof(name_) - 1] = '\0';
-}
-
-
-void Thread::Start() {
-  UNIMPLEMENTED();
-}
-
-
-void Thread::Join() {
-  UNIMPLEMENTED();
-}
-
-
-Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
-  UNIMPLEMENTED();
-  return static_cast<LocalStorageKey>(0);
-}
-
-
-void Thread::DeleteThreadLocalKey(LocalStorageKey key) {
-  UNIMPLEMENTED();
-}
-
-
-void* Thread::GetThreadLocal(LocalStorageKey key) {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
-  UNIMPLEMENTED();
-}
-
-
-void Thread::YieldCPU() {
-  UNIMPLEMENTED();
-}
-
-
-class NullMutex : public Mutex {
- public:
-  NullMutex() : data_(NULL) {
-    UNIMPLEMENTED();
-  }
-
-  virtual ~NullMutex() {
-    UNIMPLEMENTED();
-  }
-
-  virtual int Lock() {
-    UNIMPLEMENTED();
-    return 0;
-  }
-
-  virtual int Unlock() {
-    UNIMPLEMENTED();
-    return 0;
-  }
-
- private:
-  void* data_;
-};
-
-
-Mutex* OS::CreateMutex() {
-  UNIMPLEMENTED();
-  return new NullMutex();
-}
-
-
-class NullSemaphore : public Semaphore {
- public:
-  explicit NullSemaphore(int count) : data_(NULL) {
-    UNIMPLEMENTED();
-  }
-
-  virtual ~NullSemaphore() {
-    UNIMPLEMENTED();
-  }
-
-  virtual void Wait() {
-    UNIMPLEMENTED();
-  }
-
-  virtual void Signal() {
-    UNIMPLEMENTED();
-  }
- private:
-  void* data_;
-};
-
-
-Semaphore* OS::CreateSemaphore(int count) {
-  UNIMPLEMENTED();
-  return new NullSemaphore(count);
-}
-
-
-class ProfileSampler::PlatformData  : public Malloced {
- public:
-  PlatformData() {
-    UNIMPLEMENTED();
-  }
-};
-
-
-ProfileSampler::ProfileSampler(int interval) {
-  UNIMPLEMENTED();
-  // Shared setup follows.
-  data_ = new PlatformData();
-  interval_ = interval;
-  active_ = false;
-}
-
-
-ProfileSampler::~ProfileSampler() {
-  UNIMPLEMENTED();
-  // Shared tear down follows.
-  delete data_;
-}
-
-
-void ProfileSampler::Start() {
-  UNIMPLEMENTED();
-}
-
-
-void ProfileSampler::Stop() {
-  UNIMPLEMENTED();
-}
-
-
-} }  // namespace v8::internal
diff --git a/src/platform.h b/src/platform.h
index 384ae15..10a7e2c 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -44,6 +44,12 @@
 #ifndef V8_PLATFORM_H_
 #define V8_PLATFORM_H_
 
+#include <cstdarg>
+
+#include "lazy-instance.h"
+#include "utils.h"
+#include "v8globals.h"
+
 #ifdef __sun
 # ifndef signbit
 namespace std {
@@ -55,19 +61,12 @@
 // GCC specific stuff
 #ifdef __GNUC__
 
-// Needed for va_list on at least MinGW and Android.
-#include <stdarg.h>
-
 #define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
 
 #endif  // __GNUC__
 
-
-// Windows specific stuff.
-#ifdef WIN32
-
 // Microsoft Visual C++ specific stuff.
-#ifdef _MSC_VER
+#if V8_CC_MSVC
 
 #include "win32-headers.h"
 #include "win32-math.h"
@@ -76,7 +75,7 @@
 
 inline int lrint(double flt) {
   int intgr;
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
   __asm {
     fld flt
     fistp intgr
@@ -91,18 +90,12 @@
   return intgr;
 }
 
-#endif  // _MSC_VER
+#endif  // V8_CC_MSVC
 
-#ifndef __CYGWIN__
 // Random is missing on both Visual Studio and MinGW.
+#if V8_CC_MSVC || V8_CC_MINGW
 int random();
-#endif
-
-#endif  // WIN32
-
-#include "lazy-instance.h"
-#include "utils.h"
-#include "v8globals.h"
+#endif  // V8_CC_MSVC || V8_CC_MINGW
 
 namespace v8 {
 namespace internal {
diff --git a/src/preparser.h b/src/preparser.h
index faddecc..9358d6b 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -104,11 +104,6 @@
 };
 
 
-#ifdef WIN32
-#undef Yield
-#endif
-
-
 class PreParser {
  public:
   enum PreParseResult {
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 6791c88..5a984e5 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -73,7 +73,6 @@
 ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry)
     : tree_(tree),
       entry_(entry),
-      total_ticks_(0),
       self_ticks_(0),
       children_(CodeEntriesMatch),
       id_(tree->next_node_id()) {
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 86bd17b..b1dadc1 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -209,19 +209,9 @@
 }
 
 
-double ProfileNode::GetSelfMillis() const {
-  return tree_->TicksToMillis(self_ticks_);
-}
-
-
-double ProfileNode::GetTotalMillis() const {
-  return tree_->TicksToMillis(total_ticks_);
-}
-
-
 void ProfileNode::Print(int indent) {
-  OS::Print("%5u %5u %*c %s%s %d #%d",
-            total_ticks_, self_ticks_,
+  OS::Print("%5u %*c %s%s %d #%d",
+            self_ticks_,
             indent, ' ',
             entry_->name_prefix(),
             entry_->name(),
@@ -298,11 +288,6 @@
 };
 
 
-void ProfileTree::SetTickRatePerMs(double ticks_per_ms) {
-  ms_to_ticks_scale_ = ticks_per_ms > 0 ? 1.0 / ticks_per_ms : 1.0;
-}
-
-
 class Position {
  public:
   explicit Position(ProfileNode* node)
@@ -345,33 +330,6 @@
 }
 
 
-class CalculateTotalTicksCallback {
- public:
-  void BeforeTraversingChild(ProfileNode*, ProfileNode*) { }
-
-  void AfterAllChildrenTraversed(ProfileNode* node) {
-    node->IncreaseTotalTicks(node->self_ticks());
-  }
-
-  void AfterChildTraversed(ProfileNode* parent, ProfileNode* child) {
-    parent->IncreaseTotalTicks(child->total_ticks());
-  }
-};
-
-
-void ProfileTree::CalculateTotalTicks() {
-  CalculateTotalTicksCallback cb;
-  TraverseDepthFirst(&cb);
-}
-
-
-void ProfileTree::ShortPrint() {
-  OS::Print("root: %u %u %.2fms %.2fms\n",
-            root_->total_ticks(), root_->self_ticks(),
-            root_->GetTotalMillis(), root_->GetSelfMillis());
-}
-
-
 CpuProfile::CpuProfile(const char* title, unsigned uid, bool record_samples)
     : title_(title),
       uid_(uid),
@@ -389,19 +347,6 @@
 
 void CpuProfile::CalculateTotalTicksAndSamplingRate() {
   end_time_us_ = OS::Ticks();
-  top_down_.CalculateTotalTicks();
-
-  double duration_ms = (end_time_us_ - start_time_us_) / 1000.;
-  if (duration_ms < 1) duration_ms = 1;
-  unsigned ticks = top_down_.root()->total_ticks();
-  double rate = ticks / duration_ms;
-  top_down_.SetTickRatePerMs(rate);
-}
-
-
-void CpuProfile::ShortPrint() {
-  OS::Print("top down ");
-  top_down_.ShortPrint();
 }
 
 
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 99aeb1f..a282af2 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -131,14 +131,10 @@
   ProfileNode* FindOrAddChild(CodeEntry* entry);
   INLINE(void IncrementSelfTicks()) { ++self_ticks_; }
   INLINE(void IncreaseSelfTicks(unsigned amount)) { self_ticks_ += amount; }
-  INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; }
 
   INLINE(CodeEntry* entry() const) { return entry_; }
   INLINE(unsigned self_ticks() const) { return self_ticks_; }
-  INLINE(unsigned total_ticks() const) { return total_ticks_; }
   INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }
-  double GetSelfMillis() const;
-  double GetTotalMillis() const;
   unsigned id() const { return id_; }
 
   void Print(int indent);
@@ -155,7 +151,6 @@
 
   ProfileTree* tree_;
   CodeEntry* entry_;
-  unsigned total_ticks_;
   unsigned self_ticks_;
   // Mapping from CodeEntry* to ProfileNode*
   HashMap children_;
@@ -173,17 +168,9 @@
 
   ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
   void AddPathFromStart(const Vector<CodeEntry*>& path);
-  void CalculateTotalTicks();
-
-  double TicksToMillis(unsigned ticks) const {
-    return ticks * ms_to_ticks_scale_;
-  }
   ProfileNode* root() const { return root_; }
-  void SetTickRatePerMs(double ticks_per_ms);
-
   unsigned next_node_id() { return next_node_id_++; }
 
-  void ShortPrint();
   void Print() {
     root_->Print(0);
   }
@@ -195,7 +182,6 @@
   CodeEntry root_entry_;
   unsigned next_node_id_;
   ProfileNode* root_;
-  double ms_to_ticks_scale_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileTree);
 };
@@ -221,7 +207,6 @@
 
   void UpdateTicksScale();
 
-  void ShortPrint();
   void Print();
 
  private:
diff --git a/src/property-details.h b/src/property-details.h
index 6b62ddb..7f44b79 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -148,7 +148,7 @@
   bool IsHeapObject() const { return kind_ == kHeapObject; }
   bool IsExternal() const { return kind_ == kExternal; }
   bool IsSpecialization() const {
-    return kind_ == kInteger32 || kind_ == kDouble;
+    return kind_ == kInteger32 || kind_ == kDouble || kind_ == kSmi;
   }
   const char* Mnemonic() const;
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 65b1d35..71d792a 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -4722,6 +4722,19 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
+  HandleScope shs(isolate);
+  ASSERT(args.length() == 1);
+
+  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
+  if (Smi::IsValid(number)) {
+    return isolate->heap()->true_value();
+  } else {
+    return isolate->heap()->false_value();
+  }
+}
+
+
 // Returns a single character string where first character equals
 // string->Get(index).
 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
@@ -7951,6 +7964,20 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosureFromStubFailure) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
+  Handle<Context> context(isolate->context());
+  PretenureFlag pretenure_flag = NOT_TENURED;
+  Handle<JSFunction> result =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
+                                                            context,
+                                                            pretenure_flag);
+  return *result;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
diff --git a/src/runtime.h b/src/runtime.h
index e0e0b48..9054fc7 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -221,7 +221,8 @@
   F(NumberToRadixString, 2, 1) \
   F(NumberToFixed, 2, 1) \
   F(NumberToExponential, 2, 1) \
-  F(NumberToPrecision, 2, 1)
+  F(NumberToPrecision, 2, 1) \
+  F(IsValidSmi, 1, 1)
 
 
 #define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
@@ -395,6 +396,7 @@
   \
   /* Statements */ \
   F(NewClosure, 3, 1) \
+  F(NewClosureFromStubFailure, 1, 1) \
   F(NewObject, 1, 1) \
   F(NewObjectFromBound, 1, 1) \
   F(FinalizeInstanceSize, 1, 1) \
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 45963a3..19cfd5a 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1176,7 +1176,8 @@
   JSObject* recv = JSObject::cast(args[0]);
   ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[1]);
   Address setter_address = v8::ToCData<Address>(callback->setter());
-  v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
+  v8::AccessorSetterCallback fun =
+      FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
   ASSERT(fun != NULL);
   ASSERT(callback->IsCompatibleReceiver(recv));
   Handle<Name> name = args.at<Name>(2);
@@ -1221,8 +1222,8 @@
   Handle<String> name = Handle<String>::cast(name_handle);
 
   Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
-  v8::NamedPropertyGetter getter =
-      FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
+  v8::NamedPropertyGetterCallback getter =
+      FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
   ASSERT(getter != NULL);
 
   Handle<JSObject> receiver =
@@ -1291,8 +1292,8 @@
   Handle<String> name = Handle<String>::cast(name_handle);
 
   Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
-  v8::NamedPropertyGetter getter =
-      FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
+  v8::NamedPropertyGetterCallback getter =
+      FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
   ASSERT(getter != NULL);
 
   PropertyCallbackArguments callback_args(isolate,
diff --git a/src/v8dll-main.cc b/src/v8dll-main.cc
index 49d8689..7f6c9f9 100644
--- a/src/v8dll-main.cc
+++ b/src/v8dll-main.cc
@@ -30,8 +30,8 @@
 #undef USING_V8_SHARED
 #include "../include/v8.h"
 
-#ifdef WIN32
-#include <windows.h>  // NOLINT
+#if V8_OS_WIN
+#include "win32-headers.h"
 
 extern "C" {
 BOOL WINAPI DllMain(HANDLE hinstDLL,
@@ -41,4 +41,4 @@
   return TRUE;
 }
 }
-#endif
+#endif  // V8_OS_WIN
diff --git a/src/version.cc b/src/version.cc
index 72633e7..d83f18e 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      4
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      5
+#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/win32-headers.h b/src/win32-headers.h
index 2b5d7d7..c83937c 100644
--- a/src/win32-headers.h
+++ b/src/win32-headers.h
@@ -96,3 +96,4 @@
 #undef GetObject
 #undef CreateMutex
 #undef CreateSemaphore
+#undef Yield
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index ca8216b..6c83dad 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -708,7 +708,7 @@
   }
 
   // Get the full codegen state from the stack and untag it.
-  __ SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize));
+  __ SmiToInteger32(r10, Operand(rsp, kPCOnStackSize));
 
   // Switch on the state.
   Label not_no_registers, not_tos_rax;
@@ -717,7 +717,7 @@
   __ ret(1 * kPointerSize);  // Remove state.
 
   __ bind(&not_no_registers);
-  __ movq(rax, Operand(rsp, 2 * kPointerSize));
+  __ movq(rax, Operand(rsp, kPCOnStackSize + kPointerSize));
   __ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG));
   __ j(not_equal, &not_tos_rax, Label::kNear);
   __ ret(2 * kPointerSize);  // Remove state, rax.
@@ -782,8 +782,8 @@
   // 2. Get the function to call (passed as receiver) from the stack, check
   //    if it is a function.
   Label slow, non_function;
-  // The function to call is at position n+1 on the stack.
-  __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
+  StackArgumentsAccessor args(rsp, rax);
+  __ movq(rdi, args.GetReceiverOperand());
   __ JumpIfSmi(rdi, &non_function);
   __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
   __ j(not_equal, &slow);
@@ -808,7 +808,7 @@
     __ j(not_zero, &shift_arguments);
 
     // Compute the receiver in non-strict mode.
-    __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
+    __ movq(rbx, args.GetArgumentOperand(1));
     __ JumpIfSmi(rbx, &convert_to_object, Label::kNear);
 
     __ CompareRoot(rbx, Heap::kNullValueRootIndex);
@@ -837,7 +837,7 @@
     }
 
     // Restore the function to rdi.
-    __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
+    __ movq(rdi, args.GetReceiverOperand());
     __ jmp(&patch_receiver, Label::kNear);
 
     // Use the global receiver object from the called function as the
@@ -851,7 +851,7 @@
     __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
 
     __ bind(&patch_receiver);
-    __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx);
+    __ movq(args.GetArgumentOperand(1), rbx);
 
     __ jmp(&shift_arguments);
   }
@@ -868,7 +868,7 @@
   //     CALL_NON_FUNCTION builtin expects the non-function callee as
   //     receiver, so overwrite the first argument which will ultimately
   //     become the receiver.
-  __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
+  __ movq(args.GetArgumentOperand(1), rdi);
 
   // 4. Shift arguments and return address one slot down on the stack
   //    (overwriting the original receiver).  Adjust argument count to make
@@ -1178,10 +1178,11 @@
 
   // Load the first argument into rax and get rid of the rest
   // (including the receiver).
+  StackArgumentsAccessor args(rsp, rax);
   Label no_arguments;
   __ testq(rax, rax);
   __ j(zero, &no_arguments);
-  __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
+  __ movq(rbx, args.GetArgumentOperand(1));
   __ PopReturnAddressTo(rcx);
   __ lea(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
   __ PushReturnAddressFrom(rcx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 41507d1..9eed917 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -39,6 +39,17 @@
 namespace internal {
 
 
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { rbx };
+  descriptor->register_param_count_ = 1;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ =
+      Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
 void ToNumberStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -295,140 +306,6 @@
 }
 
 
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
-  // Create a new closure from the given function info in new
-  // space. Set the context to the current context in rsi.
-  Counters* counters = masm->isolate()->counters();
-
-  Label gc;
-  __ Allocate(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
-
-  __ IncrementCounter(counters->fast_new_closure_total(), 1);
-
-  // Get the function info from the stack.
-  __ movq(rdx, Operand(rsp, 1 * kPointerSize));
-
-  int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
-  // Compute the function map in the current native context and set that
-  // as the map of the allocated object.
-  __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
-  __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
-  __ movq(rbx, Operand(rcx, Context::SlotOffset(map_index)));
-  __ movq(FieldOperand(rax, JSObject::kMapOffset), rbx);
-
-  // Initialize the rest of the function. We don't have to update the
-  // write barrier because the allocated object is in new space.
-  __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
-  __ LoadRoot(r8, Heap::kTheHoleValueRootIndex);
-  __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
-  __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
-  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx);
-  __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), r8);
-  __ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx);
-  __ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi);
-  __ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx);
-
-  // Initialize the code pointer in the function to be the one
-  // found in the shared function info object.
-  // But first check if there is an optimized version for our context.
-  Label check_optimized;
-  Label install_unoptimized;
-  if (FLAG_cache_optimized_code) {
-    __ movq(rbx,
-            FieldOperand(rdx, SharedFunctionInfo::kOptimizedCodeMapOffset));
-    __ testq(rbx, rbx);
-    __ j(not_zero, &check_optimized, Label::kNear);
-  }
-  __ bind(&install_unoptimized);
-  __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset),
-          rdi);  // Initialize with undefined.
-  __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
-  __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
-  __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
-
-  // Return and remove the on-stack parameter.
-  __ ret(1 * kPointerSize);
-
-  __ bind(&check_optimized);
-
-  __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
-
-  // rcx holds native context, rbx points to fixed array of 3-element entries
-  // (native context, optimized code, literals).
-  // The optimized code map must never be empty, so check the first elements.
-  Label install_optimized;
-  // Speculatively move code object into edx.
-  __ movq(rdx, FieldOperand(rbx, SharedFunctionInfo::kFirstCodeSlot));
-  __ cmpq(rcx, FieldOperand(rbx, SharedFunctionInfo::kFirstContextSlot));
-  __ j(equal, &install_optimized);
-
-  // Iterate through the rest of map backwards. rdx holds an index.
-  Label loop;
-  Label restore;
-  __ movq(rdx, FieldOperand(rbx, FixedArray::kLengthOffset));
-  __ SmiToInteger32(rdx, rdx);
-  __ bind(&loop);
-  // Do not double check first entry.
-  __ cmpq(rdx, Immediate(SharedFunctionInfo::kSecondEntryIndex));
-  __ j(equal, &restore);
-  __ subq(rdx, Immediate(SharedFunctionInfo::kEntryLength));
-  __ cmpq(rcx, FieldOperand(rbx,
-                            rdx,
-                            times_pointer_size,
-                            FixedArray::kHeaderSize));
-  __ j(not_equal, &loop, Label::kNear);
-  // Hit: fetch the optimized code.
-  __ movq(rdx, FieldOperand(rbx,
-                            rdx,
-                            times_pointer_size,
-                            FixedArray::kHeaderSize + 1 * kPointerSize));
-
-  __ bind(&install_optimized);
-  __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
-
-  // TODO(fschneider): Idea: store proper code pointers in the map and either
-  // unmangle them on marking or do nothing as the whole map is discarded on
-  // major GC anyway.
-  __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
-  __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
-
-  // Now link a function into a list of optimized functions.
-  __ movq(rdx, ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST));
-
-  __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset), rdx);
-  // No need for write barrier as JSFunction (rax) is in the new space.
-
-  __ movq(ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST), rax);
-  // Store JSFunction (rax) into rdx before issuing write barrier as
-  // it clobbers all the registers passed.
-  __ movq(rdx, rax);
-  __ RecordWriteContextSlot(
-      rcx,
-      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
-      rdx,
-      rbx,
-      kDontSaveFPRegs);
-
-  // Return and remove the on-stack parameter.
-  __ ret(1 * kPointerSize);
-
-  __ bind(&restore);
-  __ movq(rdx, Operand(rsp, 1 * kPointerSize));
-  __ jmp(&install_unoptimized);
-
-  // Create a new closure through the slower runtime call.
-  __ bind(&gc);
-  __ PopReturnAddressTo(rcx);
-  __ pop(rdx);
-  __ push(rsi);
-  __ push(rdx);
-  __ PushRoot(Heap::kFalseValueRootIndex);
-  __ PushReturnAddressFrom(rcx);
-  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
 void FastNewContextStub::Generate(MacroAssembler* masm) {
   // Try to allocate the context in new space.
   Label gc;
@@ -437,7 +314,8 @@
               rax, rbx, rcx, &gc, TAG_OBJECT);
 
   // Get the function from the stack.
-  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rcx, args.GetArgumentOperand(0));
 
   // Set up the object header.
   __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
@@ -483,10 +361,10 @@
               rax, rbx, rcx, &gc, TAG_OBJECT);
 
   // Get the function from the stack.
-  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
-
+  StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rcx, args.GetArgumentOperand(1));
   // Get the serialized scope info from the stack.
-  __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+  __ movq(rbx, args.GetArgumentOperand(0));
 
   // Set up the object header.
   __ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex);
@@ -1259,7 +1137,8 @@
   if (tagged) {
     Label input_not_smi, loaded;
     // Test that rax is a number.
-    __ movq(rax, Operand(rsp, kPointerSize));
+    StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+    __ movq(rax, args.GetArgumentOperand(0));
     __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
     // Input is a smi. Untag and load it onto the FPU stack.
     // Then load the bits of the double into rbx.
@@ -1734,8 +1613,9 @@
     // The exponent and base are supplied as arguments on the stack.
     // This can only happen if the stub is called from non-optimized code.
     // Load input parameters from stack.
-    __ movq(base, Operand(rsp, 2 * kPointerSize));
-    __ movq(exponent, Operand(rsp, 1 * kPointerSize));
+    StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+    __ movq(base, args.GetArgumentOperand(0));
+    __ movq(exponent, args.GetArgumentOperand(1));
     __ JumpIfSmi(base, &base_is_smi, Label::kNear);
     __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
                    Heap::kHeapNumberMapRootIndex);
@@ -2168,7 +2048,8 @@
 
   Factory* factory = masm->isolate()->factory();
 
-  __ SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize));
+  StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ SmiToInteger64(rbx, args.GetArgumentOperand(2));
   // rbx = parameter count (untagged)
 
   // Check if the calling frame is an arguments adaptor frame.
@@ -2190,7 +2071,7 @@
                             ArgumentsAdaptorFrameConstants::kLengthOffset));
   __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
                       StandardFrameConstants::kCallerSPOffset));
-  __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+  __ movq(args.GetArgumentOperand(1), rdx);
 
   // rbx = parameter count (untagged)
   // rcx = argument count (untagged)
@@ -2251,7 +2132,7 @@
 
   // Set up the callee in-object property.
   STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
-  __ movq(rdx, Operand(rsp, 3 * kPointerSize));
+  __ movq(rdx, args.GetArgumentOperand(0));
   __ movq(FieldOperand(rax, JSObject::kHeaderSize +
                        Heap::kArgumentsCalleeIndex * kPointerSize),
           rdx);
@@ -2302,7 +2183,7 @@
   // Load tagged parameter count into r9.
   __ Integer32ToSmi(r9, rbx);
   __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
-  __ addq(r8, Operand(rsp, 1 * kPointerSize));
+  __ addq(r8, args.GetArgumentOperand(2));
   __ subq(r8, r9);
   __ Move(r11, factory->the_hole_value());
   __ movq(rdx, rdi);
@@ -2341,7 +2222,7 @@
 
   Label arguments_loop, arguments_test;
   __ movq(r8, rbx);
-  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+  __ movq(rdx, args.GetArgumentOperand(1));
   // Untag rcx for the loop below.
   __ SmiToInteger64(rcx, rcx);
   __ lea(kScratchRegister, Operand(r8, times_pointer_size, 0));
@@ -2368,7 +2249,7 @@
   // rcx = argument count (untagged)
   __ bind(&runtime);
   __ Integer32ToSmi(rcx, rcx);
-  __ movq(Operand(rsp, 1 * kPointerSize), rcx);  // Patch argument count.
+  __ movq(args.GetArgumentOperand(2), rcx);  // Patch argument count.
   __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
 }
 
@@ -2387,12 +2268,13 @@
   __ j(not_equal, &runtime);
 
   // Patch the arguments.length and the parameters pointer.
+  StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
   __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
-  __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+  __ movq(args.GetArgumentOperand(2), rcx);
   __ SmiToInteger64(rcx, rcx);
   __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
               StandardFrameConstants::kCallerSPOffset));
-  __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+  __ movq(args.GetArgumentOperand(1), rdx);
 
   __ bind(&runtime);
   __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
@@ -2413,18 +2295,19 @@
   __ j(equal, &adaptor_frame);
 
   // Get the length from the frame.
-  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rcx, args.GetArgumentOperand(2));
   __ SmiToInteger64(rcx, rcx);
   __ jmp(&try_allocate);
 
   // Patch the arguments.length and the parameters pointer.
   __ bind(&adaptor_frame);
   __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
-  __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+  __ movq(args.GetArgumentOperand(2), rcx);
   __ SmiToInteger64(rcx, rcx);
   __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
                       StandardFrameConstants::kCallerSPOffset));
-  __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+  __ movq(args.GetArgumentOperand(1), rdx);
 
   // Try the new space allocation. Start out with computing the size of
   // the arguments object and the elements array.
@@ -2454,7 +2337,7 @@
 
   // Get the length (smi tagged) and set that as an in-object property too.
   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
-  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  __ movq(rcx, args.GetArgumentOperand(2));
   __ movq(FieldOperand(rax, JSObject::kHeaderSize +
                        Heap::kArgumentsLengthIndex * kPointerSize),
           rcx);
@@ -2465,7 +2348,7 @@
   __ j(zero, &done);
 
   // Get the parameters pointer from the stack.
-  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+  __ movq(rdx, args.GetArgumentOperand(1));
 
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
@@ -2948,7 +2831,8 @@
   const int kMaxInlineLength = 100;
   Label slowcase;
   Label done;
-  __ movq(r8, Operand(rsp, kPointerSize * 3));
+  StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(r8, args.GetArgumentOperand(0));
   __ JumpIfNotSmi(r8, &slowcase);
   __ SmiToInteger32(rbx, r8);
   __ cmpl(rbx, Immediate(kMaxInlineLength));
@@ -2986,11 +2870,11 @@
   __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
 
   // Set input, index and length fields from arguments.
-  __ movq(r8, Operand(rsp, kPointerSize * 1));
+  __ movq(r8, args.GetArgumentOperand(2));
   __ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8);
-  __ movq(r8, Operand(rsp, kPointerSize * 2));
+  __ movq(r8, args.GetArgumentOperand(1));
   __ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8);
-  __ movq(r8, Operand(rsp, kPointerSize * 3));
+  __ movq(r8, args.GetArgumentOperand(0));
   __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
 
   // Fill out the elements FixedArray.
@@ -3121,7 +3005,8 @@
 void NumberToStringStub::Generate(MacroAssembler* masm) {
   Label runtime;
 
-  __ movq(rbx, Operand(rsp, kPointerSize));
+  StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rbx, args.GetArgumentOperand(0));
 
   // Generate code to lookup number in the number string cache.
   GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime);
@@ -3506,6 +3391,7 @@
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
+    __ Integer32ToSmi(rax, rax);
     __ push(rax);
     __ push(rdi);
     __ push(rbx);
@@ -3516,6 +3402,7 @@
     __ pop(rbx);
     __ pop(rdi);
     __ pop(rax);
+    __ SmiToInteger32(rax, rax);
   }
   __ jmp(&done);
 
@@ -3532,6 +3419,7 @@
   // rdi : the function to call
   Isolate* isolate = masm->isolate();
   Label slow, non_function;
+  StackArgumentsAccessor args(rsp, argc_);
 
   // The receiver might implicitly be the global object. This is
   // indicated by passing the hole as the receiver to the call
@@ -3539,15 +3427,14 @@
   if (ReceiverMightBeImplicit()) {
     Label call;
     // Get the receiver from the stack.
-    // +1 ~ return address
-    __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
+    __ movq(rax, args.GetReceiverOperand());
     // Call as function is indicated with the hole.
     __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
     __ j(not_equal, &call, Label::kNear);
     // Patch the receiver on the stack with the global receiver object.
     __ movq(rcx, GlobalObjectOperand());
     __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
+    __ movq(args.GetReceiverOperand(), rcx);
     __ bind(&call);
   }
 
@@ -3609,7 +3496,7 @@
   // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
   // of the original receiver from the call site).
   __ bind(&non_function);
-  __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
+  __ movq(args.GetReceiverOperand(), rdi);
   __ Set(rax, argc_);
   __ Set(rbx, 0);
   __ SetCallKind(rcx, CALL_AS_METHOD);
@@ -4144,12 +4031,13 @@
   static const unsigned int kWordBeforeResultValue = 0x458B4909;
   // Only the inline check flag is supported on X64.
   ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
-  int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0;
+  int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
 
   // Get the object - go slow case if it's a smi.
   Label slow;
-
-  __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
+  StackArgumentsAccessor args(rsp, 2 + extra_argument_offset,
+                              ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rax, args.GetArgumentOperand(0));
   __ JumpIfSmi(rax, &slow);
 
   // Check that the left hand is a JS object. Leave its map in rax.
@@ -4159,7 +4047,7 @@
   __ j(above, &slow);
 
   // Get the prototype of the function.
-  __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
+  __ movq(rdx, args.GetArgumentOperand(1));
   // rdx is function, rax is map.
 
   // If there is a call site cache don't look in the global cache, but do the
@@ -4194,8 +4082,8 @@
     __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
   } else {
     // Get return address and delta to inlined map check.
-    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
-    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+    __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+    __ subq(kScratchRegister, args.GetArgumentOperand(2));
     if (FLAG_debug_code) {
       __ movl(rdi, Immediate(kWordBeforeMapCheckValue));
       __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
@@ -4235,8 +4123,8 @@
     // Assert it is a 1-byte signed value.
     ASSERT(true_offset >= 0 && true_offset < 0x100);
     __ movl(rax, Immediate(true_offset));
-    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
-    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+    __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+    __ subq(kScratchRegister, args.GetArgumentOperand(2));
     __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
     if (FLAG_debug_code) {
       __ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4245,7 +4133,7 @@
     }
     __ Set(rax, 0);
   }
-  __ ret(2 * kPointerSize + extra_stack_space);
+  __ ret((2 + extra_argument_offset) * kPointerSize);
 
   __ bind(&is_not_instance);
   if (!HasCallSiteInlineCheck()) {
@@ -4258,8 +4146,8 @@
     // Assert it is a 1-byte signed value.
     ASSERT(false_offset >= 0 && false_offset < 0x100);
     __ movl(rax, Immediate(false_offset));
-    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
-    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+    __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+    __ subq(kScratchRegister, args.GetArgumentOperand(2));
     __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
     if (FLAG_debug_code) {
       __ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4267,7 +4155,7 @@
       __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
     }
   }
-  __ ret(2 * kPointerSize + extra_stack_space);
+  __ ret((2 + extra_argument_offset) * kPointerSize);
 
   // Slow-case: Go through the JavaScript implementation.
   __ bind(&slow);
@@ -4425,8 +4313,9 @@
   Builtins::JavaScript builtin_id = Builtins::ADD;
 
   // Load the two arguments.
-  __ movq(rax, Operand(rsp, 2 * kPointerSize));  // First argument (left).
-  __ movq(rdx, Operand(rsp, 1 * kPointerSize));  // Second argument (right).
+  StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rax, args.GetArgumentOperand(0));  // First argument (left).
+  __ movq(rdx, args.GetArgumentOperand(1));  // Second argument (right).
 
   // Make sure that both arguments are strings if not known in advance.
   // Otherwise, at least one of the arguments is definitely a string,
@@ -5433,8 +5322,9 @@
   //  rsp[8]  : right string
   //  rsp[16] : left string
 
-  __ movq(rdx, Operand(rsp, 2 * kPointerSize));  // left
-  __ movq(rax, Operand(rsp, 1 * kPointerSize));  // right
+  StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rdx, args.GetArgumentOperand(0));  // left
+  __ movq(rax, args.GetArgumentOperand(1));  // right
 
   // Check for identity.
   Label not_same;
@@ -5947,9 +5837,11 @@
   // undefined value), it guarantees the hash table doesn't contain the
   // property. It's true even if some slots represent deleted properties
   // (their names are the null value).
+  StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER,
+                              kPointerSize);
   for (int i = kInlinedProbes; i < kTotalProbes; i++) {
     // Compute the masked index: (hash + i + i * i) & mask.
-    __ movq(scratch, Operand(rsp, 2 * kPointerSize));
+    __ movq(scratch, args.GetArgumentOperand(1));
     if (i > 0) {
       __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
     }
@@ -5969,7 +5861,7 @@
     __ j(equal, &not_in_dictionary);
 
     // Stop if found the property.
-    __ cmpq(scratch, Operand(rsp, 3 * kPointerSize));
+    __ cmpq(scratch, args.GetArgumentOperand(0));
     __ j(equal, &in_dictionary);
 
     if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
@@ -6321,8 +6213,9 @@
   Label fast_elements;
 
   // Get array literal index, array literal and its map.
-  __ movq(rdx, Operand(rsp, 1 * kPointerSize));
-  __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+  StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rdx, args.GetArgumentOperand(1));
+  __ movq(rbx, args.GetArgumentOperand(0));
   __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
 
   __ CheckFastElements(rdi, &double_elements);
@@ -6489,7 +6382,8 @@
   __ j(not_zero, &normal_sequence);
 
   // look at the first argument
-  __ movq(rcx, Operand(rsp, kPointerSize));
+  StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  __ movq(rcx, args.GetArgumentOperand(0));
   __ testq(rcx, rcx);
   __ j(zero, &normal_sequence);
 
@@ -6668,7 +6562,8 @@
   if (IsFastPackedElementsKind(kind)) {
     // We might need to create a holey array
     // look at the first argument
-    __ movq(rcx, Operand(rsp, kPointerSize));
+    StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+    __ movq(rcx, args.GetArgumentOperand(0));
     __ testq(rcx, rcx);
     __ j(zero, &normal_sequence);
 
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index a39f14b..24773c2 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -744,6 +744,28 @@
 }
 
 
+Operand StackArgumentsAccessor::GetArgumentOperand(int index) {
+  ASSERT(index >= 0);
+  ASSERT(base_reg_.is(rsp) || base_reg_.is(rbp));
+  int receiver = (receiver_mode_ == ARGUMENTS_CONTAIN_RECEIVER) ? 1 : 0;
+  int displacement_to_last_argument = base_reg_.is(rsp) ?
+      kPCOnStackSize : kFPOnStackSize + kPCOnStackSize;
+  displacement_to_last_argument += extra_displacement_to_last_argument_;
+  if (argument_count_reg_.is(no_reg)) {
+    // argument[0] is at base_reg_ + displacement_to_last_argument +
+    // (argument_count_immediate_ + receiver - 1) * kPointerSize.
+    ASSERT(argument_count_immediate_ + receiver > 0);
+    return Operand(base_reg_, displacement_to_last_argument +
+        (argument_count_immediate_ + receiver - 1 - index) * kPointerSize);
+  } else {
+    // argument[0] is at base_reg_ + displacement_to_last_argument +
+    // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize.
+    return Operand(base_reg_, argument_count_reg_, times_pointer_size,
+        displacement_to_last_argument + (receiver - 1 - index) * kPointerSize);
+  }
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 5747e0b..9b8454a 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -103,6 +103,73 @@
   DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
 };
 
+
+enum StackArgumentsAccessorReceiverMode {
+  ARGUMENTS_CONTAIN_RECEIVER,
+  ARGUMENTS_DONT_CONTAIN_RECEIVER
+};
+
+
+class StackArgumentsAccessor BASE_EMBEDDED {
+ public:
+  StackArgumentsAccessor(
+      Register base_reg,
+      int argument_count_immediate,
+      StackArgumentsAccessorReceiverMode receiver_mode =
+          ARGUMENTS_CONTAIN_RECEIVER,
+      int extra_displacement_to_last_argument = 0)
+      : base_reg_(base_reg),
+        argument_count_reg_(no_reg),
+        argument_count_immediate_(argument_count_immediate),
+        receiver_mode_(receiver_mode),
+        extra_displacement_to_last_argument_(
+            extra_displacement_to_last_argument) { }
+
+  StackArgumentsAccessor(
+      Register base_reg,
+      Register argument_count_reg,
+      StackArgumentsAccessorReceiverMode receiver_mode =
+          ARGUMENTS_CONTAIN_RECEIVER,
+      int extra_displacement_to_last_argument = 0)
+      : base_reg_(base_reg),
+        argument_count_reg_(argument_count_reg),
+        argument_count_immediate_(0),
+        receiver_mode_(receiver_mode),
+        extra_displacement_to_last_argument_(
+            extra_displacement_to_last_argument) { }
+
+  StackArgumentsAccessor(
+      Register base_reg,
+      const ParameterCount& parameter_count,
+      StackArgumentsAccessorReceiverMode receiver_mode =
+          ARGUMENTS_CONTAIN_RECEIVER,
+      int extra_displacement_to_last_argument = 0)
+      : base_reg_(base_reg),
+        argument_count_reg_(parameter_count.is_reg() ?
+                            parameter_count.reg() : no_reg),
+        argument_count_immediate_(parameter_count.is_immediate() ?
+                                  parameter_count.immediate() : 0),
+        receiver_mode_(receiver_mode),
+        extra_displacement_to_last_argument_(
+            extra_displacement_to_last_argument) { }
+
+  Operand GetArgumentOperand(int index);
+  Operand GetReceiverOperand() {
+    ASSERT(receiver_mode_ == ARGUMENTS_CONTAIN_RECEIVER);
+    return GetArgumentOperand(0);;
+  }
+
+ private:
+  const Register base_reg_;
+  const Register argument_count_reg_;
+  const int argument_count_immediate_;
+  const StackArgumentsAccessorReceiverMode receiver_mode_;
+  const int extra_displacement_to_last_argument_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StackArgumentsAccessor);
+};
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_X64_CODEGEN_X64_H_
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index e6bc929..c8e1c96 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -123,14 +123,8 @@
       if ((object_regs & (1 << r)) != 0) {
         __ push(reg);
       }
-      // Store the 64-bit value as two smis.
       if ((non_object_regs & (1 << r)) != 0) {
-        __ movq(kScratchRegister, reg);
-        __ Integer32ToSmi(reg, reg);
-        __ push(reg);
-        __ sar(kScratchRegister, Immediate(32));
-        __ Integer32ToSmi(kScratchRegister, kScratchRegister);
-        __ push(kScratchRegister);
+        __ PushInt64AsTwoSmis(reg);
       }
     }
 
@@ -155,12 +149,7 @@
       }
       // Reconstruct the 64-bit value from two smis.
       if ((non_object_regs & (1 << r)) != 0) {
-        __ pop(kScratchRegister);
-        __ SmiToInteger32(kScratchRegister, kScratchRegister);
-        __ shl(kScratchRegister, Immediate(32));
-        __ pop(reg);
-        __ SmiToInteger32(reg, reg);
-        __ or_(reg, kScratchRegister);
+        __ PopInt64AsTwoSmis(reg);
       }
     }
 
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 9f2074c..04005ac 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1292,7 +1292,7 @@
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
     FastNewClosureStub stub(info->language_mode(), info->is_generator());
-    __ Push(info);
+    __ Move(rbx, info);
     __ CallStub(&stub);
   } else {
     __ push(rsi);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 4837b9a..84a47d6 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -904,8 +904,8 @@
   // -----------------------------------
   Label miss;
 
-  // Get the receiver of the function from the stack.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
 
@@ -940,8 +940,8 @@
     __ IncrementCounter(counters->keyed_call_miss(), 1);
   }
 
-  // Get the receiver of the function from the stack; 1 ~ return address.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Enter an internal frame.
   {
@@ -965,7 +965,7 @@
   // This can happen only for regular CallIC but not KeyedCallIC.
   if (id == IC::kCallIC_Miss) {
     Label invoke, global;
-    __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));  // receiver
+    __ movq(rdx, args.GetReceiverOperand());
     __ JumpIfSmi(rdx, &invoke);
     __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
     __ j(equal, &global);
@@ -975,7 +975,7 @@
     // Patch the receiver on the stack.
     __ bind(&global);
     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+    __ movq(args.GetReceiverOperand(), rdx);
     __ bind(&invoke);
   }
 
@@ -1005,8 +1005,8 @@
   // rsp[(argc + 1) * 8] : argument 0 = receiver
   // -----------------------------------
 
-  // Get the receiver of the function from the stack; 1 ~ return address.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
   GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state);
   GenerateMiss(masm, argc, extra_ic_state);
 }
@@ -1023,8 +1023,8 @@
   // rsp[(argc + 1) * 8] : argument 0 = receiver
   // -----------------------------------
 
-  // Get the receiver of the function from the stack; 1 ~ return address.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   Label do_call, slow_call, slow_load;
   Label check_number_dictionary, check_name, lookup_monomorphic_cache;
@@ -1302,7 +1302,8 @@
   // rsp[(argc + 1) * 8] : argument 0 = receiver
   // -----------------------------------
   Label slow, notin;
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
   Operand mapped_location = GenerateMappedArgumentsLookup(
       masm, rdx, rcx, rbx, rax, r8, &notin, &slow);
   __ movq(rdi, mapped_location);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 85f0255..094d239 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1299,7 +1299,11 @@
   LOperand* right = instr->right();
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    __ movl(kScratchRegister, left);
+    if (instr->hydrogen_value()->representation().IsSmi()) {
+      __ movq(kScratchRegister, left);
+    } else {
+      __ movl(kScratchRegister, left);
+    }
   }
 
   bool can_overflow =
@@ -1347,14 +1351,14 @@
     }
   } else if (right->IsStackSlot()) {
     if (instr->hydrogen_value()->representation().IsSmi()) {
-      __ SmiToInteger32(left, left);
+      __ SmiToInteger64(left, left);
       __ imul(left, ToOperand(right));
     } else {
       __ imull(left, ToOperand(right));
     }
   } else {
     if (instr->hydrogen_value()->representation().IsSmi()) {
-      __ SmiToInteger32(left, left);
+      __ SmiToInteger64(left, left);
       __ imul(left, ToRegister(right));
     } else {
       __ imull(left, ToRegister(right));
@@ -1368,9 +1372,15 @@
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Bail out if the result is supposed to be negative zero.
     Label done;
-    __ testl(left, left);
+    if (instr->hydrogen_value()->representation().IsSmi()) {
+      __ testq(left, left);
+    } else {
+      __ testl(left, left);
+    }
     __ j(not_zero, &done, Label::kNear);
     if (right->IsConstantOperand()) {
+      // Constant can't be represented as Smi due to immediate size limit.
+      ASSERT(!instr->hydrogen_value()->representation().IsSmi());
       if (ToInteger32(LConstantOperand::cast(right)) < 0) {
         DeoptimizeIf(no_condition, instr->environment());
       } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
@@ -1378,11 +1388,19 @@
         DeoptimizeIf(less, instr->environment());
       }
     } else if (right->IsStackSlot()) {
-      __ orl(kScratchRegister, ToOperand(right));
+      if (instr->hydrogen_value()->representation().IsSmi()) {
+        __ or_(kScratchRegister, ToOperand(right));
+      } else {
+        __ orl(kScratchRegister, ToOperand(right));
+      }
       DeoptimizeIf(sign, instr->environment());
     } else {
       // Test the non-zero operand for negative sign.
-      __ orl(kScratchRegister, ToRegister(right));
+      if (instr->hydrogen_value()->representation().IsSmi()) {
+        __ or_(kScratchRegister, ToRegister(right));
+      } else {
+        __ orl(kScratchRegister, ToRegister(right));
+      }
       DeoptimizeIf(sign, instr->environment());
     }
     __ bind(&done);
@@ -3906,6 +3924,14 @@
 }
 
 
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+  Register function = ToRegister(instr->function());
+  Register code_object = ToRegister(instr->code_object());
+  __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
+  __ movq(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
+}
+
+
 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
   Register result = ToRegister(instr->result());
   Register base = ToRegister(instr->base_object());
@@ -5167,7 +5193,7 @@
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
     FastNewClosureStub stub(instr->hydrogen()->language_mode(),
                             instr->hydrogen()->is_generator());
-    __ Push(instr->hydrogen()->shared_info());
+    __ Move(rbx, instr->hydrogen()->shared_info());
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   } else {
     __ push(rsi);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 96fa719..57938b2 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -263,6 +263,14 @@
 }
 
 
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  function()->PrintTo(stream);
+  stream->Add(".code_entry = ");
+  code_object()->PrintTo(stream);
+}
+
+
 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
   stream->Add(" = ");
   base_object()->PrintTo(stream);
@@ -1083,6 +1091,14 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+    HStoreCodeEntry* store_code_entry) {
+  LOperand* function = UseRegister(store_code_entry->function());
+  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+  return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
     HInnerAllocatedObject* inner_object) {
   LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1827,8 +1843,9 @@
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = UseRegister(instr->value());
-      if (instr->value()->type().IsSmi()) {
+      HValue* val = instr->value();
+      LOperand* value = UseRegister(val);
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
       } else {
         bool truncating = instr->CanTruncateToInt32();
@@ -2374,8 +2391,7 @@
 
 
 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  instr->ReplayEnvironment(env);
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // There are no real uses of a captured object.
   return NULL;
@@ -2423,20 +2439,7 @@
 
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
-  HEnvironment* env = current_block_->last_environment();
-  ASSERT(env != NULL);
-
-  env->set_ast_id(instr->ast_id());
-
-  env->Drop(instr->pop_count());
-  for (int i = instr->values()->length() - 1; i >= 0; --i) {
-    HValue* value = instr->values()->at(i);
-    if (instr->HasAssignedIndexAt(i)) {
-      env->Bind(instr->GetAssignedIndexAt(i), value);
-    } else {
-      env->Push(value);
-    }
-  }
+  instr->ReplayEnvironment(current_block_->last_environment());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index b3a20cf..00642ff 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -160,6 +160,7 @@
   V(SmiTag)                                     \
   V(SmiUntag)                                   \
   V(StackCheck)                                 \
+  V(StoreCodeEntry)                             \
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
@@ -1693,7 +1694,24 @@
 };
 
 
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+    inputs_[0] = function;
+    temps_[0] = code_object;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* code_object() { return temps_[0]; }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LInnerAllocatedObject(LOperand* base_object) {
     inputs_[0] = base_object;
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 5180e6b..0938007 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -685,22 +685,8 @@
 }
 
 
-void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
-                                            bool returns_handle) {
-#if defined(_WIN64) && !defined(__MINGW64__)
-  if (!returns_handle) {
-    EnterApiExitFrame(arg_stack_space);
-    return;
-  }
-  // We need to prepare a slot for result handle on stack and put
-  // a pointer to it into 1st arg register.
-  EnterApiExitFrame(arg_stack_space + 1);
-
-  // rcx must be used to pass the pointer to the return value slot.
-  lea(rcx, StackSpaceOperand(arg_stack_space));
-#else
+void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
   EnterApiExitFrame(arg_stack_space);
-#endif
 }
 
 
@@ -708,7 +694,6 @@
                                               Address thunk_address,
                                               Register thunk_last_arg,
                                               int stack_space,
-                                              bool returns_handle,
                                               int return_value_offset) {
   Label prologue;
   Label promote_scheduled_exception;
@@ -781,23 +766,6 @@
     PopSafepointRegisters();
   }
 
-  // Can skip the result check for new-style callbacks
-  // TODO(dcarney): may need to pass this information down
-  // as some function_addresses might not have been registered
-  if (returns_handle) {
-    Label empty_result;
-#if defined(_WIN64) && !defined(__MINGW64__)
-    // rax keeps a pointer to v8::Handle, unpack it.
-    movq(rax, Operand(rax, 0));
-#endif
-    // Check if the result handle holds 0.
-    testq(rax, rax);
-    j(zero, &empty_result);
-    // It was non-zero.  Dereference to get the result value.
-    movq(rax, Operand(rax, 0));
-    jmp(&prologue);
-    bind(&empty_result);
-  }
   // Load the value from ReturnValue
   movq(rax, Operand(rbp, return_value_offset * kPointerSize));
   bind(&prologue);
@@ -998,7 +966,7 @@
 
 void MacroAssembler::SafeMove(Register dst, Smi* src) {
   ASSERT(!dst.is(kScratchRegister));
-  ASSERT(kSmiValueSize == 32);  // JIT cookie can be converted to Smi.
+  ASSERT(SmiValuesAre32Bits());  // JIT cookie can be converted to Smi.
   if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
     Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
     Move(kScratchRegister, Smi::FromInt(jit_cookie()));
@@ -1010,7 +978,7 @@
 
 
 void MacroAssembler::SafePush(Smi* src) {
-  ASSERT(kSmiValueSize == 32);  // JIT cookie can be converted to Smi.
+  ASSERT(SmiValuesAre32Bits());  // JIT cookie can be converted to Smi.
   if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
     Push(Smi::FromInt(src->value() ^ jit_cookie()));
     Move(kScratchRegister, Smi::FromInt(jit_cookie()));
@@ -2228,6 +2196,30 @@
 }
 
 
+void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) {
+  movq(scratch, src);
+  // High bits.
+  shr(src, Immediate(64 - kSmiShift));
+  shl(src, Immediate(kSmiShift));
+  push(src);
+  // Low bits.
+  shl(scratch, Immediate(kSmiShift));
+  push(scratch);
+}
+
+
+void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) {
+  pop(scratch);
+  // Low bits.
+  shr(scratch, Immediate(kSmiShift));
+  pop(dst);
+  shr(dst, Immediate(kSmiShift));
+  // High bits.
+  shl(dst, Immediate(64 - kSmiShift));
+  or_(dst, scratch);
+}
+
+
 void MacroAssembler::JumpIfNotString(Register object,
                                      Register object_map,
                                      Label* not_string,
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 61abc20..d9fb373 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -720,6 +720,14 @@
   }
 
   void Push(Smi* smi);
+
+  // Save away a 64-bit integer on the stack as two 32-bit integers
+  // masquerading as smis so that the garbage collector skips visiting them.
+  void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister);
+  // Reconstruct a 64-bit integer from two 32-bit integers masquerading as
+  // smis on the top of stack.
+  void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister);
+
   void Test(const Operand& dst, Smi* source);
 
 
@@ -1242,7 +1250,7 @@
   // rcx (rcx must be preserverd until CallApiFunctionAndReturn).  Saves
   // context (rsi).  Clobbers rax.  Allocates arg_stack_space * kPointerSize
   // inside the exit frame (not GCed) accessible via StackSpaceOperand.
-  void PrepareCallApiFunction(int arg_stack_space, bool returns_handle);
+  void PrepareCallApiFunction(int arg_stack_space);
 
   // Calls an API function.  Allocates HandleScope, extracts returned value
   // from handle and propagates exceptions.  Clobbers r14, r15, rbx and
@@ -1252,7 +1260,6 @@
                                 Address thunk_address,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                bool returns_handle,
                                 int return_value_offset_from_rbp);
 
   // Before calling a C-function from generated code, align arguments on stack.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index dcd317c..49d9de6 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -761,7 +761,7 @@
   // position registers.
   __ movq(Operand(rbp, kInputStartMinusOne), rax);
 
-#ifdef WIN32
+#if V8_OS_WIN
   // Ensure that we have written to each stack page, in order. Skipping a page
   // on Windows can cause segmentation faults. Assuming page size is 4k.
   const int kPageSize = 4096;
@@ -771,7 +771,7 @@
       i += kRegistersPerPage) {
     __ movq(register_location(i), rax);  // One write every page.
   }
-#endif  // WIN32
+#endif  // V8_OS_WIN
 
   // Initialize code object pointer.
   __ Move(code_object_pointer(), masm_.CodeObject());
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 6883d38..55e4a9b 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -414,8 +414,10 @@
   __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
   __ movq(StackOperandForReturnAddress(0), scratch);
   __ Move(scratch, Smi::FromInt(0));
-  for (int i = 1; i <= kFastApiCallArguments; i++) {
-     __ movq(Operand(rsp, i * kPointerSize), scratch);
+  StackArgumentsAccessor args(rsp, kFastApiCallArguments,
+                              ARGUMENTS_DONT_CONTAIN_RECEIVER);
+  for (int i = 0; i < kFastApiCallArguments; i++) {
+     __ movq(args.GetArgumentOperand(i), scratch);
   }
 }
 
@@ -464,23 +466,26 @@
   __ LoadHeapObject(rdi, function);
   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
 
+  int api_call_argc = argc + kFastApiCallArguments;
+  StackArgumentsAccessor args(rsp, api_call_argc);
+
   // Pass the additional arguments.
-  __ movq(Operand(rsp, 2 * kPointerSize), rdi);
+  __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ Move(rcx, api_call_info);
     __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
-    __ movq(Operand(rsp, 3 * kPointerSize), rbx);
+    __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
   } else {
-    __ Move(Operand(rsp, 3 * kPointerSize), call_data);
+    __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
   }
   __ movq(kScratchRegister,
           ExternalReference::isolate_address(masm->isolate()));
-  __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister);
+  __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
-  __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister);
-  __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister);
+  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
+  __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
 
   // Prepare arguments.
   STATIC_ASSERT(kFastApiCallArguments == 6);
@@ -488,16 +493,10 @@
 
   // Function address is a foreign pointer outside V8's heap.
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
 
-#if defined(__MINGW64__)
+#if defined(__MINGW64__) || defined(_WIN64)
   Register arguments_arg = rcx;
   Register callback_arg = rdx;
-#elif defined(_WIN64)
-  // Win64 uses first register--rcx--for returned value.
-  Register arguments_arg = returns_handle ? rdx : rcx;
-  Register callback_arg = returns_handle ? r8 : rdx;
 #else
   Register arguments_arg = rdi;
   Register callback_arg = rsi;
@@ -507,7 +506,7 @@
   // it's not controlled by GC.
   const int kApiStackSpace = 4;
 
-  __ PrepareCallApiFunction(kApiStackSpace, returns_handle);
+  __ PrepareCallApiFunction(kApiStackSpace);
 
   __ movq(StackSpaceOperand(0), rbx);  // v8::Arguments::implicit_args_.
   __ addq(rbx, Immediate(argc * kPointerSize));
@@ -519,15 +518,12 @@
   // v8::InvocationCallback's argument.
   __ lea(arguments_arg, StackSpaceOperand(0));
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeInvocationCallback)
-      : FUNCTION_ADDR(&InvokeFunctionCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               callback_arg,
-                              argc + kFastApiCallArguments + 1,
-                              returns_handle,
+                              api_call_argc + 1,
                               kFastApiCallArguments + 1);
 }
 
@@ -1075,7 +1071,7 @@
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ movq(Operand(rsp, kPointerSize), object_reg);
+    __ movq(Operand(rsp, kPCOnStackSize), object_reg);
   }
 
   // Check the maps in the prototype chain.
@@ -1135,7 +1131,7 @@
     }
 
     if (save_at_depth == depth) {
-      __ movq(Operand(rsp, kPointerSize), reg);
+      __ movq(Operand(rsp, kPCOnStackSize), reg);
     }
 
     // Go to the next object in the prototype chain.
@@ -1304,18 +1300,11 @@
   // passed as the const ExecutableAccessorInfo& to the C++ callback.
 
   Address getter_address = v8::ToCData<Address>(callback->getter());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(isolate(), getter_address);
 
-#if defined(__MINGW64__)
+#if defined(__MINGW64__) || defined(_WIN64)
   Register getter_arg = r8;
   Register accessor_info_arg = rdx;
   Register name_arg = rcx;
-#elif defined(_WIN64)
-  // Win64 uses first register--rcx--for returned value.
-  Register getter_arg = returns_handle ? r9 : r8;
-  Register accessor_info_arg = returns_handle ? r8 : rdx;
-  Register name_arg = returns_handle ? rdx : rcx;
 #else
   Register getter_arg = rdx;
   Register accessor_info_arg = rsi;
@@ -1332,7 +1321,7 @@
   // Allocate v8::AccessorInfo in non-GCed stack space.
   const int kArgStackSpace = 1;
 
-  __ PrepareCallApiFunction(kArgStackSpace, returns_handle);
+  __ PrepareCallApiFunction(kArgStackSpace);
   STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
   __ lea(rax, Operand(name_arg, 6 * kPointerSize));
 
@@ -1343,15 +1332,12 @@
   // could be used to pass arguments.
   __ lea(accessor_info_arg, StackSpaceOperand(0));
 
-  Address thunk_address = returns_handle
-      ? FUNCTION_ADDR(&InvokeAccessorGetter)
-      : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
 
   __ CallApiFunctionAndReturn(getter_address,
                               thunk_address,
                               getter_arg,
                               kStackSpace,
-                              returns_handle,
                               5);
 }
 
@@ -1470,11 +1456,8 @@
                                                    Label* miss) {
   ASSERT(holder->IsGlobalObject());
 
-  // Get the number of arguments.
-  const int argc = arguments().immediate();
-
-  // Get the receiver from the stack.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, arguments());
+  __ movq(rdx, args.GetReceiverOperand());
 
 
   // Check that the maps haven't changed.
@@ -1538,9 +1521,8 @@
 
   GenerateNameCheck(name, &miss);
 
-  // Get the receiver from the stack.
-  const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, arguments());
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss);
@@ -1561,7 +1543,7 @@
   // necessary.
   if (object->IsGlobalObject()) {
     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+    __ movq(args.GetReceiverOperand(), rdx);
   }
 
   // Invoke the function.
@@ -1591,11 +1573,11 @@
 
   // Check that function is still array
   const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, argc);
   GenerateNameCheck(name, &miss);
 
   if (cell.is_null()) {
-    // Get the receiver from the stack.
-    __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+    __ movq(rdx, args.GetReceiverOperand());
 
     // Check that the receiver isn't a smi.
     __ JumpIfSmi(rdx, &miss);
@@ -1647,9 +1629,9 @@
   Label miss;
   GenerateNameCheck(name, &miss);
 
-  // Get the receiver from the stack.
   const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss);
@@ -1688,7 +1670,7 @@
       __ j(greater, &attempt_to_grow_elements);
 
       // Check if value is a smi.
-      __ movq(rcx, Operand(rsp, argc * kPointerSize));
+      __ movq(rcx, args.GetArgumentOperand(1));
       __ JumpIfNotSmi(rcx, &with_write_barrier);
 
       // Save new length.
@@ -1723,7 +1705,7 @@
       __ cmpl(rax, rcx);
       __ j(greater, &call_builtin);
 
-      __ movq(rcx, Operand(rsp, argc * kPointerSize));
+      __ movq(rcx, args.GetArgumentOperand(1));
       __ StoreNumberToDoubleElements(
           rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
 
@@ -1800,7 +1782,7 @@
         __ jmp(&call_builtin);
       }
 
-      __ movq(rbx, Operand(rsp, argc * kPointerSize));
+      __ movq(rbx, args.GetArgumentOperand(1));
       // Growing elements that are SMI-only requires special handling in case
       // the new element is non-Smi. For now, delegate to the builtin.
       Label no_fast_elements_check;
@@ -1849,7 +1831,7 @@
       __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
 
       // Restore receiver to rdx as finish sequence assumes it's here.
-      __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+      __ movq(rdx, args.GetReceiverOperand());
 
       // Increment element's and array's sizes.
       __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
@@ -1898,9 +1880,9 @@
   Label miss, return_undefined, call_builtin;
   GenerateNameCheck(name, &miss);
 
-  // Get the receiver from the stack.
   const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss);
@@ -1978,6 +1960,7 @@
   if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
 
   const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, argc);
 
   Label miss;
   Label name_miss;
@@ -2003,9 +1986,9 @@
   Register receiver = rbx;
   Register index = rdi;
   Register result = rax;
-  __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
+  __ movq(receiver, args.GetReceiverOperand());
   if (argc > 0) {
-    __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
+    __ movq(index, args.GetArgumentOperand(1));
   } else {
     __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
   }
@@ -2059,6 +2042,8 @@
   if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
 
   const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, argc);
+
   Label miss;
   Label name_miss;
   Label index_out_of_range;
@@ -2084,9 +2069,9 @@
   Register index = rdi;
   Register scratch = rdx;
   Register result = rax;
-  __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
+  __ movq(receiver, args.GetReceiverOperand());
   if (argc > 0) {
-    __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
+    __ movq(index, args.GetArgumentOperand(1));
   } else {
     __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
   }
@@ -2139,13 +2124,14 @@
   // If the object is not a JSObject or we got an unexpected number of
   // arguments, bail out to the regular call.
   const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, argc);
   if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
 
   Label miss;
   GenerateNameCheck(name, &miss);
 
   if (cell.is_null()) {
-    __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+    __ movq(rdx, args.GetArgumentOperand(argc - 1));
     __ JumpIfSmi(rdx, &miss);
     CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
                     name, &miss);
@@ -2158,7 +2144,7 @@
 
   // Load the char code argument.
   Register code = rbx;
-  __ movq(code, Operand(rsp, 1 * kPointerSize));
+  __ movq(code, args.GetArgumentOperand(argc));
 
   // Check the code is a smi.
   Label slow;
@@ -2345,13 +2331,14 @@
   // If the object is not a JSObject or we got an unexpected number of
   // arguments, bail out to the regular call.
   const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, argc);
   if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
 
   Label miss;
   GenerateNameCheck(name, &miss);
 
   if (cell.is_null()) {
-    __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+    __ movq(rdx, args.GetArgumentOperand(argc - 1));
     __ JumpIfSmi(rdx, &miss);
     CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
                     name, &miss);
@@ -2362,7 +2349,7 @@
     GenerateLoadFunctionFromCell(cell, function, &miss);
   }
   // Load the (only) argument into rax.
-  __ movq(rax, Operand(rsp, 1 * kPointerSize));
+  __ movq(rax, args.GetArgumentOperand(argc));
 
   // Check if the argument is a smi.
   Label not_smi;
@@ -2452,9 +2439,9 @@
   Label miss, miss_before_stack_reserved;
   GenerateNameCheck(name, &miss_before_stack_reserved);
 
-  // Get the receiver from the stack.
   const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, argc);
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss_before_stack_reserved);
@@ -2506,9 +2493,8 @@
   Label miss;
   GenerateNameCheck(name, &miss);
 
-  // Get the receiver from the stack.
-  const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, arguments());
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the receiver isn't a smi.
   if (check != NUMBER_CHECK) {
@@ -2532,7 +2518,7 @@
       // necessary.
       if (object->IsGlobalObject()) {
         __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-        __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+        __ movq(args.GetReceiverOperand(), rdx);
       }
       break;
 
@@ -2652,21 +2638,20 @@
   Label miss;
   GenerateNameCheck(name, &miss);
 
-  // Get the number of arguments.
-  const int argc = arguments().immediate();
 
   LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
 
   // Get the receiver from the stack.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  StackArgumentsAccessor args(rsp, arguments());
+  __ movq(rdx, args.GetReceiverOperand());
 
   CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
   compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
                    &miss);
 
   // Restore receiver.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  __ movq(rdx, args.GetReceiverOperand());
 
   // Check that the function really is a function.
   __ JumpIfSmi(rax, &miss);
@@ -2677,7 +2662,7 @@
   // necessary.
   if (object->IsGlobalObject()) {
     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+    __ movq(args.GetReceiverOperand(), rdx);
   }
 
   // Invoke the function.
@@ -2724,15 +2709,14 @@
   Label miss;
   GenerateNameCheck(name, &miss);
 
-  // Get the number of arguments.
-  const int argc = arguments().immediate();
+  StackArgumentsAccessor args(rsp, arguments());
   GenerateGlobalReceiverCheck(object, holder, name, &miss);
   GenerateLoadFunctionFromCell(cell, function, &miss);
 
   // Patch the receiver on the stack with the global proxy.
   if (object->IsGlobalObject()) {
     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+    __ movq(args.GetReceiverOperand(), rdx);
   }
 
   // Set up the context (function already in rdi).
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 0d3ff15..ebfea0e 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -117,3 +117,6 @@
 
 # Profiling doesn't work on Native Client.
 test-cpu-profiler/*: SKIP
+
+# Fails since 16322 (new test).
+test-code-stubs-arm/ConvertDToI: SKIP
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index 7e0ee70..105ecf1 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -41,7 +41,6 @@
 using ::v8::String;
 using ::v8::Script;
 using ::v8::Function;
-using ::v8::AccessorInfo;
 using ::v8::Extension;
 
 static void handle_property(Local<String> name,
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 192f114..ccf1cbd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -25,17 +25,17 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <limits.h>
-
-#ifndef WIN32
-#include <signal.h>  // kill
-#include <unistd.h>  // getpid
-#endif  // WIN32
+#include <climits>
+#include <csignal>
 #include <string>
 #include <map>
 
 #include "v8.h"
 
+#if V8_OS_POSIX
+#include <unistd.h>  // NOLINT
+#endif
+
 #include "api.h"
 #include "arguments.h"
 #include "cctest.h"
@@ -53,8 +53,6 @@
 
 static const bool kLogThreading = false;
 
-using ::v8::AccessorInfo;
-using ::v8::Arguments;
 using ::v8::Boolean;
 using ::v8::BooleanObject;
 using ::v8::Context;
@@ -1360,7 +1358,7 @@
 
   int32_t value = i::Smi::kMaxValue;
   // We cannot add one to a Smi::kMaxValue without wrapping.
-  if (i::kSmiValueSize < 32) {
+  if (i::SmiValuesAre31Bits()) {
     CHECK(i::Smi::IsValid(value));
     CHECK(!i::Smi::IsValid(value + 1));
 
@@ -1379,7 +1377,7 @@
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
 
   // We cannot add one to a Smi::kMaxValue without wrapping.
-  if (i::kSmiValueSize < 32) {
+  if (i::SmiValuesAre31Bits()) {
     // The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
     // The code will not be run in that case, due to the "if" guard.
     int32_t value =
@@ -9608,6 +9606,26 @@
 }
 
 
+THREADED_TEST(FunctionRemovePrototype) {
+  LocalContext context;
+  v8::HandleScope handle_scope(context->GetIsolate());
+
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->RemovePrototype();
+  Local<v8::Function> fun = t1->GetFunction();
+  context->Global()->Set(v8_str("fun"), fun);
+  CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
+
+  v8::TryCatch try_catch;
+  CompileRun("new fun()");
+  CHECK(try_catch.HasCaught());
+
+  try_catch.Reset();
+  fun->NewInstance();
+  CHECK(try_catch.HasCaught());
+}
+
+
 THREADED_TEST(GetterSetterExceptions) {
   LocalContext context;
   v8::HandleScope handle_scope(context->GetIsolate());
@@ -20013,7 +20031,7 @@
 }
 
 
-#ifndef WIN32
+#if V8_OS_POSIX
 class ThreadInterruptTest {
  public:
   ThreadInterruptTest() : sem_(NULL), sem_value_(0) { }
@@ -20255,4 +20273,4 @@
   v8::V8::SetFailedAccessCheckCallbackFunction(NULL);
 }
 
-#endif  // WIN32
+#endif  // V8_OS_POSIX
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 484eb8e..9281337 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -661,10 +661,11 @@
 // Debug event handler which counts the break points which have been hit.
 int break_point_hit_count = 0;
 int break_point_hit_count_deoptimize = 0;
-static void DebugEventBreakPointHitCount(v8::DebugEvent event,
-                                         v8::Handle<v8::Object> exec_state,
-                                         v8::Handle<v8::Object> event_data,
-                                         v8::Handle<v8::Value> data) {
+static void DebugEventBreakPointHitCount(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+  v8::Handle<v8::Object> event_data = event_details.GetEventData();
   v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
   Debug* debug = isolate->debug();
   // When hitting a debug event listener there must be a break set.
@@ -773,10 +774,11 @@
   uncaught_exception_hit_count = 0;
 }
 
-static void DebugEventCounter(v8::DebugEvent event,
-                              v8::Handle<v8::Object> exec_state,
-                              v8::Handle<v8::Object> event_data,
-                              v8::Handle<v8::Value> data) {
+static void DebugEventCounter(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+  v8::Handle<v8::Object> event_data = event_details.GetEventData();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
 
   // When hitting a debug event listener there must be a break set.
@@ -835,10 +837,10 @@
 v8::Local<v8::Function> evaluate_check_function;
 
 // The actual debug event described by the longer comment above.
-static void DebugEventEvaluate(v8::DebugEvent event,
-                               v8::Handle<v8::Object> exec_state,
-                               v8::Handle<v8::Object> event_data,
-                               v8::Handle<v8::Value> data) {
+static void DebugEventEvaluate(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -862,10 +864,10 @@
 
 // This debug event listener removes a breakpoint in a function
 int debug_event_remove_break_point = 0;
-static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
-                                       v8::Handle<v8::Object> exec_state,
-                                       v8::Handle<v8::Object> event_data,
-                                       v8::Handle<v8::Value> data) {
+static void DebugEventRemoveBreakPoint(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Value> data = event_details.GetCallbackData();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -881,10 +883,9 @@
 // Debug event handler which counts break points hit and performs a step
 // afterwards.
 StepAction step_action = StepIn;  // Step action to perform when stepping.
-static void DebugEventStep(v8::DebugEvent event,
-                           v8::Handle<v8::Object> exec_state,
-                           v8::Handle<v8::Object> event_data,
-                           v8::Handle<v8::Value> data) {
+static void DebugEventStep(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -908,10 +909,10 @@
 const char* expected_step_sequence = NULL;
 
 // The actual debug event described by the longer comment above.
-static void DebugEventStepSequence(v8::DebugEvent event,
-                                   v8::Handle<v8::Object> exec_state,
-                                   v8::Handle<v8::Object> event_data,
-                                   v8::Handle<v8::Value> data) {
+static void DebugEventStepSequence(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -939,10 +940,8 @@
 
 // Debug event handler which performs a garbage collection.
 static void DebugEventBreakPointCollectGarbage(
-    v8::DebugEvent event,
-    v8::Handle<v8::Object> exec_state,
-    v8::Handle<v8::Object> event_data,
-    v8::Handle<v8::Value> data) {
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -965,10 +964,9 @@
 
 // Debug event handler which re-issues a debug break and calls the garbage
 // collector to have the heap verified.
-static void DebugEventBreak(v8::DebugEvent event,
-                            v8::Handle<v8::Object> exec_state,
-                            v8::Handle<v8::Object> event_data,
-                            v8::Handle<v8::Value> data) {
+static void DebugEventBreak(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(debug->break_id(), 0);
@@ -991,10 +989,10 @@
 // reached.
 int max_break_point_hit_count = 0;
 bool terminate_after_max_break_point_hit = false;
-static void DebugEventBreakMax(v8::DebugEvent event,
-                               v8::Handle<v8::Object> exec_state,
-                               v8::Handle<v8::Object> event_data,
-                               v8::Handle<v8::Value> data) {
+static void DebugEventBreakMax(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
   v8::internal::Debug* debug = isolate->debug();
   // When hitting a debug event listener there must be a break set.
@@ -1179,8 +1177,7 @@
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run();
   v8::Local<v8::Function> foo =
       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1201,7 +1198,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1211,8 +1208,7 @@
   break_point_hit_count = 0;
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("bar=1"))->Run();
   v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run();
   v8::Local<v8::Function> foo =
@@ -1234,7 +1230,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1244,8 +1240,7 @@
   break_point_hit_count = 0;
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
   v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run();
   v8::Local<v8::Function> foo =
@@ -1267,7 +1262,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1277,8 +1272,7 @@
   break_point_hit_count = 0;
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
   v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run();
   v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run();
   v8::Local<v8::Function> foo =
@@ -1300,7 +1294,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1310,8 +1304,7 @@
   break_point_hit_count = 0;
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
   v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run();
   v8::Script::Compile(v8::String::New(
       "function foo(){return new bar(1).x;}"))->Run();
@@ -1334,7 +1327,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1355,8 +1348,7 @@
                                         "frame_source_column");
 
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("function foo(){}"))->Run();
   v8::Local<v8::Function> foo =
       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1381,7 +1373,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1404,8 +1396,7 @@
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
   v8::Local<v8::Function> foo;
 
   // Test IC store break point with garbage collection.
@@ -1433,7 +1424,7 @@
   SetBreakPoint(foo, 0);
   CallWithBreakPoints(env->Global(), foo, 1, 25);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1468,8 +1459,7 @@
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Local<v8::Function> foo;
 
   // Test IC store break point with garbage collection.
@@ -1515,7 +1505,7 @@
   CallAndGC(env->Global(), foo);
 
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1527,8 +1517,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
   v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
   //                                               012345678901234567890
@@ -1566,7 +1555,7 @@
   foo->Run();
   CHECK_EQ(8, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Make sure that the break point numbers are consecutive.
@@ -1583,8 +1572,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script = v8::String::New(
     "function f() {\n"
@@ -1668,7 +1656,7 @@
   g->Call(env->Global(), 0, NULL);
   CHECK_EQ(0, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Make sure that the break point numbers are consecutive.
@@ -1687,8 +1675,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> source = v8::String::New(
     "function f() {\n"
@@ -1776,7 +1763,7 @@
   g->Call(env->Global(), 0, NULL);
   CHECK_EQ(0, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Make sure that the break point numbers are consecutive.
@@ -1796,8 +1783,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script = v8::String::New(
     "function f() {\n"
@@ -1841,7 +1827,7 @@
   f->Call(env->Global(), 0, NULL);
   CHECK_EQ(3, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1853,8 +1839,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script = v8::String::New(
     "count = 0;\n"
@@ -1903,7 +1888,7 @@
   }
   CHECK_EQ(5, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1915,8 +1900,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script = v8::String::New(
     "function f() {\n"
@@ -1958,7 +1942,7 @@
   }
   CHECK_EQ(5, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -1970,8 +1954,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::Function> f;
   v8::Local<v8::String> script = v8::String::New(
@@ -2017,7 +2000,7 @@
   f->Call(env->Global(), 0, NULL);
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2029,8 +2012,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::Function> f;
   v8::Local<v8::String> script_f = v8::String::New(
@@ -2083,7 +2065,7 @@
   g->Call(env->Global(), 0, NULL);
   CHECK_EQ(2, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2095,8 +2077,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::Function> f;
   v8::Local<v8::String> script = v8::String::New(
@@ -2139,7 +2120,7 @@
   f->Call(env->Global(), 0, NULL);
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2155,8 +2136,7 @@
                                         frame_function_name_source,
                                         "frame_function_name");
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::Function> f;
   v8::Local<v8::Function> g;
@@ -2245,7 +2225,7 @@
   v8::Script::Compile(script, &origin)->Run();
   CHECK_EQ(0, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2256,8 +2236,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script = v8::String::New(
     "function f() {\n"
@@ -2290,7 +2269,7 @@
   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   CHECK_EQ(0, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2302,8 +2281,7 @@
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   v8::Local<v8::String> script_source = v8::String::New(
     "function f() {\n"
@@ -2323,7 +2301,7 @@
   ClearBreakPointFromJS(sbp1);
   ClearBreakPointFromJS(sbp2);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2339,7 +2317,7 @@
   debug_event_remove_break_point = SetBreakPoint(foo, 0);
 
   // Register the debug event listener pasing the function
-  v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+  v8::Debug::SetDebugEventListener2(DebugEventRemoveBreakPoint, foo);
 
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
@@ -2349,7 +2327,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(0, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2359,8 +2337,7 @@
   break_point_hit_count = 0;
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run();
   v8::Script::Compile(v8::String::New(
       "function foo(){debugger;debugger;}"))->Run();
@@ -2377,7 +2354,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(3, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2387,8 +2364,7 @@
     break_point_hit_count = 0;
     DebugLocalContext env;
     v8::HandleScope scope(env->GetIsolate());
-    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                     v8::Undefined());
+    v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
     v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run();
     v8::Local<v8::Function> foo =
     v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -2404,7 +2380,7 @@
     CHECK_EQ(2, break_point_hit_count);
 
     ClearBreakPoint(bp);
-    v8::Debug::SetDebugEventListener(NULL);
+    v8::Debug::SetDebugEventListener2(NULL);
     CheckDebuggerUnloaded();
 }
 
@@ -2421,7 +2397,7 @@
                                             evaluate_check_source,
                                             "evaluate_check");
   // Register the debug event listener
-  v8::Debug::SetDebugEventListener(DebugEventEvaluate);
+  v8::Debug::SetDebugEventListener2(DebugEventEvaluate);
 
   // Different expected vaules of x and a when in a break point (u = undefined,
   // d = Hello, world!).
@@ -2521,7 +2497,7 @@
   };
   bar->Call(env->Global(), 2, argv_bar_3);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2702,17 +2678,12 @@
 DebugProcessDebugMessagesData process_debug_messages_data;
 
 static void DebugProcessDebugMessagesHandler(
-    const uint16_t* message,
-    int length,
-    v8::Debug::ClientData* client_data) {
-
-  const int kBufferSize = 100000;
-  char print_buffer[kBufferSize];
-  Utf16ToAscii(message, length, print_buffer, kBufferSize);
-
+    const v8::Debug::Message& message) {
+  v8::Handle<v8::String> json = message.GetJSON();
+  v8::String::AsciiValue ascii(json);
   EvaluateResult* array_item = process_debug_messages_data.current();
 
-  bool res = GetEvaluateStringResult(print_buffer,
+  bool res = GetEvaluateStringResult(*ascii,
                                      array_item->buffer,
                                      EvaluateResult::kBufferSize);
   if (res) {
@@ -2724,7 +2695,7 @@
 // Test that the evaluation of expressions works even from ProcessDebugMessages
 // i.e. with empty stack.
 TEST(DebugEvaluateWithoutStack) {
-  v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
+  v8::Debug::SetMessageHandler2(DebugProcessDebugMessagesHandler);
 
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
@@ -2778,8 +2749,8 @@
            0);
   CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
 
-  v8::Debug::SetMessageHandler(NULL);
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetMessageHandler2(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2800,7 +2771,7 @@
   SetBreakPoint(foo, 3);
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   step_action = StepIn;
   break_point_hit_count = 0;
@@ -2809,11 +2780,11 @@
   // With stepping all break locations are hit.
   CHECK_EQ(4, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Register a debug event listener which just counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   SetBreakPoint(foo, 3);
   break_point_hit_count = 0;
@@ -2822,7 +2793,7 @@
   // Without stepping only active break points are hit.
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2833,7 +2804,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping of keyed load. The statement 'y=1'
   // is there to have more than one breakable statement in the loop, TODO(315).
@@ -2870,7 +2841,7 @@
   // With stepping all break locations are hit.
   CHECK_EQ(34, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2881,7 +2852,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping of keyed store. The statement 'y=1'
   // is there to have more than one breakable statement in the loop, TODO(315).
@@ -2917,7 +2888,7 @@
   // With stepping all break locations are hit.
   CHECK_EQ(33, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2928,7 +2899,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping of named load.
   v8::Local<v8::Function> foo = CompileFunction(
@@ -2961,7 +2932,7 @@
   // With stepping all break locations are hit.
   CHECK_EQ(54, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -2971,7 +2942,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping of named store.
   v8::Local<v8::Function> foo = CompileFunction(
@@ -2996,7 +2967,7 @@
   // With stepping all expected break locations are hit.
   CHECK_EQ(expected, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3013,7 +2984,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping.
   v8::Local<v8::Function> foo = CompileFunction(&env,
@@ -3036,11 +3007,11 @@
   // With stepping all break locations are hit.
   CHECK_EQ(11, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Register a debug event listener which just counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   SetBreakPoint(foo, 0);
   break_point_hit_count = 0;
@@ -3049,7 +3020,7 @@
   // Without stepping only active break points are hit.
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3059,7 +3030,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3082,7 +3053,7 @@
   CHECK_EQ(6, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3092,7 +3063,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3115,7 +3086,7 @@
   CHECK_EQ(6, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3125,7 +3096,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3158,7 +3129,7 @@
   CHECK_EQ(5, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3168,7 +3139,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3214,7 +3185,7 @@
   CHECK_EQ(7, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3224,7 +3195,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3254,7 +3225,7 @@
   CHECK_EQ(202, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3264,7 +3235,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3294,7 +3265,7 @@
   CHECK_EQ(202, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3304,7 +3275,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3335,7 +3306,7 @@
   CHECK_EQ(203, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3345,7 +3316,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3386,7 +3357,7 @@
   CHECK_EQ(456, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3396,7 +3367,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3438,7 +3409,7 @@
   CHECK_EQ(504, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3448,7 +3419,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3486,7 +3457,7 @@
   CHECK_EQ(8, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3496,7 +3467,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3517,7 +3488,7 @@
   CHECK_EQ(4, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3527,7 +3498,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3553,7 +3524,7 @@
   CHECK_EQ(5, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3568,7 +3539,7 @@
                                         "frame_function_name");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+  v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3604,7 +3575,7 @@
            break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3619,7 +3590,7 @@
                                         "frame_function_name");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+  v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3656,7 +3627,7 @@
            break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded(true);
 }
 
@@ -3671,7 +3642,7 @@
                                         "frame_function_name");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+  v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3691,7 +3662,7 @@
            break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3708,7 +3679,7 @@
       "foo");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   step_action = StepIn;
   break_point_hit_count = 0;
@@ -3717,11 +3688,11 @@
   // With stepping all break locations are hit.
   CHECK_EQ(3, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Register a debug event listener which just counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
@@ -3729,7 +3700,7 @@
   // Without stepping only active break points are hit.
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3747,7 +3718,7 @@
       "foo");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
 
   step_action = StepIn;
   break_point_hit_count = 0;
@@ -3756,11 +3727,11 @@
   // With stepping all break locations are hit.
   CHECK_EQ(7, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Register a debug event listener which just counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
@@ -3768,7 +3739,7 @@
   // Without stepping only the debugger statement is hit.
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3792,7 +3763,7 @@
       "foo");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStep);
+  v8::Debug::SetDebugEventListener2(DebugEventStep);
   step_action = StepIn;
 
   // Check stepping where the if condition in bar is false.
@@ -3807,11 +3778,11 @@
   foo->Call(env->Global(), argc, argv);
   CHECK_EQ(8, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 
   // Register a debug event listener which just counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
@@ -3819,7 +3790,7 @@
   // Without stepping only the debugger statement is hit.
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3831,7 +3802,7 @@
   env.ExposeDebug();
 
   // Register a debug event listener which counts.
-  v8::Debug::SetDebugEventListener(DebugEventCounter);
+  v8::Debug::SetDebugEventListener2(DebugEventCounter);
 
   // Create a script that returns a function.
   const char* src = "(function (evt) {})";
@@ -3850,7 +3821,7 @@
   CHECK_EQ(1, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -3878,7 +3849,7 @@
       CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
 
   v8::V8::AddMessageListener(MessageCallbackCount);
-  v8::Debug::SetDebugEventListener(DebugEventCounter);
+  v8::Debug::SetDebugEventListener2(DebugEventCounter);
 
   // Initial state should be no break on exceptions.
   DebugEventCounterClear();
@@ -3996,7 +3967,7 @@
   CHECK_EQ(1, uncaught_exception_hit_count);
   CHECK_EQ(1, message_callback_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
   v8::V8::RemoveMessageListeners(MessageCallbackCount);
 }
@@ -4018,7 +3989,7 @@
   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
 
   v8::V8::AddMessageListener(MessageCallbackCount);
-  v8::Debug::SetDebugEventListener(DebugEventCounter);
+  v8::Debug::SetDebugEventListener2(DebugEventCounter);
 
   DebugEventCounterClear();
   MessageCallbackCountClear();
@@ -4072,7 +4043,7 @@
                                         "frame_function_name");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+  v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
 
   // Create functions for testing stepping.
   const char* src = "function a() { n(); }; "
@@ -4144,7 +4115,7 @@
            break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -4158,7 +4129,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which sets the break flag and counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreak);
+  v8::Debug::SetDebugEventListener2(DebugEventBreak);
 
   // Create a function for testing stepping.
   const char* src = "function f0() {}"
@@ -4198,7 +4169,7 @@
   CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -4210,7 +4181,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which sets the break flag and counts.
-  v8::Debug::SetDebugEventListener(DebugEventCounter);
+  v8::Debug::SetDebugEventListener2(DebugEventCounter);
 
   // Create a function for testing stepping.
   const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
@@ -4235,7 +4206,7 @@
   CHECK_EQ(2, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -4251,7 +4222,7 @@
   v8::HandleScope scope(isolate);
 
   // Register a debug event listener which sets the break flag and counts.
-  v8::Debug::SetDebugEventListener(DebugEventCounter);
+  v8::Debug::SetDebugEventListener2(DebugEventCounter);
 
   // Set the debug break flag.
   v8::Debug::DebugBreak();
@@ -4270,7 +4241,7 @@
   CHECK_EQ(0, break_point_hit_count);
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -4875,11 +4846,11 @@
   void Run();
 };
 
-static void MessageHandler(const uint16_t* message, int length,
-                           v8::Debug::ClientData* client_data) {
-  static char print_buffer[1000];
-  Utf16ToAscii(message, length, print_buffer);
-  if (IsBreakEventMessage(print_buffer)) {
+
+static void MessageHandler(const v8::Debug::Message& message) {
+  v8::Handle<v8::String> json = message.GetJSON();
+  v8::String::AsciiValue ascii(json);
+  if (IsBreakEventMessage(*ascii)) {
     // Lets test script wait until break occurs to send commands.
     // Signals when a break is reported.
     message_queue_barriers.semaphore_2->Signal();
@@ -4981,7 +4952,7 @@
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
   message_queue_barriers.Initialize();
-  v8::Debug::SetMessageHandler(MessageHandler);
+  v8::Debug::SetMessageHandler2(MessageHandler);
   message_queue_debugger_thread.Start();
 
   const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
@@ -5447,15 +5418,13 @@
 }
 
 
-static void DummyDebugEventListener(v8::DebugEvent event,
-                                    v8::Handle<v8::Object> exec_state,
-                                    v8::Handle<v8::Object> event_data,
-                                    v8::Handle<v8::Value> data) {
+static void DummyDebugEventListener(
+    const v8::Debug::EventDetails& event_details) {
 }
 
 
 TEST(SetDebugEventListenerOnUninitializedVM) {
-  v8::Debug::SetDebugEventListener(DummyDebugEventListener);
+  v8::Debug::SetDebugEventListener2(DummyDebugEventListener);
 }
 
 
@@ -5646,8 +5615,7 @@
 
   // Set a debug event listener.
   break_point_hit_count = 0;
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
   {
     v8::HandleScope scope(env->GetIsolate());
     // Create a couple of functions for the test.
@@ -5672,7 +5640,7 @@
 
   // Remove the debug event listener without clearing breakpoints. Do this
   // outside a handle scope.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded(true);
 
   // Now set a debug message handler.
@@ -5750,7 +5718,7 @@
 
   // Clear debug message handler.
   message_handler_hit_count = 0;
-  v8::Debug::SetMessageHandler(NULL);
+  v8::Debug::SetMessageHandler2(NULL);
 
   // Run code to throw a unhandled exception. This should end up in the message
   // handler.
@@ -5769,7 +5737,7 @@
   message_handler_hit_count++;
 
   // Clear debug message handler.
-  v8::Debug::SetMessageHandler(NULL);
+  v8::Debug::SetMessageHandler2(NULL);
 }
 
 
@@ -6203,8 +6171,7 @@
                                          compiled_script_data_source,
                                          "compiled_script_data");
 
-  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
 
   // Test function source.
   v8::Local<v8::String> script = v8::String::New(
@@ -6391,10 +6358,9 @@
 // Debug event handler which gets the function on the top frame and schedules a
 // break a number of times.
 static void DebugEventDebugBreak(
-    v8::DebugEvent event,
-    v8::Handle<v8::Object> exec_state,
-    v8::Handle<v8::Object> event_data,
-    v8::Handle<v8::Value> data) {
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
 
   if (event == v8::Break) {
     break_point_hit_count++;
@@ -6445,7 +6411,7 @@
   v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
   CHECK_EQ(12, result->Int32Value());
 
-  v8::Debug::SetDebugEventListener(DebugEventDebugBreak);
+  v8::Debug::SetDebugEventListener2(DebugEventDebugBreak);
   v8::Debug::DebugBreak();
   result = f->Call(env->Global(), argc, argv);
 
@@ -6576,10 +6542,9 @@
 
 // Debug event listener which counts the script collected events.
 int script_collected_count = 0;
-static void DebugEventScriptCollectedEvent(v8::DebugEvent event,
-                                           v8::Handle<v8::Object> exec_state,
-                                           v8::Handle<v8::Object> event_data,
-                                           v8::Handle<v8::Value> data) {
+static void DebugEventScriptCollectedEvent(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   // Count the number of breaks.
   if (event == v8::ScriptCollected) {
     script_collected_count++;
@@ -6603,8 +6568,7 @@
   HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
 
   script_collected_count = 0;
-  v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent);
   {
     v8::Script::Compile(v8::String::New("eval('a=1')"))->Run();
     v8::Script::Compile(v8::String::New("eval('a=2')"))->Run();
@@ -6616,7 +6580,7 @@
 
   CHECK_EQ(2, script_collected_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -7017,7 +6981,7 @@
       "foo");
 
   // Register a debug event listener which steps and counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
 
   // Set the debug break flag before calling the code using function.apply.
   v8::Debug::DebugBreak();
@@ -7031,7 +6995,7 @@
   // When keeping the debug break several break will happen.
   CHECK_GT(break_point_hit_count, 1);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
@@ -7060,10 +7024,9 @@
 // an object with property 'a' == 1. If the property has custom accessor
 // this handler will eventually invoke it.
 static void DebugEventGetAtgumentPropertyValue(
-    v8::DebugEvent event,
-    v8::Handle<v8::Object> exec_state,
-    v8::Handle<v8::Object> event_data,
-    v8::Handle<v8::Value> data) {
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   if (event == v8::Break) {
     break_point_hit_count++;
     CHECK(debugger_context == v8::Context::GetCurrent());
@@ -7100,7 +7063,7 @@
                      named->NewInstance());
 
   // Register the debug event listener
-  v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue);
+  v8::Debug::SetDebugEventListener2(DebugEventGetAtgumentPropertyValue);
 
   // Create a function that invokes debugger.
   v8::Local<v8::Function> foo = CompileFunction(
@@ -7113,7 +7076,7 @@
   foo->Call(env->Global(), 0, NULL);
   CHECK_EQ(1, break_point_hit_count);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   debugee_context = v8::Handle<v8::Context>();
   debugger_context = v8::Handle<v8::Context>();
   CheckDebuggerUnloaded();
@@ -7146,7 +7109,7 @@
   v8::Context::Scope context_scope(expected_context);
   v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
   expected_context.Clear();
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   expected_context_data = v8::Handle<v8::Value>();
   CheckDebuggerUnloaded();
 }
@@ -7213,16 +7176,16 @@
   CHECK_EQ(TestClientData::constructor_call_counter,
            TestClientData::destructor_call_counter);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
 static bool debug_event_break_deoptimize_done = false;
 
-static void DebugEventBreakDeoptimize(v8::DebugEvent event,
-                                      v8::Handle<v8::Object> exec_state,
-                                      v8::Handle<v8::Object> event_data,
-                                      v8::Handle<v8::Value> data) {
+static void DebugEventBreakDeoptimize(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   if (event == v8::Break) {
     if (!frame_function_name.IsEmpty()) {
       // Get the name of the function.
@@ -7265,8 +7228,7 @@
   // This tests lazy deoptimization bailout for the stack check, as the first
   // time in function bar when using debug break and no break points will be at
   // the initial stack check.
-  v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize);
 
   // Compile and run function bar which will optimize it for some flag settings.
   v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run();
@@ -7277,14 +7239,14 @@
 
   CHECK(debug_event_break_deoptimize_done);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
 }
 
 
-static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event,
-                                              v8::Handle<v8::Object> exec_state,
-                                              v8::Handle<v8::Object> event_data,
-                                              v8::Handle<v8::Value> data) {
+static void DebugEventBreakWithOptimizedStack(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
   if (event == v8::Break) {
     if (!frame_function_name.IsEmpty()) {
       for (int i = 0; i < 2; i++) {
@@ -7329,8 +7291,7 @@
 
 
 static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack,
-                                   v8::Undefined());
+  v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack);
   v8::Debug::DebugBreak();
 }
 
@@ -7413,7 +7374,7 @@
   v8::HandleScope scope(env->GetIsolate());
 
   // Register a debug event listener which sets the break flag and counts.
-  v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+  v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
 
   // Create a function for getting the frame count when hitting the break.
   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
@@ -7447,17 +7408,16 @@
   TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
 
   // Get rid of the debug event listener.
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CheckDebuggerUnloaded();
 }
 
 
 v8::Local<v8::Script> inline_script;
 
-static void DebugBreakInlineListener(v8::DebugEvent event,
-                                     v8::Handle<v8::Object> exec_state,
-                                     v8::Handle<v8::Object> event_data,
-                                     v8::Handle<v8::Value> data) {
+static void DebugBreakInlineListener(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   if (event != v8::Break) return;
 
   int expected_frame_count = 4;
@@ -7484,7 +7444,7 @@
     CHECK_EQ(expected_line_number[i],
              i::GetScriptLineNumber(source_script, result->Int32Value()));
   }
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   v8::V8::TerminateExecution();
 }
 
@@ -7507,16 +7467,15 @@
       "g(false);                       \n"
       "%OptimizeFunctionOnNextCall(g); \n"
       "g(true);";
-  v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+  v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
   inline_script = v8::Script::Compile(v8::String::New(source));
   inline_script->Run();
 }
 
 
-static void DebugEventStepNext(v8::DebugEvent event,
-                               v8::Handle<v8::Object> exec_state,
-                               v8::Handle<v8::Object> event_data,
-                               v8::Handle<v8::Value> data) {
+static void DebugEventStepNext(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
   if (event == v8::Break) {
     PrepareStep(StepNext);
   }
@@ -7541,7 +7500,7 @@
   // on the stack.
   DebugLocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Debug::SetDebugEventListener(DebugEventStepNext);
+  v8::Debug::SetDebugEventListener2(DebugEventStepNext);
 
   // We step through the first script.  It exits through an exception.  We run
   // this inside a new frame to record a different FP than the second script
@@ -7553,7 +7512,7 @@
   const char* script_2 = "[0].forEach(function() { });";
   CompileRun(script_2);
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
 }
 
 
@@ -7561,10 +7520,7 @@
 int CountNativeContexts();
 
 
-static void NopListener(v8::DebugEvent event,
-                        v8::Handle<v8::Object> exec_state,
-                        v8::Handle<v8::Object> event_data,
-                        v8::Handle<v8::Value> data) {
+static void NopListener(const v8::Debug::EventDetails& event_details) {
 }
 
 
@@ -7573,15 +7529,15 @@
   v8::HandleScope scope(env->GetIsolate());
   CHECK_EQ(1, CountNativeContexts());
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
   CompileRun("debugger;");
   CHECK_EQ(1, CountNativeContexts());
 
-  v8::Debug::SetDebugEventListener(NopListener);
+  v8::Debug::SetDebugEventListener2(NopListener);
   CompileRun("debugger;");
   CHECK_EQ(2, CountNativeContexts());
 
-  v8::Debug::SetDebugEventListener(NULL);
+  v8::Debug::SetDebugEventListener2(NULL);
 }
 
 
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index a8e870e..90e1f75 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -41,7 +41,6 @@
 #include "parser.h"
 #include "unicode-inl.h"
 
-using ::v8::AccessorInfo;
 using ::v8::Context;
 using ::v8::Extension;
 using ::v8::Function;
diff --git a/test/cctest/test-platform-nullos.cc b/test/cctest/test-platform-nullos.cc
deleted file mode 100644
index 3afbd90..0000000
--- a/test/cctest/test-platform-nullos.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <unistd.h>  // for usleep()
-
-#include "v8.h"
-
-#include "platform.h"
-#include "cctest.h"
-
-using namespace ::v8::internal;
-
-
-static void yield() {
-  UNIMPLEMENTED();
-}
-
-static const int kLockCounterLimit = 50;
-static int busy_lock_counter = 0;
-
-
-static void LoopIncrement(Mutex* mutex, int rem) {
-  while (true) {
-    int count = 0;
-    int last_count = -1;
-    do {
-      CHECK_EQ(0, mutex->Lock());
-      count = busy_lock_counter;
-      CHECK_EQ(0, mutex->Unlock());
-      yield();
-    } while (count % 2 == rem && count < kLockCounterLimit);
-    if (count >= kLockCounterLimit) break;
-    CHECK_EQ(0, mutex->Lock());
-    CHECK_EQ(count, busy_lock_counter);
-    CHECK(last_count == -1 || count == last_count + 1);
-    busy_lock_counter++;
-    last_count = count;
-    CHECK_EQ(0, mutex->Unlock());
-    yield();
-  }
-}
-
-
-static void* RunTestBusyLock(void* arg) {
-  LoopIncrement(static_cast<Mutex*>(arg), 0);
-  return 0;
-}
-
-
-// Runs two threads that repeatedly acquire the lock and conditionally
-// increment a variable.
-TEST(BusyLock) {
-  pthread_t other;
-  Mutex* mutex = OS::CreateMutex();
-  int thread_created = pthread_create(&other,
-                                      NULL,
-                                      &RunTestBusyLock,
-                                      mutex);
-  CHECK_EQ(0, thread_created);
-  LoopIncrement(mutex, 1);
-  pthread_join(other, NULL);
-  delete mutex;
-}
-
-
-TEST(VirtualMemory) {
-  VirtualMemory* vm = new VirtualMemory(1 * MB);
-  CHECK(vm->IsReserved());
-  void* block_addr = vm->address();
-  size_t block_size = 4 * KB;
-  CHECK(vm->Commit(block_addr, block_size, false));
-  // Check whether we can write to memory.
-  int* addr = static_cast<int*>(block_addr);
-  addr[KB-1] = 2;
-  CHECK(vm->Uncommit(block_addr, block_size));
-  delete vm;
-}
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index f56275c..5dd92b6 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -132,14 +132,12 @@
   CHECK_EQ(NULL, helper.Walk(&entry3));
   ProfileNode* node1 = helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(0, node1->self_ticks());
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
   ProfileNode* node2 = helper.Walk(&entry1, &entry2);
   CHECK_NE(NULL, node2);
   CHECK_NE(node1, node2);
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(0, node2->self_ticks());
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -147,18 +145,14 @@
   CHECK_NE(NULL, node3);
   CHECK_NE(node1, node3);
   CHECK_NE(node2, node3);
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(1, node3->self_ticks());
 
   tree.AddPathFromStart(path_vec);
   CHECK_EQ(node1, helper.Walk(&entry1));
   CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
   CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(0, node1->self_ticks());
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(0, node2->self_ticks());
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(2, node3->self_ticks());
 
   CodeEntry* path2[] = {&entry1, &entry2, &entry2};
@@ -172,12 +166,10 @@
   CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
   CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(2, node3->self_ticks());
   ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
   CHECK_NE(NULL, node4);
   CHECK_NE(node3, node4);
-  CHECK_EQ(0, node4->total_ticks());
   CHECK_EQ(1, node4->self_ticks());
 }
 
@@ -199,14 +191,12 @@
   CHECK_EQ(NULL, helper.Walk(&entry3));
   ProfileNode* node1 = helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(0, node1->self_ticks());
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
   ProfileNode* node2 = helper.Walk(&entry1, &entry2);
   CHECK_NE(NULL, node2);
   CHECK_NE(node1, node2);
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(0, node2->self_ticks());
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -214,18 +204,14 @@
   CHECK_NE(NULL, node3);
   CHECK_NE(node1, node3);
   CHECK_NE(node2, node3);
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(1, node3->self_ticks());
 
   tree.AddPathFromEnd(path_vec);
   CHECK_EQ(node1, helper.Walk(&entry1));
   CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
   CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(0, node1->self_ticks());
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(0, node2->self_ticks());
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(2, node3->self_ticks());
 
   CodeEntry* path2[] = {&entry2, &entry2, &entry1};
@@ -239,28 +225,18 @@
   CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
   CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
   CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(2, node3->self_ticks());
   ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
   CHECK_NE(NULL, node4);
   CHECK_NE(node3, node4);
-  CHECK_EQ(0, node4->total_ticks());
   CHECK_EQ(1, node4->self_ticks());
 }
 
 
 TEST(ProfileTreeCalculateTotalTicks) {
   ProfileTree empty_tree;
-  CHECK_EQ(0, empty_tree.root()->total_ticks());
-  CHECK_EQ(0, empty_tree.root()->self_ticks());
-  empty_tree.CalculateTotalTicks();
-  CHECK_EQ(0, empty_tree.root()->total_ticks());
   CHECK_EQ(0, empty_tree.root()->self_ticks());
   empty_tree.root()->IncrementSelfTicks();
-  CHECK_EQ(0, empty_tree.root()->total_ticks());
-  CHECK_EQ(1, empty_tree.root()->self_ticks());
-  empty_tree.CalculateTotalTicks();
-  CHECK_EQ(1, empty_tree.root()->total_ticks());
   CHECK_EQ(1, empty_tree.root()->self_ticks());
 
   CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
@@ -271,17 +247,11 @@
   ProfileTree single_child_tree;
   single_child_tree.AddPathFromStart(e1_path_vec);
   single_child_tree.root()->IncrementSelfTicks();
-  CHECK_EQ(0, single_child_tree.root()->total_ticks());
   CHECK_EQ(1, single_child_tree.root()->self_ticks());
   ProfileTreeTestHelper single_child_helper(&single_child_tree);
   ProfileNode* node1 = single_child_helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
-  CHECK_EQ(0, node1->total_ticks());
-  CHECK_EQ(1, node1->self_ticks());
-  single_child_tree.CalculateTotalTicks();
-  CHECK_EQ(2, single_child_tree.root()->total_ticks());
   CHECK_EQ(1, single_child_tree.root()->self_ticks());
-  CHECK_EQ(1, node1->total_ticks());
   CHECK_EQ(1, node1->self_ticks());
 
   CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
@@ -297,24 +267,16 @@
   flat_tree.AddPathFromStart(e1_e2_path_vec);
   flat_tree.AddPathFromStart(e1_e2_path_vec);
   // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
-  CHECK_EQ(0, flat_tree.root()->total_ticks());
   CHECK_EQ(0, flat_tree.root()->self_ticks());
   node1 = flat_helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(2, node1->self_ticks());
   ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
   CHECK_NE(NULL, node2);
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(3, node2->self_ticks());
-  flat_tree.CalculateTotalTicks();
   // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
-  CHECK_EQ(5, flat_tree.root()->total_ticks());
   CHECK_EQ(0, flat_tree.root()->self_ticks());
-  CHECK_EQ(5, node1->total_ticks());
   CHECK_EQ(2, node1->self_ticks());
-  CHECK_EQ(3, node2->total_ticks());
-  CHECK_EQ(3, node2->self_ticks());
 
   CodeEntry* e2_path[] = {&entry2};
   Vector<CodeEntry*> e2_path_vec(
@@ -339,37 +301,26 @@
   // Results in            -> {entry1,0,2} -> {entry2,0,1}
   //            {root,0,0} -> {entry2,0,3}
   //                       -> {entry3,0,4}
-  CHECK_EQ(0, wide_tree.root()->total_ticks());
   CHECK_EQ(0, wide_tree.root()->self_ticks());
   node1 = wide_helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
-  CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(2, node1->self_ticks());
   ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
   CHECK_NE(NULL, node1_2);
-  CHECK_EQ(0, node1_2->total_ticks());
   CHECK_EQ(1, node1_2->self_ticks());
   node2 = wide_helper.Walk(&entry2);
   CHECK_NE(NULL, node2);
-  CHECK_EQ(0, node2->total_ticks());
   CHECK_EQ(3, node2->self_ticks());
   ProfileNode* node3 = wide_helper.Walk(&entry3);
   CHECK_NE(NULL, node3);
-  CHECK_EQ(0, node3->total_ticks());
   CHECK_EQ(4, node3->self_ticks());
-  wide_tree.CalculateTotalTicks();
   // Calculates             -> {entry1,3,2} -> {entry2,1,1}
   //            {root,10,0} -> {entry2,3,3}
   //                        -> {entry3,4,4}
-  CHECK_EQ(10, wide_tree.root()->total_ticks());
   CHECK_EQ(0, wide_tree.root()->self_ticks());
-  CHECK_EQ(3, node1->total_ticks());
   CHECK_EQ(2, node1->self_ticks());
-  CHECK_EQ(1, node1_2->total_ticks());
   CHECK_EQ(1, node1_2->self_ticks());
-  CHECK_EQ(3, node2->total_ticks());
   CHECK_EQ(3, node2->self_ticks());
-  CHECK_EQ(4, node3->total_ticks());
   CHECK_EQ(4, node3->self_ticks());
 }
 
diff --git a/test/mjsunit/allocation-folding.js b/test/mjsunit/allocation-folding.js
index fe5fa6d..ec07392 100644
--- a/test/mjsunit/allocation-folding.js
+++ b/test/mjsunit/allocation-folding.js
@@ -56,7 +56,7 @@
 
 doubles(); doubles(); doubles();
 %OptimizeFunctionOnNextCall(doubles);
-var result = doubles();
+result = doubles();
 
 gc();
 
@@ -72,8 +72,31 @@
 
 doubles_int(); doubles_int(); doubles_int();
 %OptimizeFunctionOnNextCall(doubles_int);
-var result = doubles_int();
+result = doubles_int();
 
 gc();
 
 assertEquals(result[1], 3.1);
+
+// Test allocation folding over a branch.
+
+function branch_int(left) {
+  var elem1 = [1, 2];
+  var elem2;
+  if (left) {
+    elem2 = [3, 4];
+  } else {
+    elem2 = [5, 6];
+  }
+  return elem2;
+}
+
+branch_int(1); branch_int(1); branch_int(1);
+%OptimizeFunctionOnNextCall(branch_int);
+result = branch_int(1);
+var result2 = branch_int(0);
+
+gc();
+
+assertEquals(result[1], 4);
+assertEquals(result2[1], 6);
diff --git a/test/mjsunit/array-push-non-smi-value.js b/test/mjsunit/array-push-non-smi-value.js
new file mode 100644
index 0000000..460dd2a
--- /dev/null
+++ b/test/mjsunit/array-push-non-smi-value.js
@@ -0,0 +1,36 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check pushes of non-SMI values.
+var a = [];
+function func() {
+  return a.push(0x40000000) > 60;
+}
+
+assertFalse(func());
+assertFalse(func());
+assertFalse(func());
diff --git a/test/mjsunit/compiler/increment-typefeedback.js b/test/mjsunit/compiler/increment-typefeedback.js
new file mode 100644
index 0000000..7989592
--- /dev/null
+++ b/test/mjsunit/compiler/increment-typefeedback.js
@@ -0,0 +1,39 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+  x++;
+  return x;
+}
+
+f(0.5);
+f(0.5);
+%OptimizeFunctionOnNextCall(f);
+f(0.5);
+assertOptimized(f);
diff --git a/test/mjsunit/smi-mul.js b/test/mjsunit/smi-mul.js
new file mode 100644
index 0000000..6f23d5e
--- /dev/null
+++ b/test/mjsunit/smi-mul.js
@@ -0,0 +1,67 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noalways-opt
+
+function mul(a, b) {
+    return a * b;
+}
+
+
+mul(-1, 2);
+mul(-1, 2);
+%OptimizeFunctionOnNextCall(mul);
+assertEquals(-2, mul(-1, 2));
+assertOptimized(mul);
+
+// Deopt on minus zero.
+assertEquals(-0, mul(-1, 0));
+assertUnoptimized(mul);
+
+
+function mul2(a, b) {
+    return a * b;
+}
+
+mul2(-1, 2);
+mul2(-1, 2);
+%OptimizeFunctionOnNextCall(mul2);
+
+// 2^30 is a smi boundary on arm and ia32.
+var two_30 = 1 << 30;
+// 2^31 is a smi boundary on x64.
+var two_31 = 2 * two_30;
+
+if (%IsValidSmi(two_31)) {
+  // Deopt on two_31 on x64.
+  assertEquals(two_31, mul2(-two_31, -1));
+  assertUnoptimized(mul2);
+} else {
+  // Deopt on two_30 on ia32.
+  assertEquals(two_30, mul2(-two_30, -1));
+  assertUnoptimized(mul2);
+}