Merge v8 from https://chromium.googlesource.com/external/v8.git at 4a35c5a501e5b966f895ddea8e19c3ca232cb23f

This commit was generated by merge_from_chromium.py.

Change-Id: Id874513cfaa64c4b6babdc2723483cc3527bc882
diff --git a/ChangeLog b/ChangeLog
index 27ff5d9..8084cc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2013-09-13: Version 3.21.15
+
+        Non-JSObject heap objects are now handled using slow-path IC stub
+        guarded by the map.
+        (Chromium issue 280632)
+
+        i18n Javascript code added to the snapshot.
+        (V8 issue 2745)
+
+        Performance and stability improvements on all platforms.
+
 2013-09-12: Version 3.21.14
 
         Added access check for observed objects.
diff --git a/include/v8.h b/include/v8.h
index d98a768..de27338 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -211,7 +211,7 @@
   /**
    * Creates an empty handle.
    */
-  V8_INLINE(Handle()) : val_(0) {}
+  V8_INLINE Handle() : val_(0) {}
 
   /**
    * Creates a handle for the contents of the specified handle.  This
@@ -223,7 +223,7 @@
    * Handle<String> to a variable declared as Handle<Value>, is legal
    * because String is a subclass of Value.
    */
-  template <class S> V8_INLINE(Handle(Handle<S> that))
+  template <class S> V8_INLINE Handle(Handle<S> that)
       : val_(reinterpret_cast<T*>(*that)) {
     /**
      * This check fails when trying to convert between incompatible
@@ -236,16 +236,16 @@
   /**
    * Returns true if the handle is empty.
    */
-  V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
+  V8_INLINE bool IsEmpty() const { return val_ == 0; }
 
   /**
    * Sets the handle to be empty. IsEmpty() will then return true.
    */
-  V8_INLINE(void Clear()) { val_ = 0; }
+  V8_INLINE void Clear() { val_ = 0; }
 
-  V8_INLINE(T* operator->() const) { return val_; }
+  V8_INLINE T* operator->() const { return val_; }
 
-  V8_INLINE(T* operator*() const) { return val_; }
+  V8_INLINE T* operator*() const { return val_; }
 
   /**
    * Checks whether two handles are the same.
@@ -253,7 +253,7 @@
    * to which they refer are identical.
    * The handles' references are not checked.
    */
-  template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) {
+  template <class S> V8_INLINE bool operator==(const Handle<S>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
     internal::Object** b = reinterpret_cast<internal::Object**>(*that);
     if (a == 0) return b == 0;
@@ -261,8 +261,8 @@
     return *a == *b;
   }
 
-  template <class S> V8_INLINE(
-      bool operator==(const Persistent<S>& that) const) {
+  template <class S> V8_INLINE bool operator==(
+      const Persistent<S>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
     internal::Object** b = reinterpret_cast<internal::Object**>(*that);
     if (a == 0) return b == 0;
@@ -276,16 +276,16 @@
    * the objects to which they refer are different.
    * The handles' references are not checked.
    */
-  template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) {
+  template <class S> V8_INLINE bool operator!=(const Handle<S>& that) const {
     return !operator==(that);
   }
 
-  template <class S> V8_INLINE(
-      bool operator!=(const Persistent<S>& that) const) {
+  template <class S> V8_INLINE bool operator!=(
+      const Persistent<S>& that) const {
     return !operator==(that);
   }
 
-  template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) {
+  template <class S> V8_INLINE static Handle<T> Cast(Handle<S> that) {
 #ifdef V8_ENABLE_CHECKS
     // If we're going to perform the type check then we have to check
     // that the handle isn't empty before doing the checked cast.
@@ -294,14 +294,14 @@
     return Handle<T>(T::Cast(*that));
   }
 
-  template <class S> V8_INLINE(Handle<S> As()) {
+  template <class S> V8_INLINE Handle<S> As() {
     return Handle<S>::Cast(*this);
   }
 
-  V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) {
+  V8_INLINE static Handle<T> New(Isolate* isolate, Handle<T> that) {
     return New(isolate, that.val_);
   }
-  V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) {
+  V8_INLINE static Handle<T> New(Isolate* isolate, const Persistent<T>& that) {
     return New(isolate, that.val_);
   }
 
@@ -312,7 +312,7 @@
   /**
    * Creates a new handle for the specified value.
    */
-  V8_INLINE(explicit Handle(T* val)) : val_(val) {}
+  V8_INLINE explicit Handle(T* val) : val_(val) {}
 
  private:
   friend class Utils;
@@ -328,7 +328,7 @@
   friend class Context;
   friend class HandleScope;
 
-  V8_INLINE(static Handle<T> New(Isolate* isolate, T* that));
+  V8_INLINE static Handle<T> New(Isolate* isolate, T* that);
 
   T* val_;
 };
@@ -343,8 +343,8 @@
  */
 template <class T> class Local : public Handle<T> {
  public:
-  V8_INLINE(Local());
-  template <class S> V8_INLINE(Local(Local<S> that))
+  V8_INLINE Local();
+  template <class S> V8_INLINE Local(Local<S> that)
       : Handle<T>(reinterpret_cast<T*>(*that)) {
     /**
      * This check fails when trying to convert between incompatible
@@ -355,7 +355,7 @@
   }
 
 
-  template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) {
+  template <class S> V8_INLINE static Local<T> Cast(Local<S> that) {
 #ifdef V8_ENABLE_CHECKS
     // If we're going to perform the type check then we have to check
     // that the handle isn't empty before doing the checked cast.
@@ -363,12 +363,12 @@
 #endif
     return Local<T>(T::Cast(*that));
   }
-  template <class S> V8_INLINE(Local(Handle<S> that))
+  template <class S> V8_INLINE Local(Handle<S> that)
       : Handle<T>(reinterpret_cast<T*>(*that)) {
     TYPE_CHECK(T, S);
   }
 
-  template <class S> V8_INLINE(Local<S> As()) {
+  template <class S> V8_INLINE Local<S> As() {
     return Local<S>::Cast(*this);
   }
 
@@ -377,17 +377,17 @@
    * The referee is kept alive by the local handle even when
    * the original handle is destroyed/disposed.
    */
-  V8_INLINE(static Local<T> New(Handle<T> that));
-  V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that));
+  V8_INLINE static Local<T> New(Handle<T> that);
+  V8_INLINE static Local<T> New(Isolate* isolate, Handle<T> that);
   template<class M>
-  V8_INLINE(static Local<T> New(Isolate* isolate,
-                                const Persistent<T, M>& that));
+  V8_INLINE static Local<T> New(Isolate* isolate,
+                                const Persistent<T, M>& that);
 
 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
 
  private:
 #endif
-  template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
+  template <class S> V8_INLINE Local(S* that) : Handle<T>(that) { }
 
  private:
   friend class Utils;
@@ -402,24 +402,22 @@
   template<class F> friend class internal::CustomArguments;
   friend class HandleScope;
 
-  V8_INLINE(static Local<T> New(Isolate* isolate, T* that));
+  V8_INLINE static Local<T> New(Isolate* isolate, T* that);
 };
 
 
 // Eternal handles are set-once handles that live for the life of the isolate.
 template <class T> class Eternal {
  public:
-  V8_INLINE(Eternal()) : index_(kInitialValue) { }
+  V8_INLINE Eternal() : index_(kInitialValue) { }
   template<class S>
-  V8_INLINE(Eternal(Isolate* isolate, Local<S> handle))
-      : index_(kInitialValue) {
+  V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : index_(kInitialValue) {
     Set(isolate, handle);
   }
   // Can only be safely called if already set.
-  V8_INLINE(Local<T> Get(Isolate* isolate));
-  V8_INLINE(bool IsEmpty()) { return index_ == kInitialValue; }
-  template<class S>
-  V8_INLINE(void Set(Isolate* isolate, Local<S> handle));
+  V8_INLINE Local<T> Get(Isolate* isolate);
+  V8_INLINE bool IsEmpty() { return index_ == kInitialValue; }
+  template<class S> V8_INLINE void Set(Isolate* isolate, Local<S> handle);
 
  private:
   static const int kInitialValue = -1;
@@ -432,9 +430,9 @@
  public:
   typedef void (*Callback)(const WeakCallbackData<T, P>& data);
 
-  V8_INLINE(Isolate* GetIsolate()) const { return isolate_; }
-  V8_INLINE(Local<T> GetValue()) const { return handle_; }
-  V8_INLINE(P* GetParameter()) const { return parameter_; }
+  V8_INLINE Isolate* GetIsolate() const { return isolate_; }
+  V8_INLINE Local<T> GetValue() const { return handle_; }
+  V8_INLINE P* GetParameter() const { return parameter_; }
 
  private:
   friend class internal::GlobalHandles;
@@ -470,13 +468,12 @@
   typedef Persistent<T, NonCopyablePersistentTraits<T> > NonCopyablePersistent;
   static const bool kResetInDestructor = false;
   template<class S, class M>
-  V8_INLINE(static void Copy(const Persistent<S, M>& source,
-                             NonCopyablePersistent* dest)) {
+  V8_INLINE static void Copy(const Persistent<S, M>& source,
+                             NonCopyablePersistent* dest) {
     Uncompilable<Object>();
   }
   // TODO(dcarney): come up with a good compile error here.
-  template<class O>
-  V8_INLINE(static void Uncompilable()) {
+  template<class O> V8_INLINE static void Uncompilable() {
     TYPE_CHECK(O, Primitive);
   }
 };
@@ -502,13 +499,13 @@
   /**
    * A Persistent with no storage cell.
    */
-  V8_INLINE(Persistent()) : val_(0) { }
+  V8_INLINE Persistent() : val_(0) { }
   /**
    * Construct a Persistent from a Handle.
    * When the Handle is non-empty, a new storage cell is created
    * pointing to the same object, and no flags are set.
    */
-  template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that))
+  template <class S> V8_INLINE Persistent(Isolate* isolate, Handle<S> that)
       : val_(New(isolate, *that)) {
     TYPE_CHECK(T, S);
   }
@@ -518,7 +515,7 @@
    * pointing to the same object, and no flags are set.
    */
   template <class S, class M2>
-  V8_INLINE(Persistent(Isolate* isolate, const Persistent<S, M2>& that))
+  V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that)
     : val_(New(isolate, *that)) {
     TYPE_CHECK(T, S);
   }
@@ -528,19 +525,19 @@
    * traits class is called, allowing the setting of flags based on the
    * copied Persistent.
    */
-  V8_INLINE(Persistent(const Persistent& that)) : val_(0) {
+  V8_INLINE Persistent(const Persistent& that) : val_(0) {
     Copy(that);
   }
   template <class S, class M2>
-  V8_INLINE(Persistent(const Persistent<S, M2>& that)) : val_(0) {
+  V8_INLINE Persistent(const Persistent<S, M2>& that) : val_(0) {
     Copy(that);
   }
-  V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT
+  V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT
     Copy(that);
     return *this;
   }
   template <class S, class M2>
-  V8_INLINE(Persistent& operator=(const Persistent<S, M2>& that)) { // NOLINT
+  V8_INLINE Persistent& operator=(const Persistent<S, M2>& that) { // NOLINT
     Copy(that);
     return *this;
   }
@@ -549,7 +546,7 @@
    * kResetInDestructor flags in the traits class.  Since not calling dispose
    * can result in a memory leak, it is recommended to always set this flag.
    */
-  V8_INLINE(~Persistent()) {
+  V8_INLINE ~Persistent() {
     if (M::kResetInDestructor) Reset();
   }
 
@@ -557,28 +554,28 @@
    * If non-empty, destroy the underlying storage cell
    * IsEmpty() will return true after this call.
    */
-  V8_INLINE(void Reset());
-  template <class S>
+  V8_INLINE void Reset();
   /**
    * If non-empty, destroy the underlying storage cell
    * and create a new one with the contents of other if other is non empty
    */
-  V8_INLINE(void Reset(Isolate* isolate, const Handle<S>& other));
+  template <class S>
+  V8_INLINE void Reset(Isolate* isolate, const Handle<S>& other);
   /**
    * If non-empty, destroy the underlying storage cell
    * and create a new one with the contents of other if other is non empty
    */
   template <class S, class M2>
-  V8_INLINE(void Reset(Isolate* isolate, const Persistent<S, M2>& other));
+  V8_INLINE void Reset(Isolate* isolate, const Persistent<S, M2>& other);
   // TODO(dcarney): deprecate
-  V8_INLINE(void Dispose()) { Reset(); }
-  V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Reset(); }
+  V8_INLINE void Dispose() { Reset(); }
+  V8_DEPRECATED(V8_INLINE void Dispose(Isolate* isolate)) { Reset(); }
 
-  V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
+  V8_INLINE bool IsEmpty() const { return val_ == 0; }
 
   // TODO(dcarney): this is pretty useless, fix or remove
   template <class S>
-  V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT
+  V8_INLINE static Persistent<T>& Cast(Persistent<S>& that) { // NOLINT
 #ifdef V8_ENABLE_CHECKS
     // If we're going to perform the type check then we have to check
     // that the handle isn't empty before doing the checked cast.
@@ -588,12 +585,12 @@
   }
 
   // TODO(dcarney): this is pretty useless, fix or remove
-  template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT
+  template <class S> V8_INLINE Persistent<S>& As() { // NOLINT
     return Persistent<S>::Cast(*this);
   }
 
-  template <class S, class M2> V8_INLINE(
-      bool operator==(const Persistent<S, M2>& that) const) {
+  template <class S, class M2>
+  V8_INLINE bool operator==(const Persistent<S, M2>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
     internal::Object** b = reinterpret_cast<internal::Object**>(*that);
     if (a == 0) return b == 0;
@@ -601,7 +598,7 @@
     return *a == *b;
   }
 
-  template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const) {
+  template <class S> V8_INLINE bool operator==(const Handle<S>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
     internal::Object** b = reinterpret_cast<internal::Object**>(*that);
     if (a == 0) return b == 0;
@@ -609,40 +606,40 @@
     return *a == *b;
   }
 
-  template <class S, class M2> V8_INLINE(
-      bool operator!=(const Persistent<S, M2>& that) const) {
+  template <class S, class M2>
+  V8_INLINE bool operator!=(const Persistent<S, M2>& that) const {
     return !operator==(that);
   }
 
-  template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) {
+  template <class S> V8_INLINE bool operator!=(const Handle<S>& that) const {
     return !operator==(that);
   }
 
   template<typename P>
-  V8_INLINE(void SetWeak(
+  V8_INLINE void SetWeak(
       P* parameter,
-      typename WeakCallbackData<T, P>::Callback callback));
+      typename WeakCallbackData<T, P>::Callback callback);
 
   template<typename S, typename P>
-  V8_INLINE(void SetWeak(
+  V8_INLINE void SetWeak(
       P* parameter,
-      typename WeakCallbackData<S, P>::Callback callback));
+      typename WeakCallbackData<S, P>::Callback callback);
 
   // TODO(dcarney): deprecate
   template<typename S, typename P>
-  V8_INLINE(void MakeWeak(
+  V8_INLINE void MakeWeak(
       P* parameter,
-      typename WeakReferenceCallbacks<S, P>::Revivable callback));
+      typename WeakReferenceCallbacks<S, P>::Revivable callback);
 
   // TODO(dcarney): deprecate
   template<typename P>
-  V8_INLINE(void MakeWeak(
+  V8_INLINE void MakeWeak(
       P* parameter,
-      typename WeakReferenceCallbacks<T, P>::Revivable callback));
+      typename WeakReferenceCallbacks<T, P>::Revivable callback);
 
-  V8_INLINE(void ClearWeak());
+  V8_INLINE void ClearWeak();
 
-  V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); }
+  V8_DEPRECATED(V8_INLINE void ClearWeak(Isolate* isolate)) { ClearWeak(); }
 
   /**
    * Marks the reference to this object independent. Garbage collector is free
@@ -650,9 +647,9 @@
    * independent handle should not assume that it will be preceded by a global
    * GC prologue callback or followed by a global GC epilogue callback.
    */
-  V8_INLINE(void MarkIndependent());
+  V8_INLINE void MarkIndependent();
 
-  V8_DEPRECATED(V8_INLINE(void MarkIndependent(Isolate* isolate))) {
+  V8_DEPRECATED(V8_INLINE void MarkIndependent(Isolate* isolate)) {
     MarkIndependent();
   }
 
@@ -664,29 +661,29 @@
    * external dependencies. This mark is automatically cleared after each
    * garbage collection.
    */
-  V8_INLINE(void MarkPartiallyDependent());
+  V8_INLINE void MarkPartiallyDependent();
 
-  V8_DEPRECATED(V8_INLINE(void MarkPartiallyDependent(Isolate* isolate))) {
+  V8_DEPRECATED(V8_INLINE void MarkPartiallyDependent(Isolate* isolate)) {
     MarkPartiallyDependent();
   }
 
-  V8_INLINE(bool IsIndependent() const);
+  V8_INLINE bool IsIndependent() const;
 
-  V8_DEPRECATED(V8_INLINE(bool IsIndependent(Isolate* isolate)) const) {
+  V8_DEPRECATED(V8_INLINE bool IsIndependent(Isolate* isolate) const) {
     return IsIndependent();
   }
 
   /** Checks if the handle holds the only reference to an object. */
-  V8_INLINE(bool IsNearDeath() const);
+  V8_INLINE bool IsNearDeath() const;
 
-  V8_DEPRECATED(V8_INLINE(bool IsNearDeath(Isolate* isolate)) const) {
+  V8_DEPRECATED(V8_INLINE bool IsNearDeath(Isolate* isolate) const) {
     return IsNearDeath();
   }
 
   /** Returns true if the handle's reference is weak.  */
-  V8_INLINE(bool IsWeak() const);
+  V8_INLINE bool IsWeak() const;
 
-  V8_DEPRECATED(V8_INLINE(bool IsWeak(Isolate* isolate)) const) {
+  V8_DEPRECATED(V8_INLINE bool IsWeak(Isolate* isolate) const) {
     return IsWeak();
   }
 
@@ -694,10 +691,10 @@
    * Assigns a wrapper class ID to the handle. See RetainedObjectInfo interface
    * description in v8-profiler.h for details.
    */
-  V8_INLINE(void SetWrapperClassId(uint16_t class_id));
+  V8_INLINE void SetWrapperClassId(uint16_t class_id);
 
   V8_DEPRECATED(
-      V8_INLINE(void SetWrapperClassId(Isolate * isolate, uint16_t class_id))) {
+      V8_INLINE void SetWrapperClassId(Isolate * isolate, uint16_t class_id)) {
     SetWrapperClassId(class_id);
   }
 
@@ -705,26 +702,26 @@
    * Returns the class ID previously assigned to this handle or 0 if no class ID
    * was previously assigned.
    */
-  V8_INLINE(uint16_t WrapperClassId() const);
+  V8_INLINE uint16_t WrapperClassId() const;
 
-  V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) {
+  V8_DEPRECATED(V8_INLINE uint16_t WrapperClassId(Isolate* isolate) const) {
     return WrapperClassId();
   }
 
   // TODO(dcarney): remove
-  V8_INLINE(T* ClearAndLeak());
+  V8_INLINE T* ClearAndLeak();
 
   // TODO(dcarney): remove
-  V8_INLINE(void Clear()) { val_ = 0; }
+  V8_INLINE void Clear() { val_ = 0; }
 
   // TODO(dcarney): remove
 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
 
  private:
 #endif
-  template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { }
+  template <class S> V8_INLINE Persistent(S* that) : val_(that) { }
 
-  V8_INLINE(T* operator*() const) { return val_; }
+  V8_INLINE T* operator*() const { return val_; }
 
  private:
   friend class Utils;
@@ -733,9 +730,9 @@
   template<class F1, class F2> friend class Persistent;
   template<class F> friend class ReturnValue;
 
-  V8_INLINE(static T* New(Isolate* isolate, T* that));
+  V8_INLINE static T* New(Isolate* isolate, T* that);
   template<class S, class M2>
-  V8_INLINE(void Copy(const Persistent<S, M2>& that));
+  V8_INLINE void Copy(const Persistent<S, M2>& that);
 
   T* val_;
 };
@@ -795,7 +792,7 @@
     internal::Object** next;
     internal::Object** limit;
     int level;
-    V8_INLINE(void Initialize()) {
+    V8_INLINE void Initialize() {
       next = limit = NULL;
       level = 0;
     }
@@ -904,19 +901,19 @@
  */
 class ScriptOrigin {
  public:
-  V8_INLINE(ScriptOrigin(
+  V8_INLINE ScriptOrigin(
       Handle<Value> resource_name,
       Handle<Integer> resource_line_offset = Handle<Integer>(),
       Handle<Integer> resource_column_offset = Handle<Integer>(),
-      Handle<Boolean> resource_is_shared_cross_origin = Handle<Boolean>()))
+      Handle<Boolean> resource_is_shared_cross_origin = Handle<Boolean>())
       : resource_name_(resource_name),
         resource_line_offset_(resource_line_offset),
         resource_column_offset_(resource_column_offset),
         resource_is_shared_cross_origin_(resource_is_shared_cross_origin) { }
-  V8_INLINE(Handle<Value> ResourceName() const);
-  V8_INLINE(Handle<Integer> ResourceLineOffset() const);
-  V8_INLINE(Handle<Integer> ResourceColumnOffset() const);
-  V8_INLINE(Handle<Boolean> ResourceIsSharedCrossOrigin() const);
+  V8_INLINE Handle<Value> ResourceName() const;
+  V8_INLINE Handle<Integer> ResourceLineOffset() const;
+  V8_INLINE Handle<Integer> ResourceColumnOffset() const;
+  V8_INLINE Handle<Boolean> ResourceIsSharedCrossOrigin() const;
  private:
   Handle<Value> resource_name_;
   Handle<Integer> resource_line_offset_;
@@ -1257,13 +1254,13 @@
    * Returns true if this value is the undefined value.  See ECMA-262
    * 4.3.10.
    */
-  V8_INLINE(bool IsUndefined() const);
+  V8_INLINE bool IsUndefined() const;
 
   /**
    * Returns true if this value is the null value.  See ECMA-262
    * 4.3.11.
    */
-  V8_INLINE(bool IsNull() const);
+  V8_INLINE bool IsNull() const;
 
    /**
    * Returns true if this value is true.
@@ -1279,7 +1276,7 @@
    * Returns true if this value is an instance of the String type.
    * See ECMA-262 8.4.
    */
-  V8_INLINE(bool IsString() const);
+  V8_INLINE bool IsString() const;
 
   /**
    * Returns true if this value is a symbol.
@@ -1467,12 +1464,12 @@
   bool Equals(Handle<Value> that) const;
   bool StrictEquals(Handle<Value> that) const;
 
-  template <class T> V8_INLINE(static Value* Cast(T* value));
+  template <class T> V8_INLINE static Value* Cast(T* value);
 
  private:
-  V8_INLINE(bool QuickIsUndefined() const);
-  V8_INLINE(bool QuickIsNull() const);
-  V8_INLINE(bool QuickIsString() const);
+  V8_INLINE bool QuickIsUndefined() const;
+  V8_INLINE bool QuickIsNull() const;
+  V8_INLINE bool QuickIsString() const;
   bool FullIsUndefined() const;
   bool FullIsNull() const;
   bool FullIsString() const;
@@ -1492,7 +1489,7 @@
 class V8_EXPORT Boolean : public Primitive {
  public:
   bool Value() const;
-  V8_INLINE(static Handle<Boolean> New(bool value));
+  V8_INLINE static Handle<Boolean> New(bool value);
 };
 
 
@@ -1521,7 +1518,7 @@
   /**
    * This function is no longer useful.
    */
-  V8_DEPRECATED(V8_INLINE(bool MayContainNonAscii()) const) { return true; }
+  V8_DEPRECATED(V8_INLINE bool MayContainNonAscii() const) { return true; }
 
   /**
    * Returns whether this string is known to contain only one byte data.
@@ -1593,7 +1590,7 @@
    * A zero length string.
    */
   static v8::Local<v8::String> Empty();
-  V8_INLINE(static v8::Local<v8::String> Empty(Isolate* isolate));
+  V8_INLINE static v8::Local<v8::String> Empty(Isolate* isolate);
 
   /**
    * Returns true if the string is external
@@ -1691,14 +1688,14 @@
    * regardless of the encoding, otherwise return NULL.  The encoding of the
    * string is returned in encoding_out.
    */
-  V8_INLINE(ExternalStringResourceBase* GetExternalStringResourceBase(
-      Encoding* encoding_out) const);
+  V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
+      Encoding* encoding_out) const;
 
   /**
    * Get the ExternalStringResource for an external string.  Returns
    * NULL if IsExternal() doesn't return true.
    */
-  V8_INLINE(ExternalStringResource* GetExternalStringResource() const);
+  V8_INLINE ExternalStringResource* GetExternalStringResource() const;
 
   /**
    * Get the ExternalAsciiStringResource for an external ASCII string.
@@ -1706,7 +1703,7 @@
    */
   const ExternalAsciiStringResource* GetExternalAsciiStringResource() const;
 
-  V8_INLINE(static String* Cast(v8::Value* obj));
+  V8_INLINE static String* Cast(v8::Value* obj);
 
   // TODO(dcarney): deprecate
   /**
@@ -1714,18 +1711,18 @@
    * The second parameter 'length' gives the buffer length. If omitted,
    * the function calls 'strlen' to determine the buffer length.
    */
-  V8_INLINE(static Local<String> New(const char* data, int length = -1));
+  V8_INLINE static Local<String> New(const char* data, int length = -1);
 
   // TODO(dcarney): deprecate
   /** Allocates a new string from 16-bit character codes.*/
-  V8_INLINE(static Local<String> New(const uint16_t* data, int length = -1));
+  V8_INLINE static Local<String> New(const uint16_t* data, int length = -1);
 
   // TODO(dcarney): deprecate
   /**
    * Creates an internalized string (historically called a "symbol",
    * not to be confused with ES6 symbols). Returns one if it exists already.
    */
-  V8_INLINE(static Local<String> NewSymbol(const char* data, int length = -1));
+  V8_INLINE static Local<String> NewSymbol(const char* data, int length = -1);
 
   enum NewStringType {
     kNormalString, kInternalizedString, kUndetectableString
@@ -1806,13 +1803,13 @@
 
   // TODO(dcarney): deprecate
   /** Creates an undetectable string from the supplied ASCII or UTF-8 data.*/
-  V8_INLINE(
-      static Local<String> NewUndetectable(const char* data, int length = -1));
+  V8_INLINE static Local<String> NewUndetectable(const char* data,
+                                                 int length = -1);
 
   // TODO(dcarney): deprecate
   /** Creates an undetectable string from the supplied 16-bit character codes.*/
-  V8_INLINE(static Local<String> NewUndetectable(
-      const uint16_t* data, int length = -1));
+  V8_INLINE static Local<String> NewUndetectable(const uint16_t* data,
+                                                 int length = -1);
 
   /**
    * Converts an object to a UTF-8-encoded character array.  Useful if
@@ -1907,7 +1904,7 @@
   // Create a symbol with a print name.
   static Local<Symbol> New(Isolate *isolate, const char* data, int length = -1);
 
-  V8_INLINE(static Symbol* Cast(v8::Value* obj));
+  V8_INLINE static Symbol* Cast(v8::Value* obj);
  private:
   Symbol();
   static void CheckCast(v8::Value* obj);
@@ -1922,7 +1919,7 @@
   double Value() const;
   static Local<Number> New(double value);
   static Local<Number> New(Isolate* isolate, double value);
-  V8_INLINE(static Number* Cast(v8::Value* obj));
+  V8_INLINE static Number* Cast(v8::Value* obj);
  private:
   Number();
   static void CheckCast(v8::Value* obj);
@@ -1939,7 +1936,7 @@
   static Local<Integer> New(int32_t value, Isolate*);
   static Local<Integer> NewFromUnsigned(uint32_t value, Isolate*);
   int64_t Value() const;
-  V8_INLINE(static Integer* Cast(v8::Value* obj));
+  V8_INLINE static Integer* Cast(v8::Value* obj);
  private:
   Integer();
   static void CheckCast(v8::Value* obj);
@@ -2140,7 +2137,7 @@
   int InternalFieldCount();
 
   /** Gets the value from an internal field. */
-  V8_INLINE(Local<Value> GetInternalField(int index));
+  V8_INLINE Local<Value> GetInternalField(int index);
 
   /** Sets the value in an internal field. */
   void SetInternalField(int index, Handle<Value> value);
@@ -2150,7 +2147,7 @@
    * must have been set by SetAlignedPointerInInternalField, everything else
    * leads to undefined behavior.
    */
-  V8_INLINE(void* GetAlignedPointerFromInternalField(int index));
+  V8_INLINE void* GetAlignedPointerFromInternalField(int index);
 
   /**
    * Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
@@ -2280,7 +2277,7 @@
   Local<Value> CallAsConstructor(int argc, Handle<Value> argv[]);
 
   static Local<Object> New();
-  V8_INLINE(static Object* Cast(Value* obj));
+  V8_INLINE static Object* Cast(Value* obj);
 
  private:
   Object();
@@ -2309,7 +2306,7 @@
    */
   static Local<Array> New(int length = 0);
 
-  V8_INLINE(static Array* Cast(Value* obj));
+  V8_INLINE static Array* Cast(Value* obj);
  private:
   Array();
   static void CheckCast(Value* obj);
@@ -2319,31 +2316,31 @@
 template<typename T>
 class ReturnValue {
  public:
-  template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
+  template <class S> V8_INLINE ReturnValue(const ReturnValue<S>& that)
       : value_(that.value_) {
     TYPE_CHECK(T, S);
   }
   // Handle setters
-  template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
-  template <typename S> V8_INLINE(void Set(const Handle<S> handle));
+  template <typename S> V8_INLINE void Set(const Persistent<S>& handle);
+  template <typename S> V8_INLINE void Set(const Handle<S> handle);
   // Fast primitive setters
-  V8_INLINE(void Set(bool value));
-  V8_INLINE(void Set(double i));
-  V8_INLINE(void Set(int32_t i));
-  V8_INLINE(void Set(uint32_t i));
+  V8_INLINE void Set(bool value);
+  V8_INLINE void Set(double i);
+  V8_INLINE void Set(int32_t i);
+  V8_INLINE void Set(uint32_t i);
   // Fast JS primitive setters
-  V8_INLINE(void SetNull());
-  V8_INLINE(void SetUndefined());
-  V8_INLINE(void SetEmptyString());
+  V8_INLINE void SetNull();
+  V8_INLINE void SetUndefined();
+  V8_INLINE void SetEmptyString();
   // Convenience getter for Isolate
-  V8_INLINE(Isolate* GetIsolate());
+  V8_INLINE Isolate* GetIsolate();
 
  private:
   template<class F> friend class ReturnValue;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
-  V8_INLINE(internal::Object* GetDefaultValue());
-  V8_INLINE(explicit ReturnValue(internal::Object** slot));
+  V8_INLINE internal::Object* GetDefaultValue();
+  V8_INLINE explicit ReturnValue(internal::Object** slot);
   internal::Object** value_;
 };
 
@@ -2357,15 +2354,15 @@
 template<typename T>
 class FunctionCallbackInfo {
  public:
-  V8_INLINE(int Length() const);
-  V8_INLINE(Local<Value> operator[](int i) const);
-  V8_INLINE(Local<Function> Callee() const);
-  V8_INLINE(Local<Object> This() const);
-  V8_INLINE(Local<Object> Holder() const);
-  V8_INLINE(bool IsConstructCall() const);
-  V8_INLINE(Local<Value> Data() const);
-  V8_INLINE(Isolate* GetIsolate() const);
-  V8_INLINE(ReturnValue<T> GetReturnValue() const);
+  V8_INLINE int Length() const;
+  V8_INLINE Local<Value> operator[](int i) const;
+  V8_INLINE Local<Function> Callee() const;
+  V8_INLINE Local<Object> This() const;
+  V8_INLINE Local<Object> Holder() const;
+  V8_INLINE bool IsConstructCall() const;
+  V8_INLINE Local<Value> Data() const;
+  V8_INLINE Isolate* GetIsolate() const;
+  V8_INLINE ReturnValue<T> GetReturnValue() const;
   // This shouldn't be public, but the arm compiler needs it.
   static const int kArgsLength = 6;
 
@@ -2379,10 +2376,10 @@
   static const int kCalleeIndex = -4;
   static const int kHolderIndex = -5;
 
-  V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
+  V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args,
                    internal::Object** values,
                    int length,
-                   bool is_construct_call));
+                   bool is_construct_call);
   internal::Object** implicit_args_;
   internal::Object** values_;
   int length_;
@@ -2397,11 +2394,11 @@
 template<typename T>
 class PropertyCallbackInfo {
  public:
-  V8_INLINE(Isolate* GetIsolate() const);
-  V8_INLINE(Local<Value> Data() const);
-  V8_INLINE(Local<Object> This() const);
-  V8_INLINE(Local<Object> Holder() const);
-  V8_INLINE(ReturnValue<T> GetReturnValue() const);
+  V8_INLINE Isolate* GetIsolate() const;
+  V8_INLINE Local<Value> Data() const;
+  V8_INLINE Local<Object> This() const;
+  V8_INLINE Local<Object> Holder() const;
+  V8_INLINE ReturnValue<T> GetReturnValue() const;
   // This shouldn't be public, but the arm compiler needs it.
   static const int kArgsLength = 6;
 
@@ -2410,14 +2407,13 @@
   friend class internal::PropertyCallbackArguments;
   friend class internal::CustomArguments<PropertyCallbackInfo>;
   static const int kThisIndex = 0;
-  static const int kHolderIndex = -1;
-  static const int kDataIndex = -2;
-  static const int kReturnValueIndex = -3;
-  static const int kReturnValueDefaultValueIndex = -4;
-  static const int kIsolateIndex = -5;
+  static const int kDataIndex = -1;
+  static const int kReturnValueIndex = -2;
+  static const int kReturnValueDefaultValueIndex = -3;
+  static const int kIsolateIndex = -4;
+  static const int kHolderIndex = -5;
 
-  V8_INLINE(PropertyCallbackInfo(internal::Object** args))
-      : args_(args) { }
+  V8_INLINE PropertyCallbackInfo(internal::Object** args) : args_(args) {}
   internal::Object** args_;
 };
 
@@ -2476,7 +2472,7 @@
   int ScriptId() const;
 
   ScriptOrigin GetScriptOrigin() const;
-  V8_INLINE(static Function* Cast(Value* obj));
+  V8_INLINE static Function* Cast(Value* obj);
   static const int kLineOffsetNotFound;
 
  private:
@@ -2595,7 +2591,7 @@
    */
   Contents Externalize();
 
-  V8_INLINE(static ArrayBuffer* Cast(Value* obj));
+  V8_INLINE static ArrayBuffer* Cast(Value* obj);
 
   static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
 
@@ -2636,7 +2632,7 @@
    */
   void* BaseAddress();
 
-  V8_INLINE(static ArrayBufferView* Cast(Value* obj));
+  V8_INLINE static ArrayBufferView* Cast(Value* obj);
 
   static const int kInternalFieldCount =
       V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT;
@@ -2660,7 +2656,7 @@
    */
   size_t Length();
 
-  V8_INLINE(static TypedArray* Cast(Value* obj));
+  V8_INLINE static TypedArray* Cast(Value* obj);
 
  private:
   TypedArray();
@@ -2676,7 +2672,7 @@
  public:
   static Local<Uint8Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Uint8Array* Cast(Value* obj));
+  V8_INLINE static Uint8Array* Cast(Value* obj);
 
  private:
   Uint8Array();
@@ -2692,7 +2688,7 @@
  public:
   static Local<Uint8ClampedArray> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Uint8ClampedArray* Cast(Value* obj));
+  V8_INLINE static Uint8ClampedArray* Cast(Value* obj);
 
  private:
   Uint8ClampedArray();
@@ -2707,7 +2703,7 @@
  public:
   static Local<Int8Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Int8Array* Cast(Value* obj));
+  V8_INLINE static Int8Array* Cast(Value* obj);
 
  private:
   Int8Array();
@@ -2723,7 +2719,7 @@
  public:
   static Local<Uint16Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Uint16Array* Cast(Value* obj));
+  V8_INLINE static Uint16Array* Cast(Value* obj);
 
  private:
   Uint16Array();
@@ -2739,7 +2735,7 @@
  public:
   static Local<Int16Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Int16Array* Cast(Value* obj));
+  V8_INLINE static Int16Array* Cast(Value* obj);
 
  private:
   Int16Array();
@@ -2755,7 +2751,7 @@
  public:
   static Local<Uint32Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Uint32Array* Cast(Value* obj));
+  V8_INLINE static Uint32Array* Cast(Value* obj);
 
  private:
   Uint32Array();
@@ -2771,7 +2767,7 @@
  public:
   static Local<Int32Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Int32Array* Cast(Value* obj));
+  V8_INLINE static Int32Array* Cast(Value* obj);
 
  private:
   Int32Array();
@@ -2787,7 +2783,7 @@
  public:
   static Local<Float32Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Float32Array* Cast(Value* obj));
+  V8_INLINE static Float32Array* Cast(Value* obj);
 
  private:
   Float32Array();
@@ -2803,7 +2799,7 @@
  public:
   static Local<Float64Array> New(Handle<ArrayBuffer> array_buffer,
                                size_t byte_offset, size_t length);
-  V8_INLINE(static Float64Array* Cast(Value* obj));
+  V8_INLINE static Float64Array* Cast(Value* obj);
 
  private:
   Float64Array();
@@ -2819,7 +2815,7 @@
  public:
   static Local<DataView> New(Handle<ArrayBuffer> array_buffer,
                              size_t byte_offset, size_t length);
-  V8_INLINE(static DataView* Cast(Value* obj));
+  V8_INLINE static DataView* Cast(Value* obj);
 
  private:
   DataView();
@@ -2844,7 +2840,7 @@
    */
   double ValueOf() const;
 
-  V8_INLINE(static Date* Cast(v8::Value* obj));
+  V8_INLINE static Date* Cast(v8::Value* obj);
 
   /**
    * Notification that the embedder has changed the time zone,
@@ -2881,7 +2877,7 @@
    */
   double ValueOf() const;
 
-  V8_INLINE(static NumberObject* Cast(v8::Value* obj));
+  V8_INLINE static NumberObject* Cast(v8::Value* obj);
 
  private:
   static void CheckCast(v8::Value* obj);
@@ -2904,7 +2900,7 @@
    */
   bool ValueOf() const;
 
-  V8_INLINE(static BooleanObject* Cast(v8::Value* obj));
+  V8_INLINE static BooleanObject* Cast(v8::Value* obj);
 
  private:
   static void CheckCast(v8::Value* obj);
@@ -2927,7 +2923,7 @@
    */
   Local<String> ValueOf() const;
 
-  V8_INLINE(static StringObject* Cast(v8::Value* obj));
+  V8_INLINE static StringObject* Cast(v8::Value* obj);
 
  private:
   static void CheckCast(v8::Value* obj);
@@ -2952,7 +2948,7 @@
    */
   Local<Symbol> ValueOf() const;
 
-  V8_INLINE(static SymbolObject* Cast(v8::Value* obj));
+  V8_INLINE static SymbolObject* Cast(v8::Value* obj);
 
  private:
   static void CheckCast(v8::Value* obj);
@@ -2998,7 +2994,7 @@
    */
   Flags GetFlags() const;
 
-  V8_INLINE(static RegExp* Cast(v8::Value* obj));
+  V8_INLINE static RegExp* Cast(v8::Value* obj);
 
  private:
   static void CheckCast(v8::Value* obj);
@@ -3012,7 +3008,7 @@
 class V8_EXPORT External : public Value {
  public:
   static Local<External> New(void* value);
-  V8_INLINE(static External* Cast(Value* obj));
+  V8_INLINE static External* Cast(Value* obj);
   void* Value() const;
  private:
   static void CheckCast(v8::Value* obj);
@@ -3030,7 +3026,7 @@
   /** Adds a property to each instance created by this template.*/
   void Set(Handle<String> name, Handle<Data> value,
            PropertyAttribute attributes = None);
-  V8_INLINE(void Set(const char* name, Handle<Data> value));
+  V8_INLINE void Set(const char* name, Handle<Data> value);
 
   void SetAccessorProperty(
      Local<String> name,
@@ -3707,7 +3703,7 @@
  */
 class V8_EXPORT DeclareExtension {
  public:
-  V8_INLINE(DeclareExtension(Extension* extension)) {
+  V8_INLINE DeclareExtension(Extension* extension) {
     RegisterExtension(extension);
   }
 };
@@ -3721,10 +3717,10 @@
 Handle<Boolean> V8_EXPORT True();
 Handle<Boolean> V8_EXPORT False();
 
-V8_INLINE(Handle<Primitive> Undefined(Isolate* isolate));
-V8_INLINE(Handle<Primitive> Null(Isolate* isolate));
-V8_INLINE(Handle<Boolean> True(Isolate* isolate));
-V8_INLINE(Handle<Boolean> False(Isolate* isolate));
+V8_INLINE Handle<Primitive> Undefined(Isolate* isolate);
+V8_INLINE Handle<Primitive> Null(Isolate* isolate);
+V8_INLINE Handle<Boolean> True(Isolate* isolate);
+V8_INLINE Handle<Boolean> False(Isolate* isolate);
 
 
 /**
@@ -3982,13 +3978,13 @@
   /**
    * Associate embedder-specific data with the isolate
    */
-  V8_INLINE(void SetData(void* data));
+  V8_INLINE void SetData(void* data);
 
   /**
    * Retrieve embedder-specific data from the isolate.
    * Returns NULL if SetData has never been called.
    */
-  V8_INLINE(void* GetData());
+  V8_INLINE void* GetData();
 
   /**
    * Get statistics about the heap memory usage.
@@ -4260,7 +4256,7 @@
 class V8_EXPORT AssertNoGCScope {
 #ifndef DEBUG
   // TODO(yangguo): remove isolate argument.
-  V8_INLINE(AssertNoGCScope(Isolate* isolate)) { }
+  V8_INLINE AssertNoGCScope(Isolate* isolate) {}
 #else
   AssertNoGCScope(Isolate* isolate);
   ~AssertNoGCScope();
@@ -4963,7 +4959,7 @@
    * previous call to SetEmbedderData with the same index. Note that index 0
    * currently has a special meaning for Chrome's debugger.
    */
-  V8_INLINE(Local<Value> GetEmbedderData(int index));
+  V8_INLINE Local<Value> GetEmbedderData(int index);
 
   /**
    * Sets the embedder data with the given index, growing the data as
@@ -4978,7 +4974,7 @@
    * SetAlignedPointerInEmbedderData with the same index. Note that index 0
    * currently has a special meaning for Chrome's debugger.
    */
-  V8_INLINE(void* GetAlignedPointerFromEmbedderData(int index));
+  V8_INLINE void* GetAlignedPointerFromEmbedderData(int index);
 
   /**
    * Sets a 2-byte-aligned native pointer in the embedder data with the given
@@ -5021,15 +5017,15 @@
    */
   class Scope {
    public:
-    explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) {
+    explicit V8_INLINE Scope(Handle<Context> context) : context_(context) {
       context_->Enter();
     }
     // TODO(dcarney): deprecate
-    V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT
+    V8_INLINE Scope(Isolate* isolate, Persistent<Context>& context) // NOLINT
     : context_(Handle<Context>::New(isolate, context)) {
       context_->Enter();
     }
-    V8_INLINE(~Scope()) { context_->Exit(); }
+    V8_INLINE ~Scope() { context_->Exit(); }
 
    private:
     Handle<Context> context_;
@@ -5127,7 +5123,7 @@
   /**
    * Initialize Unlocker for a given Isolate.
    */
-  V8_INLINE(explicit Unlocker(Isolate* isolate)) { Initialize(isolate); }
+  V8_INLINE explicit Unlocker(Isolate* isolate) { Initialize(isolate); }
 
   /** Deprecated. Use Isolate version instead. */
   V8_DEPRECATED(Unlocker());
@@ -5145,7 +5141,7 @@
   /**
    * Initialize Locker for a given Isolate.
    */
-  V8_INLINE(explicit Locker(Isolate* isolate)) { Initialize(isolate); }
+  V8_INLINE explicit Locker(Isolate* isolate) { Initialize(isolate); }
 
   /** Deprecated. Use Isolate version instead. */
   V8_DEPRECATED(Locker());
@@ -5274,7 +5270,7 @@
 template <size_t ptr_size> struct SmiTagging;
 
 template<int kSmiShiftSize>
-V8_INLINE(internal::Object* IntToSmi(int value)) {
+V8_INLINE internal::Object* IntToSmi(int value) {
   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
   intptr_t tagged_value =
       (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
@@ -5285,15 +5281,15 @@
 template <> struct SmiTagging<4> {
   static const int kSmiShiftSize = 0;
   static const int kSmiValueSize = 31;
-  V8_INLINE(static int SmiToInt(internal::Object* value)) {
+  V8_INLINE static int SmiToInt(internal::Object* value) {
     int shift_bits = kSmiTagSize + kSmiShiftSize;
     // Throw away top 32 bits and shift down (requires >> to be sign extending).
     return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits;
   }
-  V8_INLINE(static internal::Object* IntToSmi(int value)) {
+  V8_INLINE static internal::Object* IntToSmi(int value) {
     return internal::IntToSmi<kSmiShiftSize>(value);
   }
-  V8_INLINE(static bool IsValidSmi(intptr_t value)) {
+  V8_INLINE static bool IsValidSmi(intptr_t value) {
     // To be representable as an tagged small integer, the two
     // most-significant bits of 'value' must be either 00 or 11 due to
     // sign-extension. To check this we add 01 to the two
@@ -5313,15 +5309,15 @@
 template <> struct SmiTagging<8> {
   static const int kSmiShiftSize = 31;
   static const int kSmiValueSize = 32;
-  V8_INLINE(static int SmiToInt(internal::Object* value)) {
+  V8_INLINE static int SmiToInt(internal::Object* value) {
     int shift_bits = kSmiTagSize + kSmiShiftSize;
     // Shift down and throw away top 32 bits.
     return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits);
   }
-  V8_INLINE(static internal::Object* IntToSmi(int value)) {
+  V8_INLINE static internal::Object* IntToSmi(int value) {
     return internal::IntToSmi<kSmiShiftSize>(value);
   }
-  V8_INLINE(static bool IsValidSmi(intptr_t value)) {
+  V8_INLINE static bool IsValidSmi(intptr_t value) {
     // To be representable as a long smi, the value must be a 32-bit integer.
     return (value == static_cast<int32_t>(value));
   }
@@ -5330,8 +5326,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; }
+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
@@ -5383,94 +5379,93 @@
   static const int kNullOddballKind = 3;
 
   static void CheckInitializedImpl(v8::Isolate* isolate);
-  V8_INLINE(static void CheckInitialized(v8::Isolate* isolate)) {
+  V8_INLINE static void CheckInitialized(v8::Isolate* isolate) {
 #ifdef V8_ENABLE_CHECKS
     CheckInitializedImpl(isolate);
 #endif
   }
 
-  V8_INLINE(static bool HasHeapObjectTag(internal::Object* value)) {
+  V8_INLINE static bool HasHeapObjectTag(internal::Object* value) {
     return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) ==
             kHeapObjectTag);
   }
 
-  V8_INLINE(static int SmiValue(internal::Object* value)) {
+  V8_INLINE static int SmiValue(internal::Object* value) {
     return PlatformSmiTagging::SmiToInt(value);
   }
 
-  V8_INLINE(static internal::Object* IntToSmi(int value)) {
+  V8_INLINE static internal::Object* IntToSmi(int value) {
     return PlatformSmiTagging::IntToSmi(value);
   }
 
-  V8_INLINE(static bool IsValidSmi(intptr_t value)) {
+  V8_INLINE static bool IsValidSmi(intptr_t value) {
     return PlatformSmiTagging::IsValidSmi(value);
   }
 
-  V8_INLINE(static int GetInstanceType(internal::Object* obj)) {
+  V8_INLINE static int GetInstanceType(internal::Object* obj) {
     typedef internal::Object O;
     O* map = ReadField<O*>(obj, kHeapObjectMapOffset);
     return ReadField<uint8_t>(map, kMapInstanceTypeOffset);
   }
 
-  V8_INLINE(static int GetOddballKind(internal::Object* obj)) {
+  V8_INLINE static int GetOddballKind(internal::Object* obj) {
     typedef internal::Object O;
     return SmiValue(ReadField<O*>(obj, kOddballKindOffset));
   }
 
-  V8_INLINE(static bool IsExternalTwoByteString(int instance_type)) {
+  V8_INLINE static bool IsExternalTwoByteString(int instance_type) {
     int representation = (instance_type & kFullStringRepresentationMask);
     return representation == kExternalTwoByteRepresentationTag;
   }
 
-  V8_INLINE(static uint8_t GetNodeFlag(internal::Object** obj, int shift)) {
+  V8_INLINE static uint8_t GetNodeFlag(internal::Object** obj, int shift) {
       uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
       return *addr & static_cast<uint8_t>(1U << shift);
   }
 
-  V8_INLINE(static void UpdateNodeFlag(internal::Object** obj,
-                                       bool value, int shift)) {
+  V8_INLINE static void UpdateNodeFlag(internal::Object** obj,
+                                       bool value, int shift) {
       uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
       uint8_t mask = static_cast<uint8_t>(1 << shift);
       *addr = static_cast<uint8_t>((*addr & ~mask) | (value << shift));
   }
 
-  V8_INLINE(static uint8_t GetNodeState(internal::Object** obj)) {
+  V8_INLINE static uint8_t GetNodeState(internal::Object** obj) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
     return *addr & kNodeStateMask;
   }
 
-  V8_INLINE(static void UpdateNodeState(internal::Object** obj,
-                                        uint8_t value)) {
+  V8_INLINE static void UpdateNodeState(internal::Object** obj,
+                                        uint8_t value) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
     *addr = static_cast<uint8_t>((*addr & ~kNodeStateMask) | value);
   }
 
-  V8_INLINE(static void SetEmbedderData(v8::Isolate* isolate, void* data)) {
+  V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, void* data) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
         kIsolateEmbedderDataOffset;
     *reinterpret_cast<void**>(addr) = data;
   }
 
-  V8_INLINE(static void* GetEmbedderData(v8::Isolate* isolate)) {
+  V8_INLINE static void* GetEmbedderData(v8::Isolate* isolate) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
         kIsolateEmbedderDataOffset;
     return *reinterpret_cast<void**>(addr);
   }
 
-  V8_INLINE(static internal::Object** GetRoot(v8::Isolate* isolate,
-                                              int index)) {
+  V8_INLINE static internal::Object** GetRoot(v8::Isolate* isolate,
+                                              int index) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateRootsOffset;
     return reinterpret_cast<internal::Object**>(addr + index * kApiPointerSize);
   }
 
-  template <typename T>
-  V8_INLINE(static T ReadField(Object* ptr, int offset)) {
+  template <typename T> V8_INLINE static T ReadField(Object* ptr, int offset) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag;
     return *reinterpret_cast<T*>(addr);
   }
 
   template <typename T>
-  V8_INLINE(static T ReadEmbedderData(Context* context, int index)) {
+  V8_INLINE static T ReadEmbedderData(Context* context, int index) {
     typedef internal::Object O;
     typedef internal::Internals I;
     O* ctx = *reinterpret_cast<O**>(context);
@@ -5482,13 +5477,13 @@
     return I::ReadField<T>(embedder_data, value_offset);
   }
 
-  V8_INLINE(static bool CanCastToHeapObject(void* o)) { return false; }
-  V8_INLINE(static bool CanCastToHeapObject(Context* o)) { return true; }
-  V8_INLINE(static bool CanCastToHeapObject(String* o)) { return true; }
-  V8_INLINE(static bool CanCastToHeapObject(Object* o)) { return true; }
-  V8_INLINE(static bool CanCastToHeapObject(Message* o)) { return true; }
-  V8_INLINE(static bool CanCastToHeapObject(StackTrace* o)) { return true; }
-  V8_INLINE(static bool CanCastToHeapObject(StackFrame* o)) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(void* o) { return false; }
+  V8_INLINE static bool CanCastToHeapObject(Context* o) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(String* o) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(Object* o) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(Message* o) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(StackTrace* o) { return true; }
+  V8_INLINE static bool CanCastToHeapObject(StackFrame* o) { return true; }
 };
 
 }  // namespace internal
diff --git a/include/v8config.h b/include/v8config.h
index 0993a9f..6fe5c5a 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -295,23 +295,27 @@
 // Helper macros
 
 // A macro used to make better inlining. Don't bother for debug builds.
+// Use like:
+//   V8_INLINE int GetZero() { return 0; }
 #if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
-# define V8_INLINE(declarator) inline __attribute__((always_inline)) declarator
+# define V8_INLINE inline __attribute__((always_inline))
 #elif !defined(DEBUG) && V8_HAS___FORCEINLINE
-# define V8_INLINE(declarator) __forceinline declarator
+# define V8_INLINE __forceinline
 #else
-# define V8_INLINE(declarator) inline declarator
+# define V8_INLINE inline
 #endif
 
 
 // A macro used to tell the compiler to never inline a particular function.
 // Don't bother for debug builds.
+// Use like:
+//   V8_NOINLINE int GetMinusOne() { return -1; }
 #if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
-# define V8_NOINLINE(declarator) __attribute__((noinline)) declarator
+# define V8_NOINLINE __attribute__((noinline))
 #elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
-# define V8_NOINLINE(declarator) __declspec(noinline) declarator
+# define V8_NOINLINE __declspec(noinline)
 #else
-# define V8_NOINLINE(declarator) declarator
+# define V8_NOINLINE /* NOT SUPPORTED */
 #endif
 
 
diff --git a/src/accessors.cc b/src/accessors.cc
index f8cb0c8..669c02b 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -113,7 +113,7 @@
   // object does not have a 'length' property.  Calling SetProperty
   // causes an infinite loop.
   if (!object->IsJSArray()) {
-    return object->SetLocalPropertyIgnoreAttributes(
+    return object->SetLocalPropertyIgnoreAttributesTrampoline(
         isolate->heap()->length_string(), value, NONE);
   }
 
@@ -531,9 +531,8 @@
   if (function_raw == NULL) return heap->undefined_value();
   if (!function_raw->should_have_prototype()) {
     // Since we hit this accessor, object will have no prototype property.
-    return object->SetLocalPropertyIgnoreAttributes(heap->prototype_string(),
-                                                    value_raw,
-                                                    NONE);
+    return object->SetLocalPropertyIgnoreAttributesTrampoline(
+        heap->prototype_string(), value_raw, NONE);
   }
 
   HandleScope scope(isolate);
diff --git a/src/api.cc b/src/api.cc
index f75a851..71a8f4a 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -403,9 +403,6 @@
   kSnapshotContext,
   kLibraries,
   kExperimentalLibraries,
-#if defined(V8_I18N_SUPPORT)
-  kI18NExtension,
-#endif
   kCompressedStartupDataCount
 };
 
@@ -446,17 +443,6 @@
       exp_libraries_source.length();
   compressed_data[kExperimentalLibraries].raw_size =
       i::ExperimentalNatives::GetRawScriptsSize();
-
-#if defined(V8_I18N_SUPPORT)
-  i::Vector<const ii:byte> i18n_extension_source =
-      i::I18NNatives::GetScriptsSource();
-  compressed_data[kI18NExtension].data =
-      reinterpret_cast<const char*>(i18n_extension_source.start());
-  compressed_data[kI18NExtension].compressed_size =
-      i18n_extension_source.length();
-  compressed_data[kI18NExtension].raw_size =
-      i::I18NNatives::GetRawScriptsSize();
-#endif
 #endif
 }
 
@@ -486,15 +472,6 @@
       decompressed_data[kExperimentalLibraries].data,
       decompressed_data[kExperimentalLibraries].raw_size);
   i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
-
-#if defined(V8_I18N_SUPPORT)
-  ASSERT_EQ(i::I18NNatives::GetRawScriptsSize(),
-            decompressed_data[kI18NExtension].raw_size);
-  i::Vector<const char> i18n_extension_source(
-      decompressed_data[kI18NExtension].data,
-      decompressed_data[kI18NExtension].raw_size);
-  i::I18NNatives::SetRawScriptsSource(i18n_extension_source);
-#endif
 #endif
 }
 
diff --git a/src/arguments.h b/src/arguments.h
index 169528b..c1db98b 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -175,6 +175,10 @@
   static const int kArgsLength = T::kArgsLength;
   static const int kThisIndex = T::kThisIndex;
   static const int kHolderIndex = T::kHolderIndex;
+  static const int kDataIndex = T::kDataIndex;
+  static const int kReturnValueDefaultValueIndex =
+      T::kReturnValueDefaultValueIndex;
+  static const int kIsolateIndex = T::kIsolateIndex;
 
   PropertyCallbackArguments(Isolate* isolate,
                             Object* data,
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index ed8639c..bd8b061 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -39,6 +39,7 @@
 #if V8_TARGET_ARCH_ARM
 
 #include "arm/assembler-arm-inl.h"
+#include "macro-assembler.h"
 #include "serialize.h"
 
 namespace v8 {
@@ -775,9 +776,9 @@
 
 int Assembler::target_at(int pos)  {
   Instr instr = instr_at(pos);
-  if ((instr & ~kImm24Mask) == 0) {
-    // Emitted label constant, not part of a branch.
-    return instr - (Code::kHeaderSize - kHeapObjectTag);
+  if (is_uint24(instr)) {
+    // Emitted link to a label, not part of a branch.
+    return instr;
   }
   ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
   int imm26 = ((instr & kImm24Mask) << 8) >> 6;
@@ -792,11 +793,72 @@
 
 void Assembler::target_at_put(int pos, int target_pos) {
   Instr instr = instr_at(pos);
-  if ((instr & ~kImm24Mask) == 0) {
+  if (is_uint24(instr)) {
     ASSERT(target_pos == pos || target_pos >= 0);
-    // Emitted label constant, not part of a branch.
-    // Make label relative to Code* of generated Code object.
-    instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
+    // Emitted link to a label, not part of a branch.
+    // Load the position of the label relative to the generated code object
+    // pointer in a register.
+
+    // Here are the instructions we need to emit:
+    //   For ARMv7: target24 => target16_1:target16_0
+    //      movw dst, #target16_0
+    //      movt dst, #target16_1
+    //   For ARMv6: target24 => target8_2:target8_1:target8_0
+    //      mov dst, #target8_0
+    //      orr dst, dst, #target8_1 << 8
+    //      orr dst, dst, #target8_2 << 16
+
+    // We extract the destination register from the emitted nop instruction.
+    Register dst = Register::from_code(
+        Instruction::RmValue(instr_at(pos + kInstrSize)));
+    ASSERT(IsNop(instr_at(pos + kInstrSize), dst.code()));
+    uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
+    ASSERT(is_uint24(target24));
+    if (is_uint8(target24)) {
+      // If the target fits in a byte then only patch with a mov
+      // instruction.
+      CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
+                          1,
+                          CodePatcher::DONT_FLUSH);
+      patcher.masm()->mov(dst, Operand(target24));
+    } else {
+      uint16_t target16_0 = target24 & kImm16Mask;
+      uint16_t target16_1 = target24 >> 16;
+      if (CpuFeatures::IsSupported(ARMv7)) {
+        // Patch with movw/movt.
+        if (target16_1 == 0) {
+          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
+                              1,
+                              CodePatcher::DONT_FLUSH);
+          patcher.masm()->movw(dst, target16_0);
+        } else {
+          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
+                              2,
+                              CodePatcher::DONT_FLUSH);
+          patcher.masm()->movw(dst, target16_0);
+          patcher.masm()->movt(dst, target16_1);
+        }
+      } else {
+        // Patch with a sequence of mov/orr/orr instructions.
+        uint8_t target8_0 = target16_0 & kImm8Mask;
+        uint8_t target8_1 = target16_0 >> 8;
+        uint8_t target8_2 = target16_1 & kImm8Mask;
+        if (target8_2 == 0) {
+          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
+                              2,
+                              CodePatcher::DONT_FLUSH);
+          patcher.masm()->mov(dst, Operand(target8_0));
+          patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
+        } else {
+          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
+                              3,
+                              CodePatcher::DONT_FLUSH);
+          patcher.masm()->mov(dst, Operand(target8_0));
+          patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
+          patcher.masm()->orr(dst, dst, Operand(target8_2 << 16));
+        }
+      }
+    }
     return;
   }
   int imm26 = target_pos - (pos + kPcLoadDelta);
@@ -1229,21 +1291,6 @@
 }
 
 
-void Assembler::label_at_put(Label* L, int at_offset) {
-  int target_pos;
-  ASSERT(!L->is_bound());
-  if (L->is_linked()) {
-    // Point to previous instruction that uses the link.
-    target_pos = L->pos();
-  } else {
-    // First entry of the link chain points to itself.
-    target_pos = at_offset;
-  }
-  L->link_to(at_offset);
-  instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
-}
-
-
 // Branch instructions.
 void Assembler::b(int branch_offset, Condition cond) {
   ASSERT((branch_offset & 3) == 0);
@@ -1386,6 +1433,45 @@
 }
 
 
+void Assembler::mov_label_offset(Register dst, Label* label) {
+  if (label->is_bound()) {
+    mov(dst, Operand(label->pos() + (Code::kHeaderSize - kHeapObjectTag)));
+  } else {
+    // Emit the link to the label in the code stream followed by extra nop
+    // instructions.
+    // If the label is not linked, then start a new link chain by linking it to
+    // itself, emitting pc_offset().
+    int link = label->is_linked() ? label->pos() : pc_offset();
+    label->link_to(pc_offset());
+
+    // When the label is bound, these instructions will be patched with a
+    // sequence of movw/movt or mov/orr/orr instructions. They will load the
+    // destination register with the position of the label from the beginning
+    // of the code.
+    //
+    // The link will be extracted from the first instruction and the destination
+    // register from the second.
+    //   For ARMv7:
+    //      link
+    //      mov dst, dst
+    //   For ARMv6:
+    //      link
+    //      mov dst, dst
+    //      mov dst, dst
+    //
+    // When the label gets bound: target_at extracts the link and target_at_put
+    // patches the instructions.
+    ASSERT(is_uint24(link));
+    BlockConstPoolScope block_const_pool(this);
+    emit(link);
+    nop(dst.code());
+    if (!CpuFeatures::IsSupported(ARMv7)) {
+      nop(dst.code());
+    }
+  }
+}
+
+
 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
   ASSERT(immediate < 0x10000);
   // May use movw if supported, but on unsupported platforms will try to use
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index f647848..866b1c9 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -748,10 +748,6 @@
   // Manages the jump elimination optimization if the second parameter is true.
   int branch_offset(Label* L, bool jump_elimination_allowed);
 
-  // Puts a labels target address at the given position.
-  // The high 8 bits are set to zero.
-  void label_at_put(Label* L, int at_offset);
-
   // Return the address in the constant pool of the code target address used by
   // the branch/call instruction at pc, or the object in a mov.
   INLINE(static Address target_pointer_address_at(Address pc));
@@ -903,6 +899,10 @@
     mov(dst, Operand(src), s, cond);
   }
 
+  // Load the position of the label relative to the generated code object
+  // pointer in a register.
+  void mov_label_offset(Register dst, Label* label);
+
   // ARMv7 instructions for loading a 32 bit immediate in two instructions.
   // This may actually emit a different mov instruction, but on an ARMv7 it
   // is guaranteed to only emit one instruction.
@@ -1561,7 +1561,6 @@
   void RecordRelocInfo(double data);
   void RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo);
 
-  friend class RegExpMacroAssemblerARM;
   friend class RelocInfo;
   friend class CodePatcher;
   friend class BlockConstPoolScope;
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index e0c37e1..f60e1f8 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -291,68 +291,55 @@
 }
 
 
+static void CallRuntimePassFunction(MacroAssembler* masm,
+                                    Runtime::FunctionId function_id) {
+  FrameScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function onto the stack.
+  __ push(r1);
+  // Push call kind information.
+  __ push(r5);
+  // Function is also the parameter to the runtime call.
+  __ push(r1);
+
+  __ CallRuntime(function_id, 1);
+  // Restore call kind information.
+  __ pop(r5);
+  // Restore receiver.
+  __ pop(r1);
+}
+
+
 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
   __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
   __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
   __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ mov(pc, r2);
-}
-
-
-void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
-  GenerateTailCallToSharedCode(masm);
-}
-
-
-void Builtins::Generate_InstallRecompiledCode(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(r1);
-    // Push call kind information.
-    __ push(r5);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(r1);
-    __ CallRuntime(Runtime::kInstallRecompiledCode, 1);
-    // Calculate the entry point.
-    __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Restore call kind information.
-    __ pop(r5);
-    // Restore saved function.
-    __ pop(r1);
-
-    // Tear down internal frame.
-  }
-
-  // Do a tail-call of the compiled function.
   __ Jump(r2);
 }
 
 
+void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+  // Checking whether the queued function is ready for install is optional,
+  // since we come across interrupts and stack checks elsewhere.  However,
+  // not checking may delay installing ready functions, and always checking
+  // would be quite expensive.  A good compromise is to first check against
+  // stack limit as a cue for an interrupt signal.
+  Label ok;
+  __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+  __ cmp(sp, Operand(ip));
+  __ b(hs, &ok);
+
+  CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode);
+  // Tail call to returned code.
+  __ add(r0, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ Jump(r0);
+
+  __ bind(&ok);
+  GenerateTailCallToSharedCode(masm);
+}
+
+
 void Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(r1);
-    // Push call kind information.
-    __ push(r5);
-
-    __ push(r1);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kConcurrentRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(r5);
-    // Restore receiver.
-    __ pop(r1);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile);
   GenerateTailCallToSharedCode(masm);
 }
 
@@ -795,59 +782,17 @@
 
 
 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(r1);
-    // Push call kind information.
-    __ push(r5);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(r1);
-    __ CallRuntime(Runtime::kLazyCompile, 1);
-    // Calculate the entry point.
-    __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Restore call kind information.
-    __ pop(r5);
-    // Restore saved function.
-    __ pop(r1);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyCompile);
   // Do a tail-call of the compiled function.
+  __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ Jump(r2);
 }
 
 
 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(r1);
-    // Push call kind information.
-    __ push(r5);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(r1);
-    __ CallRuntime(Runtime::kLazyRecompile, 1);
-    // Calculate the entry point.
-    __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Restore call kind information.
-    __ pop(r5);
-    // Restore saved function.
-    __ pop(r1);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyRecompile);
   // Do a tail-call of the compiled function.
+  __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ Jump(r2);
 }
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 3a1d128..cd1809f 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -5790,7 +5790,6 @@
   __ b(lt, &done);
 
   // Check the number to string cache.
-  Label not_cached;
   __ bind(&not_string);
   // Puts the cached result into scratch1.
   NumberToStringStub::GenerateLookupNumberStringCache(masm,
@@ -5799,26 +5798,9 @@
                                                       scratch2,
                                                       scratch3,
                                                       scratch4,
-                                                      &not_cached);
+                                                      slow);
   __ mov(arg, scratch1);
   __ str(arg, MemOperand(sp, stack_offset));
-  __ jmp(&done);
-
-  // Check if the argument is a safe string wrapper.
-  __ bind(&not_cached);
-  __ JumpIfSmi(arg, slow);
-  __ CompareObjectType(
-      arg, scratch1, scratch2, JS_VALUE_TYPE);  // map -> scratch1.
-  __ b(ne, slow);
-  __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
-  __ and_(scratch2,
-          scratch2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
-  __ cmp(scratch2,
-         Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
-  __ b(ne, slow);
-  __ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset));
-  __ str(arg, MemOperand(sp, stack_offset));
-
   __ bind(&done);
 }
 
@@ -6855,90 +6837,128 @@
 
 
 template<class T>
-static void CreateArrayDispatch(MacroAssembler* masm) {
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmp(r3, Operand(kind));
-    __ b(ne, &next);
-    T stub(kind);
+static void CreateArrayDispatch(MacroAssembler* masm,
+                                AllocationSiteOverrideMode mode) {
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    T stub(GetInitialFastElementsKind(),
+           CONTEXT_CHECK_REQUIRED,
+           mode);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmp(r3, Operand(kind));
+      __ b(ne, &next);
+      T stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
-static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
-  // r2 - type info cell
-  // r3 - kind
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
+                                           AllocationSiteOverrideMode mode) {
+  // r2 - type info cell (if mode != DISABLE_ALLOCATION_SITES)
+  // r3 - kind (if mode != DISABLE_ALLOCATION_SITES)
   // r0 - number of arguments
   // r1 - constructor?
   // sp[0] - last argument
-  ASSERT(FAST_SMI_ELEMENTS == 0);
-  ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
-  ASSERT(FAST_ELEMENTS == 2);
-  ASSERT(FAST_HOLEY_ELEMENTS == 3);
-  ASSERT(FAST_DOUBLE_ELEMENTS == 4);
-  ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
-
-  // is the low bit set? If so, we are holey and that is good.
-  __ tst(r3, Operand(1));
   Label normal_sequence;
-  __ b(ne, &normal_sequence);
+  if (mode == DONT_OVERRIDE) {
+    ASSERT(FAST_SMI_ELEMENTS == 0);
+    ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+    ASSERT(FAST_ELEMENTS == 2);
+    ASSERT(FAST_HOLEY_ELEMENTS == 3);
+    ASSERT(FAST_DOUBLE_ELEMENTS == 4);
+    ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
+
+    // is the low bit set? If so, we are holey and that is good.
+    __ tst(r3, Operand(1));
+    __ b(ne, &normal_sequence);
+  }
 
   // look at the first argument
   __ ldr(r5, MemOperand(sp, 0));
   __ cmp(r5, Operand::Zero());
   __ b(eq, &normal_sequence);
 
-  // We are going to create a holey array, but our kind is non-holey.
-  // Fix kind and retry (only if we have an allocation site in the cell).
-  __ add(r3, r3, Operand(1));
-  __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
-  __ b(eq, &normal_sequence);
-  __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
-  __ ldr(r5, FieldMemOperand(r5, 0));
-  __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
-  __ b(ne, &normal_sequence);
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    ElementsKind initial = GetInitialFastElementsKind();
+    ElementsKind holey_initial = GetHoleyElementsKind(initial);
 
-  // Save the resulting elements kind in type info
-  __ SmiTag(r3);
-  __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
-  __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
-  __ SmiUntag(r3);
+    ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+                                                  CONTEXT_CHECK_REQUIRED,
+                                                  DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub_holey);
 
-  __ bind(&normal_sequence);
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmp(r3, Operand(kind));
-    __ b(ne, &next);
-    ArraySingleArgumentConstructorStub stub(kind);
+    __ bind(&normal_sequence);
+    ArraySingleArgumentConstructorStub stub(initial,
+                                            CONTEXT_CHECK_REQUIRED,
+                                            DISABLE_ALLOCATION_SITES);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    // We are going to create a holey array, but our kind is non-holey.
+    // Fix kind and retry (only if we have an allocation site in the cell).
+    __ add(r3, r3, Operand(1));
+    __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    if (FLAG_debug_code) {
+      __ ldr(r5, FieldMemOperand(r5, 0));
+      __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
+      __ Assert(eq, kExpectedAllocationSiteInCell);
+      __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
+    }
+
+    // Save the resulting elements kind in type info
+    __ SmiTag(r3);
+    __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
+    __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
+    __ SmiUntag(r3);
+
+    __ bind(&normal_sequence);
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmp(r3, Operand(kind));
+      __ b(ne, &next);
+      ArraySingleArgumentConstructorStub stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
 template<class T>
 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
+  ElementsKind initial_kind = GetInitialFastElementsKind();
+  ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
+
   int to_index = GetSequenceIndexFromFastElementsKind(
       TERMINAL_FAST_ELEMENTS_KIND);
   for (int i = 0; i <= to_index; ++i) {
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
-    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
+        (!FLAG_track_allocation_sites &&
+         (kind == initial_kind || kind == initial_holey_kind))) {
       T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
       stub1.GetCode(isolate)->set_is_pregenerated(true);
     }
@@ -6971,6 +6991,34 @@
 }
 
 
+void ArrayConstructorStub::GenerateDispatchToArrayStub(
+    MacroAssembler* masm,
+    AllocationSiteOverrideMode mode) {
+  if (argument_count_ == ANY) {
+    Label not_zero_case, not_one_case;
+    __ tst(r0, r0);
+    __ b(ne, &not_zero_case);
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+
+    __ bind(&not_zero_case);
+    __ cmp(r0, Operand(1));
+    __ b(gt, &not_one_case);
+    CreateArrayDispatchOneArgument(masm, mode);
+
+    __ bind(&not_one_case);
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else if (argument_count_ == NONE) {
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+  } else if (argument_count_ == ONE) {
+    CreateArrayDispatchOneArgument(masm, mode);
+  } else if (argument_count_ == MORE_THAN_ONE) {
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r0 : argc (only if argument_count_ == ANY)
@@ -7002,50 +7050,24 @@
     __ bind(&okay_here);
   }
 
-  Label no_info, switch_ready;
+  Label no_info;
   // Get the elements kind and case on that.
   __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
   __ b(eq, &no_info);
   __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
 
-  // The type cell may have undefined in its value.
-  __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
-  __ b(eq, &no_info);
-
-  // The type cell has either an AllocationSite or a JSFunction
+  // If the type cell is undefined, or contains anything other than an
+  // AllocationSite, call an array constructor that doesn't use AllocationSites.
   __ ldr(r4, FieldMemOperand(r3, 0));
   __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
   __ b(ne, &no_info);
 
   __ ldr(r3, FieldMemOperand(r3, AllocationSite::kTransitionInfoOffset));
   __ SmiUntag(r3);
-  __ jmp(&switch_ready);
+  GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
+
   __ bind(&no_info);
-  __ mov(r3, Operand(GetInitialFastElementsKind()));
-  __ bind(&switch_ready);
-
-  if (argument_count_ == ANY) {
-    Label not_zero_case, not_one_case;
-    __ tst(r0, r0);
-    __ b(ne, &not_zero_case);
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-
-    __ bind(&not_zero_case);
-    __ cmp(r0, Operand(1));
-    __ b(gt, &not_one_case);
-    CreateArrayDispatchOneArgument(masm);
-
-    __ bind(&not_one_case);
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else if (argument_count_ == NONE) {
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-  } else if (argument_count_ == ONE) {
-    CreateArrayDispatchOneArgument(masm);
-  } else if (argument_count_ == MORE_THAN_ONE) {
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else {
-    UNREACHABLE();
-  }
+  GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
 }
 
 
diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h
index 9bfccf8..7036139 100644
--- a/src/arm/constants-arm.h
+++ b/src/arm/constants-arm.h
@@ -220,6 +220,8 @@
   kCoprocessorMask = 15 << 8,
   kOpCodeMask = 15 << 21,  // In data-processing instructions.
   kImm24Mask  = (1 << 24) - 1,
+  kImm16Mask  = (1 << 16) - 1,
+  kImm8Mask  = (1 << 8) - 1,
   kOff12Mask  = (1 << 12) - 1,
   kOff8Mask  = (1 << 8) - 1
 };
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 28ec1a2..b6fb70b 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3007,7 +3007,7 @@
 
   VisitForAccumulatorValue(args->at(0));
 
-  Label materialize_true, materialize_false;
+  Label materialize_true, materialize_false, skip_lookup;
   Label* if_true = NULL;
   Label* if_false = NULL;
   Label* fall_through = NULL;
@@ -3019,7 +3019,7 @@
   __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ ldrb(ip, FieldMemOperand(r1, Map::kBitField2Offset));
   __ tst(ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
-  __ b(ne, if_true);
+  __ b(ne, &skip_lookup);
 
   // Check for fast case object. Generate false result for slow case object.
   __ ldr(r2, FieldMemOperand(r0, JSObject::kPropertiesOffset));
@@ -3065,6 +3065,14 @@
   __ b(ne, &loop);
 
   __ bind(&done);
+
+  // Set the bit in the map to indicate that there is no local valueOf field.
+  __ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset));
+  __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
+  __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset));
+
+  __ bind(&skip_lookup);
+
   // If a valueOf property is not found on the object check that its
   // prototype is the un-modified String prototype. If not result is false.
   __ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
@@ -3074,11 +3082,9 @@
   __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
   __ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
   __ cmp(r2, r3);
-  __ b(ne, if_false);
-
-  __ jmp(if_true);
-
   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
   context()->Plug(if_true, if_false);
 }
 
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 9695072..59a8818 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1724,9 +1724,13 @@
 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->global_object()->representation().IsTagged());
-  LOperand* global_object = UseFixed(instr->global_object(), r0);
-  LRandom* result = new(zone()) LRandom(global_object);
-  return MarkAsCall(DefineFixedDouble(result, d7), instr);
+  LOperand* global_object = UseTempRegister(instr->global_object());
+  LOperand* scratch = TempRegister();
+  LOperand* scratch2 = TempRegister();
+  LOperand* scratch3 = TempRegister();
+  LRandom* result = new(zone()) LRandom(
+      global_object, scratch, scratch2, scratch3);
+  return DefineFixedDouble(result, d7);
 }
 
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index f90f3c4..98cacac 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -1462,13 +1462,22 @@
 };
 
 
-class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
-  explicit LRandom(LOperand* global_object) {
+  LRandom(LOperand* global_object,
+          LOperand* scratch,
+          LOperand* scratch2,
+          LOperand* scratch3) {
     inputs_[0] = global_object;
+    temps_[0] = scratch;
+    temps_[1] = scratch2;
+    temps_[2] = scratch3;
   }
 
-  LOperand* global_object() { return inputs_[0]; }
+  LOperand* global_object() const { return inputs_[0]; }
+  LOperand* scratch() const { return temps_[0]; }
+  LOperand* scratch2() const { return temps_[1]; }
+  LOperand* scratch3() const { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(Random, "random")
   DECLARE_HYDROGEN_ACCESSOR(Random)
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index cf76a08..7f65023 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3891,80 +3891,64 @@
 
 
 void LCodeGen::DoRandom(LRandom* instr) {
-  class DeferredDoRandom V8_FINAL : public LDeferredCode {
-   public:
-    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
-    virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
-   private:
-    LRandom* instr_;
-  };
-
-  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
-
-  // Having marked this instruction as a call we can use any
-  // registers.
-  ASSERT(ToDoubleRegister(instr->result()).is(d7));
-  ASSERT(ToRegister(instr->global_object()).is(r0));
-
+  // Assert that the register size is indeed the size of each seed.
   static const int kSeedSize = sizeof(uint32_t);
   STATIC_ASSERT(kPointerSize == kSeedSize);
 
-  __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
+  // Load native context
+  Register global_object = ToRegister(instr->global_object());
+  Register native_context = global_object;
+  __ ldr(native_context, FieldMemOperand(
+          global_object, GlobalObject::kNativeContextOffset));
+
+  // Load state (FixedArray of the native context's random seeds)
   static const int kRandomSeedOffset =
       FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
-  __ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset));
-  // r2: FixedArray of the native context's random seeds
+  Register state = native_context;
+  __ ldr(state, FieldMemOperand(native_context, kRandomSeedOffset));
 
   // Load state[0].
-  __ ldr(r1, FieldMemOperand(r2, ByteArray::kHeaderSize));
-  __ cmp(r1, Operand::Zero());
-  __ b(eq, deferred->entry());
+  Register state0 = ToRegister(instr->scratch());
+  __ ldr(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
   // Load state[1].
-  __ ldr(r0, FieldMemOperand(r2, ByteArray::kHeaderSize + kSeedSize));
-  // r1: state[0].
-  // r0: state[1].
+  Register state1 = ToRegister(instr->scratch2());
+  __ ldr(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
-  __ and_(r3, r1, Operand(0xFFFF));
-  __ mov(r4, Operand(18273));
-  __ mul(r3, r3, r4);
-  __ add(r1, r3, Operand(r1, LSR, 16));
+  Register scratch3 = ToRegister(instr->scratch3());
+  Register scratch4 = scratch0();
+  __ and_(scratch3, state0, Operand(0xFFFF));
+  __ mov(scratch4, Operand(18273));
+  __ mul(scratch3, scratch3, scratch4);
+  __ add(state0, scratch3, Operand(state0, LSR, 16));
   // Save state[0].
-  __ str(r1, FieldMemOperand(r2, ByteArray::kHeaderSize));
+  __ str(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
 
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
-  __ and_(r3, r0, Operand(0xFFFF));
-  __ mov(r4, Operand(36969));
-  __ mul(r3, r3, r4);
-  __ add(r0, r3, Operand(r0, LSR, 16));
+  __ and_(scratch3, state1, Operand(0xFFFF));
+  __ mov(scratch4, Operand(36969));
+  __ mul(scratch3, scratch3, scratch4);
+  __ add(state1, scratch3, Operand(state1, LSR, 16));
   // Save state[1].
-  __ str(r0, FieldMemOperand(r2, ByteArray::kHeaderSize + kSeedSize));
+  __ str(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
-  __ and_(r0, r0, Operand(0x3FFFF));
-  __ add(r0, r0, Operand(r1, LSL, 14));
+  Register random = scratch4;
+  __ and_(random, state1, Operand(0x3FFFF));
+  __ add(random, random, Operand(state0, LSL, 14));
 
-  __ bind(deferred->exit());
   // 0x41300000 is the top half of 1.0 x 2^20 as a double.
   // Create this constant using mov/orr to avoid PC relative load.
-  __ mov(r1, Operand(0x41000000));
-  __ orr(r1, r1, Operand(0x300000));
+  __ mov(scratch3, Operand(0x41000000));
+  __ orr(scratch3, scratch3, Operand(0x300000));
   // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
-  __ vmov(d7, r0, r1);
+  DwVfpRegister result = ToDoubleRegister(instr->result());
+  __ vmov(result, random, scratch3);
   // Move 0x4130000000000000 to VFP.
-  __ mov(r0, Operand::Zero());
-  __ vmov(d8, r0, r1);
-  // Subtract and store the result in the heap number.
-  __ vsub(d7, d7, d8);
-}
-
-
-void LCodeGen::DoDeferredRandom(LRandom* instr) {
-  __ PrepareCallCFunction(1, scratch0());
-  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
-  // Return value is in r0.
+  __ mov(scratch4, Operand::Zero());
+  DwVfpRegister scratch5 = double_scratch0();
+  __ vmov(scratch5, scratch4, scratch3);
+  __ vsub(result, result, scratch5);
 }
 
 
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index 5826849..4b6b5ca 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -149,7 +149,6 @@
   void DoDeferredTaggedToI(LTaggedToI* instr);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
-  void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredAllocate(LAllocate* instr);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 7628f23..7df7857 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -3845,10 +3845,13 @@
 #endif
 
 
-CodePatcher::CodePatcher(byte* address, int instructions)
+CodePatcher::CodePatcher(byte* address,
+                         int instructions,
+                         FlushICache flush_cache)
     : address_(address),
       size_(instructions * Assembler::kInstrSize),
-      masm_(NULL, address, size_ + Assembler::kGap) {
+      masm_(NULL, address, size_ + Assembler::kGap),
+      flush_cache_(flush_cache) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
@@ -3858,7 +3861,9 @@
 
 CodePatcher::~CodePatcher() {
   // Indicate that code has changed.
-  CPU::FlushICache(address_, size_);
+  if (flush_cache_ == FLUSH) {
+    CPU::FlushICache(address_, size_);
+  }
 
   // Check that the code was patched as expected.
   ASSERT(masm_.pc_ == address_ + size_);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index cff9ac7..9abd5a0 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1429,7 +1429,14 @@
 // an assertion to fail.
 class CodePatcher {
  public:
-  CodePatcher(byte* address, int instructions);
+  enum FlushICache {
+    FLUSH,
+    DONT_FLUSH
+  };
+
+  CodePatcher(byte* address,
+              int instructions,
+              FlushICache flush_cache = FLUSH);
   virtual ~CodePatcher();
 
   // Macro assembler to emit code.
@@ -1449,6 +1456,7 @@
   byte* address_;  // The address of the code being patched.
   int size_;  // Number of bytes of the expected patch size.
   MacroAssembler masm_;  // Macro assembler used to generate the code.
+  FlushICache flush_cache_;  // Whether to flush the I cache after patching.
 };
 
 
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index a26aa9e..cbc34e1 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -134,7 +134,6 @@
       exit_label_() {
   ASSERT_EQ(0, registers_to_save % 2);
   __ jmp(&entry_label_);   // We'll write the entry code later.
-  EmitBacktrackConstantPool();
   __ bind(&start_label_);  // And then continue from here.
 }
 
@@ -938,37 +937,8 @@
 }
 
 
-static bool is_valid_memory_offset(int value) {
-  if (value < 0) value = -value;
-  return value < (1<<12);
-}
-
-
 void RegExpMacroAssemblerARM::PushBacktrack(Label* label) {
-  if (label->is_bound()) {
-    int target = label->pos();
-    __ mov(r0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
-  } else {
-    int constant_offset = GetBacktrackConstantPoolEntry();
-    masm_->label_at_put(label, constant_offset);
-    // Reading pc-relative is based on the address 8 bytes ahead of
-    // the current opcode.
-    unsigned int offset_of_pc_register_read =
-      masm_->pc_offset() + Assembler::kPcLoadDelta;
-    int pc_offset_of_constant =
-      constant_offset - offset_of_pc_register_read;
-    ASSERT(pc_offset_of_constant < 0);
-    if (is_valid_memory_offset(pc_offset_of_constant)) {
-      Assembler::BlockConstPoolScope block_const_pool(masm_);
-      __ ldr(r0, MemOperand(pc, pc_offset_of_constant));
-    } else {
-      // Not a 12-bit offset, so it needs to be loaded from the constant
-      // pool.
-      Assembler::BlockConstPoolScope block_const_pool(masm_);
-      __ mov(r0, Operand(pc_offset_of_constant + Assembler::kInstrSize));
-      __ ldr(r0, MemOperand(pc, r0));
-    }
-  }
+  __ mov_label_offset(r0, label);
   Push(r0);
   CheckStackLimit();
 }
@@ -1279,38 +1249,6 @@
 }
 
 
-void RegExpMacroAssemblerARM::EmitBacktrackConstantPool() {
-  __ CheckConstPool(false, false);
-  Assembler::BlockConstPoolScope block_const_pool(masm_);
-  backtrack_constant_pool_offset_ = masm_->pc_offset();
-  for (int i = 0; i < kBacktrackConstantPoolSize; i++) {
-    __ emit(0);
-  }
-
-  backtrack_constant_pool_capacity_ = kBacktrackConstantPoolSize;
-}
-
-
-int RegExpMacroAssemblerARM::GetBacktrackConstantPoolEntry() {
-  while (backtrack_constant_pool_capacity_ > 0) {
-    int offset = backtrack_constant_pool_offset_;
-    backtrack_constant_pool_offset_ += kPointerSize;
-    backtrack_constant_pool_capacity_--;
-    if (masm_->pc_offset() - offset < 2 * KB) {
-      return offset;
-    }
-  }
-  Label new_pool_skip;
-  __ jmp(&new_pool_skip);
-  EmitBacktrackConstantPool();
-  __ bind(&new_pool_skip);
-  int offset = backtrack_constant_pool_offset_;
-  backtrack_constant_pool_offset_ += kPointerSize;
-  backtrack_constant_pool_capacity_--;
-  return offset;
-}
-
-
 bool RegExpMacroAssemblerARM::CanReadUnaligned() {
   return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe();
 }
diff --git a/src/arm/regexp-macro-assembler-arm.h b/src/arm/regexp-macro-assembler-arm.h
index 0874ad1..9f07489 100644
--- a/src/arm/regexp-macro-assembler-arm.h
+++ b/src/arm/regexp-macro-assembler-arm.h
@@ -160,9 +160,6 @@
   // Check whether we are exceeding the stack limit on the backtrack stack.
   void CheckStackLimit();
 
-  void EmitBacktrackConstantPool();
-  int GetBacktrackConstantPoolEntry();
-
 
   // Generate a call to CheckStackGuardState.
   void CallCheckStackGuardState(Register scratch);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 5bab086..085af3f 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -785,6 +785,11 @@
                                      Register holder,
                                      Register name,
                                      Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
   __ push(name);
   Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
   ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
@@ -793,10 +798,6 @@
   __ push(scratch);
   __ push(receiver);
   __ push(holder);
-  __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
-  __ push(scratch);
-  __ mov(scratch, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ push(scratch);
 }
 
 
@@ -811,7 +812,7 @@
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate());
-  __ mov(r0, Operand(6));
+  __ mov(r0, Operand(StubCache::kInterceptorArgsLength));
   __ mov(r1, Operand(ref));
 
   CEntryStub stub(1);
@@ -1110,7 +1111,7 @@
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        6);
+        StubCache::kInterceptorArgsLength);
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1420,6 +1421,15 @@
     Handle<ExecutableAccessorInfo> callback) {
   // Build AccessorInfo::args_ list on the stack and push property name below
   // the exit frame to make GC aware of them and store pointers to them.
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4);
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5);
+  ASSERT(!scratch2().is(reg));
+  ASSERT(!scratch3().is(reg));
+  ASSERT(!scratch4().is(reg));
   __ push(receiver());
   __ mov(scratch2(), sp);  // scratch2 = AccessorInfo::args_
   if (heap()->InNewSpace(callback->data())) {
@@ -1429,13 +1439,13 @@
   } else {
     __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
   }
-  __ Push(reg, scratch3());
+  __ push(scratch3());
   __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
   __ mov(scratch4(), scratch3());
   __ Push(scratch3(), scratch4());
   __ mov(scratch4(),
          Operand(ExternalReference::isolate_address(isolate())));
-  __ Push(scratch4(), name());
+  __ Push(scratch4(), reg, name());
   __ mov(r0, sp);  // r0 = Handle<Name>
 
   const int kApiStackSpace = 1;
@@ -1465,7 +1475,7 @@
                               thunk_ref,
                               r2,
                               kStackUnwindSpace,
-                              5);
+                              6);
 }
 
 
@@ -1553,7 +1563,7 @@
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
                           isolate());
-    __ TailCallExternalReference(ref, 6, 1);
+    __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
   }
 }
 
diff --git a/src/assembler.h b/src/assembler.h
index 3ebaee3..6b399f2 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -196,7 +196,6 @@
   }
 
   friend class Assembler;
-  friend class RegexpAssembler;
   friend class Displacement;
   friend class RegExpMacroAssemblerIrregexp;
 };
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 58b115d..0756aef 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -45,10 +45,6 @@
 #include "extensions/statistics-extension.h"
 #include "code-stubs.h"
 
-#if defined(V8_I18N_SUPPORT)
-#include "extensions/i18n/i18n-extension.h"
-#endif
-
 namespace v8 {
 namespace internal {
 
@@ -106,9 +102,6 @@
   GCExtension::Register();
   ExternalizeStringExtension::Register();
   StatisticsExtension::Register();
-#if defined(V8_I18N_SUPPORT)
-  v8_i18n::Extension::Register();
-#endif
 }
 
 
@@ -2291,12 +2284,6 @@
     InstallExtension(isolate, "v8/statistics", &extension_states);
   }
 
-#if defined(V8_I18N_SUPPORT)
-  if (FLAG_enable_i18n) {
-    InstallExtension(isolate, "v8/i18n", &extension_states);
-  }
-#endif
-
   if (extensions == NULL) return true;
   // Install required extensions
   int count = v8::ImplementationUtilities::GetNameCount(extensions);
diff --git a/src/builtins.h b/src/builtins.h
index cbfa1d7..c712f1e 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -87,8 +87,6 @@
                                     Code::kNoExtraICState)              \
   V(InRecompileQueue,               BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
-  V(InstallRecompiledCode,          BUILTIN, UNINITIALIZED,             \
-                                    Code::kNoExtraICState)              \
   V(JSConstructStubCountdown,       BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
   V(JSConstructStubGeneric,         BUILTIN, UNINITIALIZED,             \
@@ -122,7 +120,7 @@
                                     Code::kNoExtraICState)              \
   V(KeyedLoadIC_MissForceGeneric,   BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_Slow,               BUILTIN, UNINITIALIZED,             \
+  V(KeyedLoadIC_Slow,               STUB, MONOMORPHIC,                  \
                                     Code::kNoExtraICState)              \
   V(StoreIC_Miss,                   BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
@@ -144,7 +142,7 @@
                                     Code::kNoExtraICState)              \
   V(LoadIC_Getter_ForDeopt,         LOAD_IC, MONOMORPHIC,               \
                                     Code::kNoExtraICState)              \
-  V(LoadIC_Slow,                    LOAD_IC, GENERIC,                   \
+  V(LoadIC_Slow,                    STUB, MONOMORPHIC,                  \
                                     Code::kNoExtraICState)              \
                                                                         \
   V(KeyedLoadIC_Initialize,         KEYED_LOAD_IC, UNINITIALIZED,       \
@@ -382,7 +380,6 @@
                                CFunctionId id,
                                BuiltinExtraArguments extra_args);
   static void Generate_InRecompileQueue(MacroAssembler* masm);
-  static void Generate_InstallRecompiledCode(MacroAssembler* masm);
   static void Generate_ConcurrentRecompile(MacroAssembler* masm);
   static void Generate_JSConstructStubCountdown(MacroAssembler* masm);
   static void Generate_JSConstructStubGeneric(MacroAssembler* masm);
diff --git a/src/checks.h b/src/checks.h
index 062bdf6..f5c5f23 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -197,6 +197,20 @@
 
 
 inline void CheckNonEqualsHelper(const char* file,
+                              int line,
+                              const char* expected_source,
+                              int64_t expected,
+                              const char* value_source,
+                              int64_t value) {
+  if (expected == value) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
+             expected_source, value_source, expected, value);
+  }
+}
+
+
+inline void CheckNonEqualsHelper(const char* file,
                                  int line,
                                  const char* expected_source,
                                  double expected,
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 81bbb52..946eb76 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -736,6 +736,13 @@
 };
 
 
+enum AllocationSiteOverrideMode {
+  DONT_OVERRIDE,
+  DISABLE_ALLOCATION_SITES,
+  LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
+};
+
+
 class ArrayConstructorStub: public PlatformCodeStub {
  public:
   enum ArgumentCountKey { ANY, NONE, ONE, MORE_THAN_ONE };
@@ -745,6 +752,9 @@
   void Generate(MacroAssembler* masm);
 
  private:
+  void GenerateDispatchToArrayStub(MacroAssembler* masm,
+                                   AllocationSiteOverrideMode mode);
+
   virtual CodeStub::Major MajorKey() { return ArrayConstructor; }
   virtual int MinorKey() { return argument_count_; }
 
@@ -1863,13 +1873,6 @@
 };
 
 
-enum AllocationSiteOverrideMode {
-  DONT_OVERRIDE,
-  DISABLE_ALLOCATION_SITES,
-  LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
-};
-
-
 class ArrayConstructorStubBase : public HydrogenCodeStub {
  public:
   ArrayConstructorStubBase(ElementsKind kind, ContextCheckMode context_mode,
@@ -1877,7 +1880,8 @@
     // It only makes sense to override local allocation site behavior
     // if there is a difference between the global allocation site policy
     // for an ElementsKind and the desired usage of the stub.
-    ASSERT(override_mode != DISABLE_ALLOCATION_SITES ||
+    ASSERT(!(FLAG_track_allocation_sites &&
+             override_mode == DISABLE_ALLOCATION_SITES) ||
            AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
     bit_field_ = ElementsKindBits::encode(kind) |
         AllocationSiteOverrideModeBits::encode(override_mode) |
diff --git a/src/compiler.cc b/src/compiler.cc
index 50db8e0..47634ec 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1067,7 +1067,7 @@
       info->closure()->PrintName();
       PrintF(" as it has been disabled.\n");
     }
-    ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
+    ASSERT(!info->closure()->IsInRecompileQueue());
     return Handle<Code>::null();
   }
 
@@ -1114,7 +1114,7 @@
   // Optimized code is finally replacing unoptimized code.  Reset the latter's
   // profiler ticks to prevent too soon re-opt after a deopt.
   info->shared_info()->code()->set_profiler_ticks(0);
-  ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
+  ASSERT(!info->closure()->IsInRecompileQueue());
   return (status == OptimizingCompiler::SUCCEEDED) ? info->code()
                                                    : Handle<Code>::null();
 }
diff --git a/src/cpu.cc b/src/cpu.cc
index 26eca61..2bf51a7 100644
--- a/src/cpu.cc
+++ b/src/cpu.cc
@@ -54,7 +54,7 @@
 // Define __cpuid() for non-MSVC compilers.
 #if !V8_CC_MSVC
 
-static V8_INLINE(void __cpuid(int cpu_info[4], int info_type)) {
+static V8_INLINE void __cpuid(int cpu_info[4], int info_type) {
 #if defined(__i386__) && defined(__pic__)
   // Make sure to preserve ebx, which contains the pointer
   // to the GOT in case we're generating PIC.
diff --git a/src/debug.cc b/src/debug.cc
index 3f2739e..0496b8c 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -2110,8 +2110,7 @@
             function->set_code(*lazy_compile);
             function->shared()->set_code(*lazy_compile);
           } else if (kind == Code::BUILTIN &&
-              (function->IsMarkedForInstallingRecompiledCode() ||
-               function->IsInRecompileQueue() ||
+              (function->IsInRecompileQueue() ||
                function->IsMarkedForLazyRecompilation() ||
                function->IsMarkedForConcurrentRecompilation())) {
             // Abort in-flight compilation.
diff --git a/src/execution.cc b/src/execution.cc
index c59a737..979641a 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -459,6 +459,22 @@
 }
 
 
+bool StackGuard::IsInstallCodeRequest() {
+  ExecutionAccess access(isolate_);
+  return (thread_local_.interrupt_flags_ & INSTALL_CODE) != 0;
+}
+
+
+void StackGuard::RequestInstallCode() {
+  ExecutionAccess access(isolate_);
+  thread_local_.interrupt_flags_ |= INSTALL_CODE;
+  if (thread_local_.postpone_interrupts_nesting_ == 0) {
+    thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
+    isolate_->heap()->SetStackLimits();
+  }
+}
+
+
 bool StackGuard::IsFullDeopt() {
   ExecutionAccess access(isolate_);
   return (thread_local_.interrupt_flags_ & FULL_DEOPT) != 0;
@@ -916,7 +932,6 @@
 
   isolate->counters()->stack_interrupts()->Increment();
   isolate->counters()->runtime_profiler_ticks()->Increment();
-  isolate->runtime_profiler()->OptimizeNow();
 #ifdef ENABLE_DEBUGGER_SUPPORT
   if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
     DebugBreakHelper(isolate);
@@ -935,6 +950,12 @@
     stack_guard->Continue(FULL_DEOPT);
     Deoptimizer::DeoptimizeAll(isolate);
   }
+  if (stack_guard->IsInstallCodeRequest()) {
+    ASSERT(FLAG_concurrent_recompilation);
+    stack_guard->Continue(INSTALL_CODE);
+    isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+  }
+  isolate->runtime_profiler()->OptimizeNow();
   return isolate->heap()->undefined_value();
 }
 
diff --git a/src/execution.h b/src/execution.h
index 0c1bf94..371ea30 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -42,7 +42,8 @@
   PREEMPT = 1 << 3,
   TERMINATE = 1 << 4,
   GC_REQUEST = 1 << 5,
-  FULL_DEOPT = 1 << 6
+  FULL_DEOPT = 1 << 6,
+  INSTALL_CODE = 1 << 7
 };
 
 
@@ -213,6 +214,8 @@
 #endif
   bool IsGCRequest();
   void RequestGC();
+  bool IsInstallCodeRequest();
+  void RequestInstallCode();
   bool IsFullDeopt();
   void FullDeopt();
   void Continue(InterruptFlag after_what);
diff --git a/src/extensions/i18n/break-iterator.js b/src/extensions/i18n/break-iterator.js
deleted file mode 100644
index 898bd5d..0000000
--- a/src/extensions/i18n/break-iterator.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Initializes the given object so it's a valid BreakIterator instance.
- * Useful for subclassing.
- */
-function initializeBreakIterator(iterator, locales, options) {
-  if (iterator.hasOwnProperty('__initializedIntlObject')) {
-    throw new TypeError('Trying to re-initialize v8BreakIterator object.');
-  }
-
-  if (options === undefined) {
-    options = {};
-  }
-
-  var getOption = getGetOption(options, 'breakiterator');
-
-  var internalOptions = {};
-
-  defineWEProperty(internalOptions, 'type', getOption(
-    'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
-
-  var locale = resolveLocale('breakiterator', locales, options);
-  var resolved = Object.defineProperties({}, {
-    requestedLocale: {value: locale.locale, writable: true},
-    type: {value: internalOptions.type, writable: true},
-    locale: {writable: true}
-  });
-
-  var internalIterator = %CreateBreakIterator(locale.locale,
-                                              internalOptions,
-                                              resolved);
-
-  Object.defineProperty(iterator, 'iterator', {value: internalIterator});
-  Object.defineProperty(iterator, 'resolved', {value: resolved});
-  Object.defineProperty(iterator, '__initializedIntlObject',
-                        {value: 'breakiterator'});
-
-  return iterator;
-}
-
-
-/**
- * Constructs Intl.v8BreakIterator object given optional locales and options
- * parameters.
- *
- * @constructor
- */
-%SetProperty(Intl, 'v8BreakIterator', function() {
-    var locales = arguments[0];
-    var options = arguments[1];
-
-    if (!this || this === Intl) {
-      // Constructor is called as a function.
-      return new Intl.v8BreakIterator(locales, options);
-    }
-
-    return initializeBreakIterator(toObject(this), locales, options);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-
-
-/**
- * BreakIterator resolvedOptions method.
- */
-%SetProperty(Intl.v8BreakIterator.prototype, 'resolvedOptions', function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'breakiterator') {
-      throw new TypeError('resolvedOptions method called on a non-object or ' +
-          'on a object that is not Intl.v8BreakIterator.');
-    }
-
-    var segmenter = this;
-    var locale = getOptimalLanguageTag(segmenter.resolved.requestedLocale,
-                                       segmenter.resolved.locale);
-
-    return {
-      locale: locale,
-      type: segmenter.resolved.type
-    };
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.v8BreakIterator.prototype.resolvedOptions,
-                 'resolvedOptions');
-%FunctionRemovePrototype(Intl.v8BreakIterator.prototype.resolvedOptions);
-%SetNativeFlag(Intl.v8BreakIterator.prototype.resolvedOptions);
-
-
-/**
- * Returns the subset of the given locale list for which this locale list
- * has a matching (possibly fallback) locale. Locales appear in the same
- * order in the returned list as in the input list.
- * Options are optional parameter.
- */
-%SetProperty(Intl.v8BreakIterator, 'supportedLocalesOf', function(locales) {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    return supportedLocalesOf('breakiterator', locales, arguments[1]);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.v8BreakIterator.supportedLocalesOf, 'supportedLocalesOf');
-%FunctionRemovePrototype(Intl.v8BreakIterator.supportedLocalesOf);
-%SetNativeFlag(Intl.v8BreakIterator.supportedLocalesOf);
-
-
-/**
- * Adopts text to segment using the iterator. Old text, if present,
- * gets discarded.
- */
-function adoptText(iterator, text) {
-  %BreakIteratorAdoptText(iterator.iterator, String(text));
-}
-
-
-/**
- * Returns index of the first break in the string and moves current pointer.
- */
-function first(iterator) {
-  return %BreakIteratorFirst(iterator.iterator);
-}
-
-
-/**
- * Returns the index of the next break and moves the pointer.
- */
-function next(iterator) {
-  return %BreakIteratorNext(iterator.iterator);
-}
-
-
-/**
- * Returns index of the current break.
- */
-function current(iterator) {
-  return %BreakIteratorCurrent(iterator.iterator);
-}
-
-
-/**
- * Returns type of the current break.
- */
-function breakType(iterator) {
-  return %BreakIteratorBreakType(iterator.iterator);
-}
-
-
-addBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
-addBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
-addBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
-addBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
-addBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
diff --git a/src/extensions/i18n/collator.js b/src/extensions/i18n/collator.js
deleted file mode 100644
index d8d247b..0000000
--- a/src/extensions/i18n/collator.js
+++ /dev/null
@@ -1,209 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Initializes the given object so it's a valid Collator instance.
- * Useful for subclassing.
- */
-function initializeCollator(collator, locales, options) {
-  if (collator.hasOwnProperty('__initializedIntlObject')) {
-    throw new TypeError('Trying to re-initialize Collator object.');
-  }
-
-  if (options === undefined) {
-    options = {};
-  }
-
-  var getOption = getGetOption(options, 'collator');
-
-  var internalOptions = {};
-
-  defineWEProperty(internalOptions, 'usage', getOption(
-    'usage', 'string', ['sort', 'search'], 'sort'));
-
-  var sensitivity = getOption('sensitivity', 'string',
-                              ['base', 'accent', 'case', 'variant']);
-  if (sensitivity === undefined && internalOptions.usage === 'sort') {
-    sensitivity = 'variant';
-  }
-  defineWEProperty(internalOptions, 'sensitivity', sensitivity);
-
-  defineWEProperty(internalOptions, 'ignorePunctuation', getOption(
-    'ignorePunctuation', 'boolean', undefined, false));
-
-  var locale = resolveLocale('collator', locales, options);
-
-  // ICU can't take kb, kc... parameters through localeID, so we need to pass
-  // them as options.
-  // One exception is -co- which has to be part of the extension, but only for
-  // usage: sort, and its value can't be 'standard' or 'search'.
-  var extensionMap = parseExtension(locale.extension);
-  setOptions(
-      options, extensionMap, COLLATOR_KEY_MAP, getOption, internalOptions);
-
-  var collation = 'default';
-  var extension = '';
-  if (extensionMap.hasOwnProperty('co') && internalOptions.usage === 'sort') {
-    if (ALLOWED_CO_VALUES.indexOf(extensionMap.co) !== -1) {
-      extension = '-u-co-' + extensionMap.co;
-      // ICU can't tell us what the collation is, so save user's input.
-      collation = extensionMap.co;
-    }
-  } else if (internalOptions.usage === 'search') {
-    extension = '-u-co-search';
-  }
-  defineWEProperty(internalOptions, 'collation', collation);
-
-  var requestedLocale = locale.locale + extension;
-
-  // We define all properties C++ code may produce, to prevent security
-  // problems. If malicious user decides to redefine Object.prototype.locale
-  // we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
-  // Object.defineProperties will either succeed defining or throw an error.
-  var resolved = Object.defineProperties({}, {
-    caseFirst: {writable: true},
-    collation: {value: internalOptions.collation, writable: true},
-    ignorePunctuation: {writable: true},
-    locale: {writable: true},
-    numeric: {writable: true},
-    requestedLocale: {value: requestedLocale, writable: true},
-    sensitivity: {writable: true},
-    strength: {writable: true},
-    usage: {value: internalOptions.usage, writable: true}
-  });
-
-  var internalCollator = %CreateCollator(requestedLocale,
-                                         internalOptions,
-                                         resolved);
-
-  // Writable, configurable and enumerable are set to false by default.
-  Object.defineProperty(collator, 'collator', {value: internalCollator});
-  Object.defineProperty(collator, '__initializedIntlObject',
-                        {value: 'collator'});
-  Object.defineProperty(collator, 'resolved', {value: resolved});
-
-  return collator;
-}
-
-
-/**
- * Constructs Intl.Collator object given optional locales and options
- * parameters.
- *
- * @constructor
- */
-%SetProperty(Intl, 'Collator', function() {
-    var locales = arguments[0];
-    var options = arguments[1];
-
-    if (!this || this === Intl) {
-      // Constructor is called as a function.
-      return new Intl.Collator(locales, options);
-    }
-
-    return initializeCollator(toObject(this), locales, options);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-
-
-/**
- * Collator resolvedOptions method.
- */
-%SetProperty(Intl.Collator.prototype, 'resolvedOptions', function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'collator') {
-      throw new TypeError('resolvedOptions method called on a non-object ' +
-                          'or on a object that is not Intl.Collator.');
-    }
-
-    var coll = this;
-    var locale = getOptimalLanguageTag(coll.resolved.requestedLocale,
-                                       coll.resolved.locale);
-
-    return {
-      locale: locale,
-      usage: coll.resolved.usage,
-      sensitivity: coll.resolved.sensitivity,
-      ignorePunctuation: coll.resolved.ignorePunctuation,
-      numeric: coll.resolved.numeric,
-      caseFirst: coll.resolved.caseFirst,
-      collation: coll.resolved.collation
-    };
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.Collator.prototype.resolvedOptions, 'resolvedOptions');
-%FunctionRemovePrototype(Intl.Collator.prototype.resolvedOptions);
-%SetNativeFlag(Intl.Collator.prototype.resolvedOptions);
-
-
-/**
- * Returns the subset of the given locale list for which this locale list
- * has a matching (possibly fallback) locale. Locales appear in the same
- * order in the returned list as in the input list.
- * Options are optional parameter.
- */
-%SetProperty(Intl.Collator, 'supportedLocalesOf', function(locales) {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    return supportedLocalesOf('collator', locales, arguments[1]);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.Collator.supportedLocalesOf, 'supportedLocalesOf');
-%FunctionRemovePrototype(Intl.Collator.supportedLocalesOf);
-%SetNativeFlag(Intl.Collator.supportedLocalesOf);
-
-
-/**
- * When the compare method is called with two arguments x and y, it returns a
- * Number other than NaN that represents the result of a locale-sensitive
- * String comparison of x with y.
- * The result is intended to order String values in the sort order specified
- * by the effective locale and collation options computed during construction
- * of this Collator object, and will be negative, zero, or positive, depending
- * on whether x comes before y in the sort order, the Strings are equal under
- * the sort order, or x comes after y in the sort order, respectively.
- */
-function compare(collator, x, y) {
-  return %InternalCompare(collator.collator, String(x), String(y));
-};
-
-
-addBoundMethod(Intl.Collator, 'compare', compare, 2);
diff --git a/src/extensions/i18n/date-format.js b/src/extensions/i18n/date-format.js
deleted file mode 100644
index b1d28e5..0000000
--- a/src/extensions/i18n/date-format.js
+++ /dev/null
@@ -1,474 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Returns a string that matches LDML representation of the options object.
- */
-function toLDMLString(options) {
-  var getOption = getGetOption(options, 'dateformat');
-
-  var ldmlString = '';
-
-  var option = getOption('weekday', 'string', ['narrow', 'short', 'long']);
-  ldmlString += appendToLDMLString(
-      option, {narrow: 'EEEEE', short: 'EEE', long: 'EEEE'});
-
-  option = getOption('era', 'string', ['narrow', 'short', 'long']);
-  ldmlString += appendToLDMLString(
-      option, {narrow: 'GGGGG', short: 'GGG', long: 'GGGG'});
-
-  option = getOption('year', 'string', ['2-digit', 'numeric']);
-  ldmlString += appendToLDMLString(option, {'2-digit': 'yy', 'numeric': 'y'});
-
-  option = getOption('month', 'string',
-                     ['2-digit', 'numeric', 'narrow', 'short', 'long']);
-  ldmlString += appendToLDMLString(option, {'2-digit': 'MM', 'numeric': 'M',
-          'narrow': 'MMMMM', 'short': 'MMM', 'long': 'MMMM'});
-
-  option = getOption('day', 'string', ['2-digit', 'numeric']);
-  ldmlString += appendToLDMLString(
-      option, {'2-digit': 'dd', 'numeric': 'd'});
-
-  var hr12 = getOption('hour12', 'boolean');
-  option = getOption('hour', 'string', ['2-digit', 'numeric']);
-  if (hr12 === undefined) {
-    ldmlString += appendToLDMLString(option, {'2-digit': 'jj', 'numeric': 'j'});
-  } else if (hr12 === true) {
-    ldmlString += appendToLDMLString(option, {'2-digit': 'hh', 'numeric': 'h'});
-  } else {
-    ldmlString += appendToLDMLString(option, {'2-digit': 'HH', 'numeric': 'H'});
-  }
-
-  option = getOption('minute', 'string', ['2-digit', 'numeric']);
-  ldmlString += appendToLDMLString(option, {'2-digit': 'mm', 'numeric': 'm'});
-
-  option = getOption('second', 'string', ['2-digit', 'numeric']);
-  ldmlString += appendToLDMLString(option, {'2-digit': 'ss', 'numeric': 's'});
-
-  option = getOption('timeZoneName', 'string', ['short', 'long']);
-  ldmlString += appendToLDMLString(option, {short: 'v', long: 'vv'});
-
-  return ldmlString;
-}
-
-
-/**
- * Returns either LDML equivalent of the current option or empty string.
- */
-function appendToLDMLString(option, pairs) {
-  if (option !== undefined) {
-    return pairs[option];
-  } else {
-    return '';
-  }
-}
-
-
-/**
- * Returns object that matches LDML representation of the date.
- */
-function fromLDMLString(ldmlString) {
-  // First remove '' quoted text, so we lose 'Uhr' strings.
-  ldmlString = ldmlString.replace(QUOTED_STRING_RE, '');
-
-  var options = {};
-  var match = ldmlString.match(/E{3,5}/g);
-  options = appendToDateTimeObject(
-      options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
-
-  match = ldmlString.match(/G{3,5}/g);
-  options = appendToDateTimeObject(
-      options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
-
-  match = ldmlString.match(/y{1,2}/g);
-  options = appendToDateTimeObject(
-      options, 'year', match, {y: 'numeric', yy: '2-digit'});
-
-  match = ldmlString.match(/M{1,5}/g);
-  options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
-      M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
-
-  // Sometimes we get L instead of M for month - standalone name.
-  match = ldmlString.match(/L{1,5}/g);
-  options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
-      L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
-
-  match = ldmlString.match(/d{1,2}/g);
-  options = appendToDateTimeObject(
-      options, 'day', match, {d: 'numeric', dd: '2-digit'});
-
-  match = ldmlString.match(/h{1,2}/g);
-  if (match !== null) {
-    options['hour12'] = true;
-  }
-  options = appendToDateTimeObject(
-      options, 'hour', match, {h: 'numeric', hh: '2-digit'});
-
-  match = ldmlString.match(/H{1,2}/g);
-  if (match !== null) {
-    options['hour12'] = false;
-  }
-  options = appendToDateTimeObject(
-      options, 'hour', match, {H: 'numeric', HH: '2-digit'});
-
-  match = ldmlString.match(/m{1,2}/g);
-  options = appendToDateTimeObject(
-      options, 'minute', match, {m: 'numeric', mm: '2-digit'});
-
-  match = ldmlString.match(/s{1,2}/g);
-  options = appendToDateTimeObject(
-      options, 'second', match, {s: 'numeric', ss: '2-digit'});
-
-  match = ldmlString.match(/v{1,2}/g);
-  options = appendToDateTimeObject(
-      options, 'timeZoneName', match, {v: 'short', vv: 'long'});
-
-  return options;
-}
-
-
-function appendToDateTimeObject(options, option, match, pairs) {
-  if (match === null) {
-    if (!options.hasOwnProperty(option)) {
-      defineWEProperty(options, option, undefined);
-    }
-    return options;
-  }
-
-  var property = match[0];
-  defineWEProperty(options, option, pairs[property]);
-
-  return options;
-}
-
-
-/**
- * Returns options with at least default values in it.
- */
-function toDateTimeOptions(options, required, defaults) {
-  if (options === undefined) {
-    options = null;
-  } else {
-    options = toObject(options);
-  }
-
-  options = Object.apply(this, [options]);
-
-  var needsDefault = true;
-  if ((required === 'date' || required === 'any') &&
-      (options.weekday !== undefined || options.year !== undefined ||
-       options.month !== undefined || options.day !== undefined)) {
-    needsDefault = false;
-  }
-
-  if ((required === 'time' || required === 'any') &&
-      (options.hour !== undefined || options.minute !== undefined ||
-       options.second !== undefined)) {
-    needsDefault = false;
-  }
-
-  if (needsDefault && (defaults === 'date' || defaults === 'all')) {
-    Object.defineProperty(options, 'year', {value: 'numeric',
-                                            writable: true,
-                                            enumerable: true,
-                                            configurable: true});
-    Object.defineProperty(options, 'month', {value: 'numeric',
-                                             writable: true,
-                                             enumerable: true,
-                                             configurable: true});
-    Object.defineProperty(options, 'day', {value: 'numeric',
-                                           writable: true,
-                                           enumerable: true,
-                                           configurable: true});
-  }
-
-  if (needsDefault && (defaults === 'time' || defaults === 'all')) {
-    Object.defineProperty(options, 'hour', {value: 'numeric',
-                                            writable: true,
-                                            enumerable: true,
-                                            configurable: true});
-    Object.defineProperty(options, 'minute', {value: 'numeric',
-                                              writable: true,
-                                              enumerable: true,
-                                              configurable: true});
-    Object.defineProperty(options, 'second', {value: 'numeric',
-                                              writable: true,
-                                              enumerable: true,
-                                              configurable: true});
-  }
-
-  return options;
-}
-
-
-/**
- * Initializes the given object so it's a valid DateTimeFormat instance.
- * Useful for subclassing.
- */
-function initializeDateTimeFormat(dateFormat, locales, options) {
-
-  if (dateFormat.hasOwnProperty('__initializedIntlObject')) {
-    throw new TypeError('Trying to re-initialize DateTimeFormat object.');
-  }
-
-  if (options === undefined) {
-    options = {};
-  }
-
-  var locale = resolveLocale('dateformat', locales, options);
-
-  options = toDateTimeOptions(options, 'any', 'date');
-
-  var getOption = getGetOption(options, 'dateformat');
-
-  // We implement only best fit algorithm, but still need to check
-  // if the formatMatcher values are in range.
-  var matcher = getOption('formatMatcher', 'string',
-                          ['basic', 'best fit'], 'best fit');
-
-  // Build LDML string for the skeleton that we pass to the formatter.
-  var ldmlString = toLDMLString(options);
-
-  // Filter out supported extension keys so we know what to put in resolved
-  // section later on.
-  // We need to pass calendar and number system to the method.
-  var tz = canonicalizeTimeZoneID(options.timeZone);
-
-  // ICU prefers options to be passed using -u- extension key/values, so
-  // we need to build that.
-  var internalOptions = {};
-  var extensionMap = parseExtension(locale.extension);
-  var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP,
-                             getOption, internalOptions);
-
-  var requestedLocale = locale.locale + extension;
-  var resolved = Object.defineProperties({}, {
-    calendar: {writable: true},
-    day: {writable: true},
-    era: {writable: true},
-    hour12: {writable: true},
-    hour: {writable: true},
-    locale: {writable: true},
-    minute: {writable: true},
-    month: {writable: true},
-    numberingSystem: {writable: true},
-    pattern: {writable: true},
-    requestedLocale: {value: requestedLocale, writable: true},
-    second: {writable: true},
-    timeZone: {writable: true},
-    timeZoneName: {writable: true},
-    tz: {value: tz, writable: true},
-    weekday: {writable: true},
-    year: {writable: true}
-  });
-
-  var formatter = %CreateDateTimeFormat(
-    requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
-
-  if (tz !== undefined && tz !== resolved.timeZone) {
-    throw new RangeError('Unsupported time zone specified ' + tz);
-  }
-
-  Object.defineProperty(dateFormat, 'formatter', {value: formatter});
-  Object.defineProperty(dateFormat, 'resolved', {value: resolved});
-  Object.defineProperty(dateFormat, '__initializedIntlObject',
-                        {value: 'dateformat'});
-
-  return dateFormat;
-}
-
-
-/**
- * Constructs Intl.DateTimeFormat object given optional locales and options
- * parameters.
- *
- * @constructor
- */
-%SetProperty(Intl, 'DateTimeFormat', function() {
-    var locales = arguments[0];
-    var options = arguments[1];
-
-    if (!this || this === Intl) {
-      // Constructor is called as a function.
-      return new Intl.DateTimeFormat(locales, options);
-    }
-
-    return initializeDateTimeFormat(toObject(this), locales, options);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-
-
-/**
- * DateTimeFormat resolvedOptions method.
- */
-%SetProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'dateformat') {
-      throw new TypeError('resolvedOptions method called on a non-object or ' +
-          'on a object that is not Intl.DateTimeFormat.');
-    }
-
-    var format = this;
-    var fromPattern = fromLDMLString(format.resolved.pattern);
-    var userCalendar = ICU_CALENDAR_MAP[format.resolved.calendar];
-    if (userCalendar === undefined) {
-      // Use ICU name if we don't have a match. It shouldn't happen, but
-      // it would be too strict to throw for this.
-      userCalendar = format.resolved.calendar;
-    }
-
-    var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
-                                       format.resolved.locale);
-
-    var result = {
-      locale: locale,
-      numberingSystem: format.resolved.numberingSystem,
-      calendar: userCalendar,
-      timeZone: format.resolved.timeZone
-    };
-
-    addWECPropertyIfDefined(result, 'timeZoneName', fromPattern.timeZoneName);
-    addWECPropertyIfDefined(result, 'era', fromPattern.era);
-    addWECPropertyIfDefined(result, 'year', fromPattern.year);
-    addWECPropertyIfDefined(result, 'month', fromPattern.month);
-    addWECPropertyIfDefined(result, 'day', fromPattern.day);
-    addWECPropertyIfDefined(result, 'weekday', fromPattern.weekday);
-    addWECPropertyIfDefined(result, 'hour12', fromPattern.hour12);
-    addWECPropertyIfDefined(result, 'hour', fromPattern.hour);
-    addWECPropertyIfDefined(result, 'minute', fromPattern.minute);
-    addWECPropertyIfDefined(result, 'second', fromPattern.second);
-
-    return result;
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.DateTimeFormat.prototype.resolvedOptions,
-                 'resolvedOptions');
-%FunctionRemovePrototype(Intl.DateTimeFormat.prototype.resolvedOptions);
-%SetNativeFlag(Intl.DateTimeFormat.prototype.resolvedOptions);
-
-
-/**
- * Returns the subset of the given locale list for which this locale list
- * has a matching (possibly fallback) locale. Locales appear in the same
- * order in the returned list as in the input list.
- * Options are optional parameter.
- */
-%SetProperty(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    return supportedLocalesOf('dateformat', locales, arguments[1]);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.DateTimeFormat.supportedLocalesOf, 'supportedLocalesOf');
-%FunctionRemovePrototype(Intl.DateTimeFormat.supportedLocalesOf);
-%SetNativeFlag(Intl.DateTimeFormat.supportedLocalesOf);
-
-
-/**
- * Returns a String value representing the result of calling ToNumber(date)
- * according to the effective locale and the formatting options of this
- * DateTimeFormat.
- */
-function formatDate(formatter, dateValue) {
-  var dateMs;
-  if (dateValue === undefined) {
-    dateMs = Date.now();
-  } else {
-    dateMs = Number(dateValue);
-  }
-
-  if (!isFinite(dateMs)) {
-    throw new RangeError('Provided date is not in valid range.');
-  }
-
-  return %InternalDateFormat(formatter.formatter, new Date(dateMs));
-}
-
-
-/**
- * Returns a Date object representing the result of calling ToString(value)
- * according to the effective locale and the formatting options of this
- * DateTimeFormat.
- * Returns undefined if date string cannot be parsed.
- */
-function parseDate(formatter, value) {
-  return %InternalDateParse(formatter.formatter, String(value));
-}
-
-
-// 0 because date is optional argument.
-addBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
-addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
-
-
-/**
- * Returns canonical Area/Location name, or throws an exception if the zone
- * name is invalid IANA name.
- */
-function canonicalizeTimeZoneID(tzID) {
-  // Skip undefined zones.
-  if (tzID === undefined) {
-    return tzID;
-  }
-
-  // Special case handling (UTC, GMT).
-  var upperID = tzID.toUpperCase();
-  if (upperID === 'UTC' || upperID === 'GMT' ||
-      upperID === 'ETC/UTC' || upperID === 'ETC/GMT') {
-    return 'UTC';
-  }
-
-  // We expect only _ and / beside ASCII letters.
-  // All inputs should conform to Area/Location from now on.
-  var match = TIMEZONE_NAME_CHECK_RE.exec(tzID);
-  if (match === null) {
-    throw new RangeError('Expected Area/Location for time zone, got ' + tzID);
-  }
-
-  var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]);
-  var i = 3;
-  while (match[i] !== undefined && i < match.length) {
-    result = result + '_' + toTitleCaseWord(match[i]);
-    i++;
-  }
-
-  return result;
-}
diff --git a/src/extensions/i18n/footer.js b/src/extensions/i18n/footer.js
deleted file mode 100644
index ac33f1e..0000000
--- a/src/extensions/i18n/footer.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-// Fix RegExp global state so we don't fail WebKit layout test:
-// fast/js/regexp-caching.html
-// It seems that 'g' or test() operations leave state changed.
-var CLEANUP_RE = new RegExp('');
-CLEANUP_RE.test('');
-
-return Intl;
-}());
diff --git a/src/extensions/i18n/globals.js b/src/extensions/i18n/globals.js
deleted file mode 100644
index 68fabe7..0000000
--- a/src/extensions/i18n/globals.js
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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.
-// limitations under the License.
-
-
-/**
- * List of available services.
- */
-var AVAILABLE_SERVICES = ['collator',
-                          'numberformat',
-                          'dateformat',
-                          'breakiterator'];
-
-/**
- * Caches available locales for each service.
- */
-var AVAILABLE_LOCALES = {
-  'collator': undefined,
-  'numberformat': undefined,
-  'dateformat': undefined,
-  'breakiterator': undefined
-};
-
-/**
- * Caches default ICU locale.
- */
-var DEFAULT_ICU_LOCALE = undefined;
-
-/**
- * Unicode extension regular expression.
- */
-var UNICODE_EXTENSION_RE = new RegExp('-u(-[a-z0-9]{2,8})+', 'g');
-
-/**
- * Matches any Unicode extension.
- */
-var ANY_EXTENSION_RE = new RegExp('-[a-z0-9]{1}-.*', 'g');
-
-/**
- * Replace quoted text (single quote, anything but the quote and quote again).
- */
-var QUOTED_STRING_RE = new RegExp("'[^']+'", 'g');
-
-/**
- * Matches valid service name.
- */
-var SERVICE_RE =
-    new RegExp('^(collator|numberformat|dateformat|breakiterator)$');
-
-/**
- * Validates a language tag against bcp47 spec.
- * Actual value is assigned on first run.
- */
-var LANGUAGE_TAG_RE = undefined;
-
-/**
- * Helps find duplicate variants in the language tag.
- */
-var LANGUAGE_VARIANT_RE = undefined;
-
-/**
- * Helps find duplicate singletons in the language tag.
- */
-var LANGUAGE_SINGLETON_RE = undefined;
-
-/**
- * Matches valid IANA time zone names.
- */
-var TIMEZONE_NAME_CHECK_RE =
-    new RegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
-
-/**
- * Maps ICU calendar names into LDML type.
- */
-var ICU_CALENDAR_MAP = {
-  'gregorian': 'gregory',
-  'japanese': 'japanese',
-  'buddhist': 'buddhist',
-  'roc': 'roc',
-  'persian': 'persian',
-  'islamic-civil': 'islamicc',
-  'islamic': 'islamic',
-  'hebrew': 'hebrew',
-  'chinese': 'chinese',
-  'indian': 'indian',
-  'coptic': 'coptic',
-  'ethiopic': 'ethiopic',
-  'ethiopic-amete-alem': 'ethioaa'
-};
-
-/**
- * Map of Unicode extensions to option properties, and their values and types,
- * for a collator.
- */
-var COLLATOR_KEY_MAP = {
-  'kn': {'property': 'numeric', 'type': 'boolean'},
-  'kf': {'property': 'caseFirst', 'type': 'string',
-         'values': ['false', 'lower', 'upper']}
-};
-
-/**
- * Map of Unicode extensions to option properties, and their values and types,
- * for a number format.
- */
-var NUMBER_FORMAT_KEY_MAP = {
-  'nu': {'property': undefined, 'type': 'string'}
-};
-
-/**
- * Map of Unicode extensions to option properties, and their values and types,
- * for a date/time format.
- */
-var DATETIME_FORMAT_KEY_MAP = {
-  'ca': {'property': undefined, 'type': 'string'},
-  'nu': {'property': undefined, 'type': 'string'}
-};
-
-/**
- * Allowed -u-co- values. List taken from:
- * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml
- */
-var ALLOWED_CO_VALUES = [
-  'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic',
-  'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin'
-];
-
-/**
- * Object attributes (configurable, writable, enumerable).
- * To combine attributes, OR them.
- * Values/names are copied from v8/include/v8.h:PropertyAttribute
- */
-var ATTRIBUTES = {
-  'NONE': 0,
-  'READ_ONLY': 1,
-  'DONT_ENUM': 2,
-  'DONT_DELETE': 4
-};
-
-/**
- * Error message for when function object is created with new and it's not
- * a constructor.
- */
-var ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR =
-  'Function object that\'s not a constructor was created with new';
diff --git a/src/extensions/i18n/header.js b/src/extensions/i18n/header.js
deleted file mode 100644
index 1c0a2d8..0000000
--- a/src/extensions/i18n/header.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Intl object is a single object that has some named properties,
- * all of which are constructors.
- */
-var Intl = (function() {
-
-'use strict';
-
-var Intl = {};
diff --git a/src/extensions/i18n/i18n-extension.cc b/src/extensions/i18n/i18n-extension.cc
deleted file mode 100644
index b5f2863..0000000
--- a/src/extensions/i18n/i18n-extension.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-// limitations under the License.
-
-#include "i18n-extension.h"
-
-#include "natives.h"
-
-using v8::internal::I18NNatives;
-
-namespace v8_i18n {
-
-Extension::Extension()
-    : v8::Extension("v8/i18n",
-                    reinterpret_cast<const char*>(
-                        I18NNatives::GetScriptsSource().start()),
-                    0,
-                    0,
-                    I18NNatives::GetScriptsSource().length()) {}
-
-
-void Extension::Register() {
-  static Extension i18n_extension;
-  static v8::DeclareExtension extension_declaration(&i18n_extension);
-}
-
-}  // namespace v8_i18n
diff --git a/src/extensions/i18n/i18n-extension.h b/src/extensions/i18n/i18n-extension.h
deleted file mode 100644
index 9e538cb..0000000
--- a/src/extensions/i18n/i18n-extension.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-// limitations under the License.
-
-#ifndef V8_EXTENSIONS_I18N_I18N_EXTENSION_H_
-#define V8_EXTENSIONS_I18N_I18N_EXTENSION_H_
-
-#include "v8.h"
-
-namespace v8_i18n {
-
-class Extension : public v8::Extension {
- public:
-  Extension();
-
-  static void Register();
-
- private:
-  static Extension* extension_;
-};
-
-}  // namespace v8_i18n
-
-#endif  // V8_EXTENSIONS_I18N_I18N_EXTENSION_H_
diff --git a/src/extensions/i18n/i18n-utils.js b/src/extensions/i18n/i18n-utils.js
deleted file mode 100644
index 545082e..0000000
--- a/src/extensions/i18n/i18n-utils.js
+++ /dev/null
@@ -1,536 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Adds bound method to the prototype of the given object.
- */
-function addBoundMethod(obj, methodName, implementation, length) {
-  function getter() {
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject === undefined) {
-        throw new TypeError('Method ' + methodName + ' called on a ' +
-                            'non-object or on a wrong type of object.');
-    }
-    var internalName = '__bound' + methodName + '__';
-    if (this[internalName] === undefined) {
-      var that = this;
-      var boundMethod;
-      if (length === undefined || length === 2) {
-        boundMethod = function(x, y) {
-          if (%_IsConstructCall()) {
-            throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-          }
-          return implementation(that, x, y);
-        }
-      } else if (length === 1) {
-        boundMethod = function(x) {
-          if (%_IsConstructCall()) {
-            throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-          }
-          return implementation(that, x);
-        }
-      } else {
-        boundMethod = function() {
-          if (%_IsConstructCall()) {
-            throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-          }
-          // DateTimeFormat.format needs to be 0 arg method, but can stil
-          // receive optional dateValue param. If one was provided, pass it
-          // along.
-          if (arguments.length > 0) {
-            return implementation(that, arguments[0]);
-          } else {
-            return implementation(that);
-          }
-        }
-      }
-      %FunctionSetName(boundMethod, internalName);
-      %FunctionRemovePrototype(boundMethod);
-      %SetNativeFlag(boundMethod);
-      this[internalName] = boundMethod;
-    }
-    return this[internalName];
-  }
-
-  %FunctionSetName(getter, methodName);
-  %FunctionRemovePrototype(getter);
-  %SetNativeFlag(getter);
-
-  Object.defineProperty(obj.prototype, methodName, {
-    get: getter,
-    enumerable: false,
-    configurable: true
-  });
-}
-
-
-/**
- * Returns an intersection of locales and service supported locales.
- * Parameter locales is treated as a priority list.
- */
-function supportedLocalesOf(service, locales, options) {
-  if (service.match(SERVICE_RE) === null) {
-    throw new Error('Internal error, wrong service type: ' + service);
-  }
-
-  // Provide defaults if matcher was not specified.
-  if (options === undefined) {
-    options = {};
-  } else {
-    options = toObject(options);
-  }
-
-  var matcher = options.localeMatcher;
-  if (matcher !== undefined) {
-    matcher = String(matcher);
-    if (matcher !== 'lookup' && matcher !== 'best fit') {
-      throw new RangeError('Illegal value for localeMatcher:' + matcher);
-    }
-  } else {
-    matcher = 'best fit';
-  }
-
-  var requestedLocales = initializeLocaleList(locales);
-
-  // Cache these, they don't ever change per service.
-  if (AVAILABLE_LOCALES[service] === undefined) {
-    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
-  }
-
-  // Use either best fit or lookup algorithm to match locales.
-  if (matcher === 'best fit') {
-    return initializeLocaleList(bestFitSupportedLocalesOf(
-        requestedLocales, AVAILABLE_LOCALES[service]));
-  }
-
-  return initializeLocaleList(lookupSupportedLocalesOf(
-      requestedLocales, AVAILABLE_LOCALES[service]));
-}
-
-
-/**
- * Returns the subset of the provided BCP 47 language priority list for which
- * this service has a matching locale when using the BCP 47 Lookup algorithm.
- * Locales appear in the same order in the returned list as in the input list.
- */
-function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
-  var matchedLocales = [];
-  for (var i = 0; i < requestedLocales.length; ++i) {
-    // Remove -u- extension.
-    var locale = requestedLocales[i].replace(UNICODE_EXTENSION_RE, '');
-    do {
-      if (availableLocales[locale] !== undefined) {
-        // Push requested locale not the resolved one.
-        matchedLocales.push(requestedLocales[i]);
-        break;
-      }
-      // Truncate locale if possible, if not break.
-      var pos = locale.lastIndexOf('-');
-      if (pos === -1) {
-        break;
-      }
-      locale = locale.substring(0, pos);
-    } while (true);
-  }
-
-  return matchedLocales;
-}
-
-
-/**
- * Returns the subset of the provided BCP 47 language priority list for which
- * this service has a matching locale when using the implementation
- * dependent algorithm.
- * Locales appear in the same order in the returned list as in the input list.
- */
-function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
-  // TODO(cira): implement better best fit algorithm.
-  return lookupSupportedLocalesOf(requestedLocales, availableLocales);
-}
-
-
-/**
- * Returns a getOption function that extracts property value for given
- * options object. If property is missing it returns defaultValue. If value
- * is out of range for that property it throws RangeError.
- */
-function getGetOption(options, caller) {
-  if (options === undefined) {
-    throw new Error('Internal ' + caller + ' error. ' +
-                    'Default options are missing.');
-  }
-
-  var getOption = function getOption(property, type, values, defaultValue) {
-    if (options[property] !== undefined) {
-      var value = options[property];
-      switch (type) {
-        case 'boolean':
-          value = Boolean(value);
-          break;
-        case 'string':
-          value = String(value);
-          break;
-        case 'number':
-          value = Number(value);
-          break;
-        default:
-          throw new Error('Internal error. Wrong value type.');
-      }
-      if (values !== undefined && values.indexOf(value) === -1) {
-        throw new RangeError('Value ' + value + ' out of range for ' + caller +
-                             ' options property ' + property);
-      }
-
-      return value;
-    }
-
-    return defaultValue;
-  }
-
-  return getOption;
-}
-
-
-/**
- * Compares a BCP 47 language priority list requestedLocales against the locales
- * in availableLocales and determines the best available language to meet the
- * request. Two algorithms are available to match the locales: the Lookup
- * algorithm described in RFC 4647 section 3.4, and an implementation dependent
- * best-fit algorithm. Independent of the locale matching algorithm, options
- * specified through Unicode locale extension sequences are negotiated
- * separately, taking the caller's relevant extension keys and locale data as
- * well as client-provided options into consideration. Returns an object with
- * a locale property whose value is the language tag of the selected locale,
- * and properties for each key in relevantExtensionKeys providing the selected
- * value for that key.
- */
-function resolveLocale(service, requestedLocales, options) {
-  requestedLocales = initializeLocaleList(requestedLocales);
-
-  var getOption = getGetOption(options, service);
-  var matcher = getOption('localeMatcher', 'string',
-                          ['lookup', 'best fit'], 'best fit');
-  var resolved;
-  if (matcher === 'lookup') {
-    resolved = lookupMatcher(service, requestedLocales);
-  } else {
-    resolved = bestFitMatcher(service, requestedLocales);
-  }
-
-  return resolved;
-}
-
-
-/**
- * Returns best matched supported locale and extension info using basic
- * lookup algorithm.
- */
-function lookupMatcher(service, requestedLocales) {
-  if (service.match(SERVICE_RE) === null) {
-    throw new Error('Internal error, wrong service type: ' + service);
-  }
-
-  // Cache these, they don't ever change per service.
-  if (AVAILABLE_LOCALES[service] === undefined) {
-    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
-  }
-
-  for (var i = 0; i < requestedLocales.length; ++i) {
-    // Remove all extensions.
-    var locale = requestedLocales[i].replace(ANY_EXTENSION_RE, '');
-    do {
-      if (AVAILABLE_LOCALES[service][locale] !== undefined) {
-        // Return the resolved locale and extension.
-        var extensionMatch = requestedLocales[i].match(UNICODE_EXTENSION_RE);
-        var extension = (extensionMatch === null) ? '' : extensionMatch[0];
-        return {'locale': locale, 'extension': extension, 'position': i};
-      }
-      // Truncate locale if possible.
-      var pos = locale.lastIndexOf('-');
-      if (pos === -1) {
-        break;
-      }
-      locale = locale.substring(0, pos);
-    } while (true);
-  }
-
-  // Didn't find a match, return default.
-  if (DEFAULT_ICU_LOCALE === undefined) {
-    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
-  }
-
-  return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
-}
-
-
-/**
- * Returns best matched supported locale and extension info using
- * implementation dependend algorithm.
- */
-function bestFitMatcher(service, requestedLocales) {
-  // TODO(cira): implement better best fit algorithm.
-  return lookupMatcher(service, requestedLocales);
-}
-
-
-/**
- * Parses Unicode extension into key - value map.
- * Returns empty object if the extension string is invalid.
- * We are not concerned with the validity of the values at this point.
- */
-function parseExtension(extension) {
-  var extensionSplit = extension.split('-');
-
-  // Assume ['', 'u', ...] input, but don't throw.
-  if (extensionSplit.length <= 2 ||
-      (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
-    return {};
-  }
-
-  // Key is {2}alphanum, value is {3,8}alphanum.
-  // Some keys may not have explicit values (booleans).
-  var extensionMap = {};
-  var previousKey = undefined;
-  for (var i = 2; i < extensionSplit.length; ++i) {
-    var length = extensionSplit[i].length;
-    var element = extensionSplit[i];
-    if (length === 2) {
-      extensionMap[element] = undefined;
-      previousKey = element;
-    } else if (length >= 3 && length <=8 && previousKey !== undefined) {
-      extensionMap[previousKey] = element;
-      previousKey = undefined;
-    } else {
-      // There is a value that's too long, or that doesn't have a key.
-      return {};
-    }
-  }
-
-  return extensionMap;
-}
-
-
-/**
- * Converts parameter to an Object if possible.
- */
-function toObject(value) {
-  if (value === undefined || value === null) {
-    throw new TypeError('Value cannot be converted to an Object.');
-  }
-
-  return Object(value);
-}
-
-
-/**
- * Populates internalOptions object with boolean key-value pairs
- * from extensionMap and options.
- * Returns filtered extension (number and date format constructors use
- * Unicode extensions for passing parameters to ICU).
- * It's used for extension-option pairs only, e.g. kn-normalization, but not
- * for 'sensitivity' since it doesn't have extension equivalent.
- * Extensions like nu and ca don't have options equivalent, so we place
- * undefined in the map.property to denote that.
- */
-function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
-  var extension = '';
-
-  var updateExtension = function updateExtension(key, value) {
-    return '-' + key + '-' + String(value);
-  }
-
-  var updateProperty = function updateProperty(property, type, value) {
-    if (type === 'boolean' && (typeof value === 'string')) {
-      value = (value === 'true') ? true : false;
-    }
-
-    if (property !== undefined) {
-      defineWEProperty(outOptions, property, value);
-    }
-  }
-
-  for (var key in keyValues) {
-    if (keyValues.hasOwnProperty(key)) {
-      var value = undefined;
-      var map = keyValues[key];
-      if (map.property !== undefined) {
-        // This may return true if user specifies numeric: 'false', since
-        // Boolean('nonempty') === true.
-        value = getOption(map.property, map.type, map.values);
-      }
-      if (value !== undefined) {
-        updateProperty(map.property, map.type, value);
-        extension += updateExtension(key, value);
-        continue;
-      }
-      // User options didn't have it, check Unicode extension.
-      // Here we want to convert strings 'true', 'false' into proper Boolean
-      // values (not a user error).
-      if (extensionMap.hasOwnProperty(key)) {
-        value = extensionMap[key];
-        if (value !== undefined) {
-          updateProperty(map.property, map.type, value);
-          extension += updateExtension(key, value);
-        } else if (map.type === 'boolean') {
-          // Boolean keys are allowed not to have values in Unicode extension.
-          // Those default to true.
-          updateProperty(map.property, map.type, true);
-          extension += updateExtension(key, true);
-        }
-      }
-    }
-  }
-
-  return extension === ''? '' : '-u' + extension;
-}
-
-
-/**
- * Converts all OwnProperties into
- * configurable: false, writable: false, enumerable: true.
- */
-function freezeArray(array) {
-  array.forEach(function(element, index) {
-    Object.defineProperty(array, index, {value: element,
-                                         configurable: false,
-                                         writable: false,
-                                         enumerable: true});
-  });
-
-  Object.defineProperty(array, 'length', {value: array.length,
-                                          writable: false});
-
-  return array;
-}
-
-
-/**
- * It's sometimes desireable to leave user requested locale instead of ICU
- * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter
- * one, if that was what user requested).
- * This function returns user specified tag if its maximized form matches ICU
- * resolved locale. If not we return ICU result.
- */
-function getOptimalLanguageTag(original, resolved) {
-  // Returns Array<Object>, where each object has maximized and base properties.
-  // Maximized: zh -> zh-Hans-CN
-  // Base: zh-CN-u-ca-gregory -> zh-CN
-  // Take care of grandfathered or simple cases.
-  if (original === resolved) {
-    return original;
-  }
-
-  var locales = %GetLanguageTagVariants([original, resolved]);
-  if (locales[0].maximized !== locales[1].maximized) {
-    return resolved;
-  }
-
-  // Preserve extensions of resolved locale, but swap base tags with original.
-  var resolvedBase = new RegExp('^' + locales[1].base);
-  return resolved.replace(resolvedBase, locales[0].base);
-}
-
-
-/**
- * Returns an Object that contains all of supported locales for a given
- * service.
- * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ
- * that is supported. This is required by the spec.
- */
-function getAvailableLocalesOf(service) {
-  var available = %AvailableLocalesOf(service);
-
-  for (var i in available) {
-    if (available.hasOwnProperty(i)) {
-      var parts = i.match(/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/);
-      if (parts !== null) {
-        // Build xx-ZZ. We don't care about the actual value,
-        // as long it's not undefined.
-        available[parts[1] + '-' + parts[3]] = null;
-      }
-    }
-  }
-
-  return available;
-}
-
-
-/**
- * Defines a property and sets writable and enumerable to true.
- * Configurable is false by default.
- */
-function defineWEProperty(object, property, value) {
-  Object.defineProperty(object, property,
-                        {value: value, writable: true, enumerable: true});
-}
-
-
-/**
- * Adds property to an object if the value is not undefined.
- * Sets configurable descriptor to false.
- */
-function addWEPropertyIfDefined(object, property, value) {
-  if (value !== undefined) {
-    defineWEProperty(object, property, value);
-  }
-}
-
-
-/**
- * Defines a property and sets writable, enumerable and configurable to true.
- */
-function defineWECProperty(object, property, value) {
-  Object.defineProperty(object, property,
-                        {value: value,
-                         writable: true,
-                         enumerable: true,
-                         configurable: true});
-}
-
-
-/**
- * Adds property to an object if the value is not undefined.
- * Sets all descriptors to true.
- */
-function addWECPropertyIfDefined(object, property, value) {
-  if (value !== undefined) {
-    defineWECProperty(object, property, value);
-  }
-}
-
-
-/**
- * Returns titlecased word, aMeRricA -> America.
- */
-function toTitleCaseWord(word) {
-  return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase();
-}
diff --git a/src/extensions/i18n/locale.js b/src/extensions/i18n/locale.js
deleted file mode 100644
index e478327..0000000
--- a/src/extensions/i18n/locale.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Canonicalizes the language tag, or throws in case the tag is invalid.
- */
-function canonicalizeLanguageTag(localeID) {
-  // null is typeof 'object' so we have to do extra check.
-  if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
-      localeID === null) {
-    throw new TypeError('Language ID should be string or object.');
-  }
-
-  var localeString = String(localeID);
-
-  if (isValidLanguageTag(localeString) === false) {
-    throw new RangeError('Invalid language tag: ' + localeString);
-  }
-
-  // This call will strip -kn but not -kn-true extensions.
-  // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
-  // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
-  // upgrade to ICU 4.9.
-  var tag = %CanonicalizeLanguageTag(localeString);
-  if (tag === 'invalid-tag') {
-    throw new RangeError('Invalid language tag: ' + localeString);
-  }
-
-  return tag;
-}
-
-
-/**
- * Returns an array where all locales are canonicalized and duplicates removed.
- * Throws on locales that are not well formed BCP47 tags.
- */
-function initializeLocaleList(locales) {
-  var seen = [];
-  if (locales === undefined) {
-    // Constructor is called without arguments.
-    seen = [];
-  } else {
-    // We allow single string localeID.
-    if (typeof locales === 'string') {
-      seen.push(canonicalizeLanguageTag(locales));
-      return freezeArray(seen);
-    }
-
-    var o = toObject(locales);
-    // Converts it to UInt32 (>>> is shr on 32bit integers).
-    var len = o.length >>> 0;
-
-    for (var k = 0; k < len; k++) {
-      if (k in o) {
-        var value = o[k];
-
-        var tag = canonicalizeLanguageTag(value);
-
-        if (seen.indexOf(tag) === -1) {
-          seen.push(tag);
-        }
-      }
-    }
-  }
-
-  return freezeArray(seen);
-}
-
-
-/**
- * Validates the language tag. Section 2.2.9 of the bcp47 spec
- * defines a valid tag.
- *
- * ICU is too permissible and lets invalid tags, like
- * hant-cmn-cn, through.
- *
- * Returns false if the language tag is invalid.
- */
-function isValidLanguageTag(locale) {
-  // Check if it's well-formed, including grandfadered tags.
-  if (LANGUAGE_TAG_RE.test(locale) === false) {
-    return false;
-  }
-
-  // Just return if it's a x- form. It's all private.
-  if (locale.indexOf('x-') === 0) {
-    return true;
-  }
-
-  // Check if there are any duplicate variants or singletons (extensions).
-
-  // Remove private use section.
-  locale = locale.split(/-x-/)[0];
-
-  // Skip language since it can match variant regex, so we start from 1.
-  // We are matching i-klingon here, but that's ok, since i-klingon-klingon
-  // is not valid and would fail LANGUAGE_TAG_RE test.
-  var variants = [];
-  var extensions = [];
-  var parts = locale.split(/-/);
-  for (var i = 1; i < parts.length; i++) {
-    var value = parts[i];
-    if (LANGUAGE_VARIANT_RE.test(value) === true && extensions.length === 0) {
-      if (variants.indexOf(value) === -1) {
-        variants.push(value);
-      } else {
-        return false;
-      }
-    }
-
-    if (LANGUAGE_SINGLETON_RE.test(value) === true) {
-      if (extensions.indexOf(value) === -1) {
-        extensions.push(value);
-      } else {
-        return false;
-      }
-    }
-  }
-
-  return true;
- }
-
-
-/**
- * Builds a regular expresion that validates the language tag
- * against bcp47 spec.
- * Uses http://tools.ietf.org/html/bcp47, section 2.1, ABNF.
- * Runs on load and initializes the global REs.
- */
-(function() {
-  var alpha = '[a-zA-Z]';
-  var digit = '[0-9]';
-  var alphanum = '(' + alpha + '|' + digit + ')';
-  var regular = '(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|' +
-                'zh-min|zh-min-nan|zh-xiang)';
-  var irregular = '(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|' +
-                  'i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|' +
-                  'i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)';
-  var grandfathered = '(' + irregular + '|' + regular + ')';
-  var privateUse = '(x(-' + alphanum + '{1,8})+)';
-
-  var singleton = '(' + digit + '|[A-WY-Za-wy-z])';
-  LANGUAGE_SINGLETON_RE = new RegExp('^' + singleton + '$', 'i');
-
-  var extension = '(' + singleton + '(-' + alphanum + '{2,8})+)';
-
-  var variant = '(' + alphanum + '{5,8}|(' + digit + alphanum + '{3}))';
-  LANGUAGE_VARIANT_RE = new RegExp('^' + variant + '$', 'i');
-
-  var region = '(' + alpha + '{2}|' + digit + '{3})';
-  var script = '(' + alpha + '{4})';
-  var extLang = '(' + alpha + '{3}(-' + alpha + '{3}){0,2})';
-  var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' +
-                 alpha + '{5,8})';
-  var langTag = language + '(-' + script + ')?(-' + region + ')?(-' +
-                variant + ')*(-' + extension + ')*(-' + privateUse + ')?';
-
-  var languageTag =
-      '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$';
-  LANGUAGE_TAG_RE = new RegExp(languageTag, 'i');
-})();
diff --git a/src/extensions/i18n/number-format.js b/src/extensions/i18n/number-format.js
deleted file mode 100644
index 5722a5d..0000000
--- a/src/extensions/i18n/number-format.js
+++ /dev/null
@@ -1,289 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Verifies that the input is a well-formed ISO 4217 currency code.
- * Don't uppercase to test. It could convert invalid code into a valid one.
- * For example \u00DFP (Eszett+P) becomes SSP.
- */
-function isWellFormedCurrencyCode(currency) {
-  return typeof currency == "string" &&
-      currency.length == 3 &&
-      currency.match(/[^A-Za-z]/) == null;
-}
-
-
-/**
- * Returns the valid digit count for a property, or throws RangeError on
- * a value out of the range.
- */
-function getNumberOption(options, property, min, max, fallback) {
-  var value = options[property];
-  if (value !== undefined) {
-    value = Number(value);
-    if (isNaN(value) || value < min || value > max) {
-      throw new RangeError(property + ' value is out of range.');
-    }
-    return Math.floor(value);
-  }
-
-  return fallback;
-}
-
-
-/**
- * Initializes the given object so it's a valid NumberFormat instance.
- * Useful for subclassing.
- */
-function initializeNumberFormat(numberFormat, locales, options) {
-  if (numberFormat.hasOwnProperty('__initializedIntlObject')) {
-    throw new TypeError('Trying to re-initialize NumberFormat object.');
-  }
-
-  if (options === undefined) {
-    options = {};
-  }
-
-  var getOption = getGetOption(options, 'numberformat');
-
-  var locale = resolveLocale('numberformat', locales, options);
-
-  var internalOptions = {};
-  defineWEProperty(internalOptions, 'style', getOption(
-    'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
-
-  var currency = getOption('currency', 'string');
-  if (currency !== undefined && !isWellFormedCurrencyCode(currency)) {
-    throw new RangeError('Invalid currency code: ' + currency);
-  }
-
-  if (internalOptions.style === 'currency' && currency === undefined) {
-    throw new TypeError('Currency code is required with currency style.');
-  }
-
-  var currencyDisplay = getOption(
-      'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
-  if (internalOptions.style === 'currency') {
-    defineWEProperty(internalOptions, 'currency', currency.toUpperCase());
-    defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
-  }
-
-  // Digit ranges.
-  var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
-  defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
-
-  var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
-  defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
-
-  var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3);
-  defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
-
-  var mnsd = options['minimumSignificantDigits'];
-  var mxsd = options['maximumSignificantDigits'];
-  if (mnsd !== undefined || mxsd !== undefined) {
-    mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0);
-    defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
-
-    mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
-    defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
-  }
-
-  // Grouping.
-  defineWEProperty(internalOptions, 'useGrouping', getOption(
-    'useGrouping', 'boolean', undefined, true));
-
-  // ICU prefers options to be passed using -u- extension key/values for
-  // number format, so we need to build that.
-  var extensionMap = parseExtension(locale.extension);
-  var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
-                             getOption, internalOptions);
-
-  var requestedLocale = locale.locale + extension;
-  var resolved = Object.defineProperties({}, {
-    currency: {writable: true},
-    currencyDisplay: {writable: true},
-    locale: {writable: true},
-    maximumFractionDigits: {writable: true},
-    minimumFractionDigits: {writable: true},
-    minimumIntegerDigits: {writable: true},
-    numberingSystem: {writable: true},
-    requestedLocale: {value: requestedLocale, writable: true},
-    style: {value: internalOptions.style, writable: true},
-    useGrouping: {writable: true}
-  });
-  if (internalOptions.hasOwnProperty('minimumSignificantDigits')) {
-    defineWEProperty(resolved, 'minimumSignificantDigits', undefined);
-  }
-  if (internalOptions.hasOwnProperty('maximumSignificantDigits')) {
-    defineWEProperty(resolved, 'maximumSignificantDigits', undefined);
-  }
-  var formatter = %CreateNumberFormat(requestedLocale,
-                                      internalOptions,
-                                      resolved);
-
-  // We can't get information about number or currency style from ICU, so we
-  // assume user request was fulfilled.
-  if (internalOptions.style === 'currency') {
-    Object.defineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
-                                                        writable: true});
-  }
-
-  Object.defineProperty(numberFormat, 'formatter', {value: formatter});
-  Object.defineProperty(numberFormat, 'resolved', {value: resolved});
-  Object.defineProperty(numberFormat, '__initializedIntlObject',
-                        {value: 'numberformat'});
-
-  return numberFormat;
-}
-
-
-/**
- * Constructs Intl.NumberFormat object given optional locales and options
- * parameters.
- *
- * @constructor
- */
-%SetProperty(Intl, 'NumberFormat', function() {
-    var locales = arguments[0];
-    var options = arguments[1];
-
-    if (!this || this === Intl) {
-      // Constructor is called as a function.
-      return new Intl.NumberFormat(locales, options);
-    }
-
-    return initializeNumberFormat(toObject(this), locales, options);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-
-
-/**
- * NumberFormat resolvedOptions method.
- */
-%SetProperty(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'numberformat') {
-      throw new TypeError('resolvedOptions method called on a non-object' +
-          ' or on a object that is not Intl.NumberFormat.');
-    }
-
-    var format = this;
-    var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
-                                       format.resolved.locale);
-
-    var result = {
-      locale: locale,
-      numberingSystem: format.resolved.numberingSystem,
-      style: format.resolved.style,
-      useGrouping: format.resolved.useGrouping,
-      minimumIntegerDigits: format.resolved.minimumIntegerDigits,
-      minimumFractionDigits: format.resolved.minimumFractionDigits,
-      maximumFractionDigits: format.resolved.maximumFractionDigits,
-    };
-
-    if (result.style === 'currency') {
-      defineWECProperty(result, 'currency', format.resolved.currency);
-      defineWECProperty(result, 'currencyDisplay',
-                        format.resolved.currencyDisplay);
-    }
-
-    if (format.resolved.hasOwnProperty('minimumSignificantDigits')) {
-      defineWECProperty(result, 'minimumSignificantDigits',
-                        format.resolved.minimumSignificantDigits);
-    }
-
-    if (format.resolved.hasOwnProperty('maximumSignificantDigits')) {
-      defineWECProperty(result, 'maximumSignificantDigits',
-                        format.resolved.maximumSignificantDigits);
-    }
-
-    return result;
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.NumberFormat.prototype.resolvedOptions,
-                 'resolvedOptions');
-%FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions);
-%SetNativeFlag(Intl.NumberFormat.prototype.resolvedOptions);
-
-
-/**
- * Returns the subset of the given locale list for which this locale list
- * has a matching (possibly fallback) locale. Locales appear in the same
- * order in the returned list as in the input list.
- * Options are optional parameter.
- */
-%SetProperty(Intl.NumberFormat, 'supportedLocalesOf', function(locales) {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    return supportedLocalesOf('numberformat', locales, arguments[1]);
-  },
-  ATTRIBUTES.DONT_ENUM
-);
-%FunctionSetName(Intl.NumberFormat.supportedLocalesOf, 'supportedLocalesOf');
-%FunctionRemovePrototype(Intl.NumberFormat.supportedLocalesOf);
-%SetNativeFlag(Intl.NumberFormat.supportedLocalesOf);
-
-
-/**
- * Returns a String value representing the result of calling ToNumber(value)
- * according to the effective locale and the formatting options of this
- * NumberFormat.
- */
-function formatNumber(formatter, value) {
-  // Spec treats -0 and +0 as 0.
-  var number = Number(value);
-  if (number === -0) {
-    number = 0;
-  }
-
-  return %InternalNumberFormat(formatter.formatter, number);
-}
-
-
-/**
- * Returns a Number that represents string value that was passed in.
- */
-function parseNumber(formatter, value) {
-  return %InternalNumberParse(formatter.formatter, String(value));
-}
-
-
-addBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
-addBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
diff --git a/src/extensions/i18n/overrides.js b/src/extensions/i18n/overrides.js
deleted file mode 100644
index b2d60b3..0000000
--- a/src/extensions/i18n/overrides.js
+++ /dev/null
@@ -1,220 +0,0 @@
-// 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.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-
-// Save references to Intl objects and methods we use, for added security.
-var savedObjects = {
-  'collator': Intl.Collator,
-  'numberformat': Intl.NumberFormat,
-  'dateformatall': Intl.DateTimeFormat,
-  'dateformatdate': Intl.DateTimeFormat,
-  'dateformattime': Intl.DateTimeFormat
-};
-
-
-// Default (created with undefined locales and options parameters) collator,
-// number and date format instances. They'll be created as needed.
-var defaultObjects = {
-  'collator': undefined,
-  'numberformat': undefined,
-  'dateformatall': undefined,
-  'dateformatdate': undefined,
-  'dateformattime': undefined,
-};
-
-
-/**
- * Returns cached or newly created instance of a given service.
- * We cache only default instances (where no locales or options are provided).
- */
-function cachedOrNewService(service, locales, options, defaults) {
-  var useOptions = (defaults === undefined) ? options : defaults;
-  if (locales === undefined && options === undefined) {
-    if (defaultObjects[service] === undefined) {
-      defaultObjects[service] = new savedObjects[service](locales, useOptions);
-    }
-    return defaultObjects[service];
-  }
-  return new savedObjects[service](locales, useOptions);
-}
-
-
-/**
- * Compares this and that, and returns less than 0, 0 or greater than 0 value.
- * Overrides the built-in method.
- */
-Object.defineProperty(String.prototype, 'localeCompare', {
-  value: function(that) {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (this === undefined || this === null) {
-      throw new TypeError('Method invoked on undefined or null value.');
-    }
-
-    var locales = arguments[1];
-    var options = arguments[2];
-    var collator = cachedOrNewService('collator', locales, options);
-    return compare(collator, this, that);
-  },
-  writable: true,
-  configurable: true,
-  enumerable: false
-});
-%FunctionSetName(String.prototype.localeCompare, 'localeCompare');
-%FunctionRemovePrototype(String.prototype.localeCompare);
-%SetNativeFlag(String.prototype.localeCompare);
-
-
-/**
- * Formats a Number object (this) using locale and options values.
- * If locale or options are omitted, defaults are used.
- */
-Object.defineProperty(Number.prototype, 'toLocaleString', {
-  value: function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    if (!(this instanceof Number) && typeof(this) !== 'number') {
-      throw new TypeError('Method invoked on an object that is not Number.');
-    }
-
-    var locales = arguments[0];
-    var options = arguments[1];
-    var numberFormat = cachedOrNewService('numberformat', locales, options);
-    return formatNumber(numberFormat, this);
-  },
-  writable: true,
-  configurable: true,
-  enumerable: false
-});
-%FunctionSetName(Number.prototype.toLocaleString, 'toLocaleString');
-%FunctionRemovePrototype(Number.prototype.toLocaleString);
-%SetNativeFlag(Number.prototype.toLocaleString);
-
-
-/**
- * Returns actual formatted date or fails if date parameter is invalid.
- */
-function toLocaleDateTime(date, locales, options, required, defaults, service) {
-  if (!(date instanceof Date)) {
-    throw new TypeError('Method invoked on an object that is not Date.');
-  }
-
-  if (isNaN(date)) {
-    return 'Invalid Date';
-  }
-
-  var internalOptions = toDateTimeOptions(options, required, defaults);
-
-  var dateFormat =
-      cachedOrNewService(service, locales, options, internalOptions);
-
-  return formatDate(dateFormat, date);
-}
-
-
-/**
- * Formats a Date object (this) using locale and options values.
- * If locale or options are omitted, defaults are used - both date and time are
- * present in the output.
- */
-Object.defineProperty(Date.prototype, 'toLocaleString', {
-  value: function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    var locales = arguments[0];
-    var options = arguments[1];
-    return toLocaleDateTime(
-        this, locales, options, 'any', 'all', 'dateformatall');
-  },
-  writable: true,
-  configurable: true,
-  enumerable: false
-});
-%FunctionSetName(Date.prototype.toLocaleString, 'toLocaleString');
-%FunctionRemovePrototype(Date.prototype.toLocaleString);
-%SetNativeFlag(Date.prototype.toLocaleString);
-
-
-/**
- * Formats a Date object (this) using locale and options values.
- * If locale or options are omitted, defaults are used - only date is present
- * in the output.
- */
-Object.defineProperty(Date.prototype, 'toLocaleDateString', {
-  value: function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    var locales = arguments[0];
-    var options = arguments[1];
-    return toLocaleDateTime(
-        this, locales, options, 'date', 'date', 'dateformatdate');
-  },
-  writable: true,
-  configurable: true,
-  enumerable: false
-});
-%FunctionSetName(Date.prototype.toLocaleDateString, 'toLocaleDateString');
-%FunctionRemovePrototype(Date.prototype.toLocaleDateString);
-%SetNativeFlag(Date.prototype.toLocaleDateString);
-
-
-/**
- * Formats a Date object (this) using locale and options values.
- * If locale or options are omitted, defaults are used - only time is present
- * in the output.
- */
-Object.defineProperty(Date.prototype, 'toLocaleTimeString', {
-  value: function() {
-    if (%_IsConstructCall()) {
-      throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
-    }
-
-    var locales = arguments[0];
-    var options = arguments[1];
-    return toLocaleDateTime(
-        this, locales, options, 'time', 'time', 'dateformattime');
-  },
-  writable: true,
-  configurable: true,
-  enumerable: false
-});
-%FunctionSetName(Date.prototype.toLocaleTimeString, 'toLocaleTimeString');
-%FunctionRemovePrototype(Date.prototype.toLocaleTimeString);
-%SetNativeFlag(Date.prototype.toLocaleTimeString);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 7548c01..cc153af 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -401,7 +401,6 @@
             "enable use of constant pools for double immediate (ARM only)")
 
 // bootstrapper.cc
-DEFINE_bool(enable_i18n, true, "enable i18n extension")
 DEFINE_string(expose_natives_as, NULL, "expose natives in global object")
 DEFINE_string(expose_debug_as, NULL, "expose debug in global object")
 DEFINE_bool(expose_gc, false, "expose gc extension")
diff --git a/src/globals.h b/src/globals.h
index 992f3a8..1977e68 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -342,9 +342,9 @@
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
 
-// Newly written code should use V8_INLINE() and V8_NOINLINE() directly.
-#define INLINE(declarator)    V8_INLINE(declarator)
-#define NO_INLINE(declarator) V8_NOINLINE(declarator)
+// Newly written code should use V8_INLINE and V8_NOINLINE directly.
+#define INLINE(declarator)    V8_INLINE declarator
+#define NO_INLINE(declarator) V8_NOINLINE declarator
 
 
 // Newly written code should use V8_WARN_UNUSED_RESULT.
diff --git a/src/heap.cc b/src/heap.cc
index 0455a84..24e4039 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4371,7 +4371,7 @@
 
   if (!function->shared()->is_generator()) {
     MaybeObject* maybe_failure =
-        JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes(
+        JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributesTrampoline(
             constructor_string(), function, DONT_ENUM);
     if (maybe_failure->IsFailure()) return maybe_failure;
   }
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 7b623b5..23c373f 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4005,7 +4005,9 @@
 
 
 static bool CanInlinePropertyAccess(Map* type) {
-  return !type->is_dictionary_map() && !type->has_named_interceptor();
+  return type->IsJSObjectMap() &&
+      !type->is_dictionary_map() &&
+      !type->has_named_interceptor();
 }
 
 
@@ -5381,6 +5383,7 @@
   map->LookupDescriptor(NULL, *name, &lookup);
   if (lookup.IsField()) {
     HCheckMaps* checked_object = AddCheckMap(object, map);
+    ASSERT(map->IsJSObjectMap());
     return BuildLoadNamedField(
         checked_object, HObjectAccess::ForField(map, &lookup, name));
   }
@@ -5392,6 +5395,12 @@
     return New<HConstant>(constant);
   }
 
+  if (lookup.IsFound()) {
+    // Cannot handle the property, do a generic load instead.
+    HValue* context = environment()->context();
+    return new(zone()) HLoadNamedGeneric(context, object, name);
+  }
+
   // Handle a load from a known field somewhere in the prototype chain.
   LookupInPrototypes(map, name, &lookup);
   if (lookup.IsField()) {
@@ -5484,6 +5493,7 @@
   Handle<Map> most_general_consolidated_map;
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
+    if (!map->IsJSObjectMap()) return NULL;
     // Don't allow mixing of JSArrays with JSObjects.
     if (map->instance_type() == JS_ARRAY_TYPE) {
       if (has_non_js_array_access) return NULL;
@@ -5536,7 +5546,7 @@
     HValue* object,
     HValue* key,
     HValue* val,
-    Expression* prop,
+    SmallMapList* maps,
     BailoutId ast_id,
     int position,
     bool is_store,
@@ -5544,7 +5554,6 @@
     bool* has_side_effects) {
   *has_side_effects = false;
   BuildCheckHeapObject(object);
-  SmallMapList* maps = prop->GetReceiverTypes();
 
   if (!is_store) {
     HInstruction* consolidated_load =
@@ -5600,7 +5609,8 @@
   if (untransitionable_maps.length() == 1) {
     Handle<Map> untransitionable_map = untransitionable_maps[0];
     HInstruction* instr = NULL;
-    if (untransitionable_map->has_slow_elements_kind()) {
+    if (untransitionable_map->has_slow_elements_kind() ||
+        !untransitionable_map->IsJSObjectMap()) {
       instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val)
                                       : BuildLoadKeyedGeneric(object, key));
     } else {
@@ -5617,6 +5627,7 @@
 
   for (int i = 0; i < untransitionable_maps.length(); ++i) {
     Handle<Map> map = untransitionable_maps[i];
+    if (!map->IsJSObjectMap()) continue;
     ElementsKind elements_kind = map->elements_kind();
     HBasicBlock* this_map = graph()->CreateBasicBlock();
     HBasicBlock* other_map = graph()->CreateBasicBlock();
@@ -5689,10 +5700,9 @@
       instr = BuildMonomorphicElementAccess(
           obj, key, val, NULL, map, is_store, expr->GetStoreMode());
     }
-  } else if (expr->GetReceiverTypes() != NULL &&
-             !expr->GetReceiverTypes()->is_empty()) {
+  } else if (types != NULL && !types->is_empty()) {
     return HandlePolymorphicElementAccess(
-        obj, key, val, expr, ast_id, position, is_store,
+        obj, key, val, types, ast_id, position, is_store,
         expr->GetStoreMode(), has_side_effects);
   } else {
     if (is_store) {
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 979a350..c1dafa8 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -2008,7 +2008,7 @@
   HValue* HandlePolymorphicElementAccess(HValue* object,
                                          HValue* key,
                                          HValue* val,
-                                         Expression* prop,
+                                         SmallMapList* maps,
                                          BailoutId ast_id,
                                          int position,
                                          bool is_store,
diff --git a/src/i18n.js b/src/i18n.js
new file mode 100644
index 0000000..1798bbb
--- /dev/null
+++ b/src/i18n.js
@@ -0,0 +1,2116 @@
+// 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.
+// limitations under the License.
+
+// ECMAScript 402 API implementation.
+
+/**
+ * Intl object is a single object that has some named properties,
+ * all of which are constructors.
+ */
+$Object.defineProperty(global, "Intl", { enumerable: false, value: (function() {
+
+'use strict';
+
+var Intl = {};
+
+var undefined = global.undefined;
+
+var AVAILABLE_SERVICES = ['collator',
+                          'numberformat',
+                          'dateformat',
+                          'breakiterator'];
+
+/**
+ * Caches available locales for each service.
+ */
+var AVAILABLE_LOCALES = {
+  'collator': undefined,
+  'numberformat': undefined,
+  'dateformat': undefined,
+  'breakiterator': undefined
+};
+
+/**
+ * Caches default ICU locale.
+ */
+var DEFAULT_ICU_LOCALE = undefined;
+
+/**
+ * Unicode extension regular expression.
+ */
+var UNICODE_EXTENSION_RE = undefined;
+
+function GetUnicodeExtensionRE() {
+  if (UNICODE_EXTENSION_RE === undefined) {
+    UNICODE_EXTENSION_RE = new $RegExp('-u(-[a-z0-9]{2,8})+', 'g');
+  }
+  return UNICODE_EXTENSION_RE;
+}
+
+/**
+ * Matches any Unicode extension.
+ */
+var ANY_EXTENSION_RE = undefined;
+
+function GetAnyExtensionRE() {
+  if (ANY_EXTENSION_RE === undefined) {
+    ANY_EXTENSION_RE = new $RegExp('-[a-z0-9]{1}-.*', 'g');
+  }
+  return ANY_EXTENSION_RE;
+}
+
+/**
+ * Replace quoted text (single quote, anything but the quote and quote again).
+ */
+var QUOTED_STRING_RE = undefined;
+
+function GetQuotedStringRE() {
+  if (QUOTED_STRING_RE === undefined) {
+    QUOTED_STRING_RE = new $RegExp("'[^']+'", 'g');
+  }
+  return QUOTED_STRING_RE;
+}
+
+/**
+ * Matches valid service name.
+ */
+var SERVICE_RE = undefined;
+
+function GetServiceRE() {
+  if (SERVICE_RE === undefined) {
+    SERVICE_RE =
+        new $RegExp('^(collator|numberformat|dateformat|breakiterator)$');
+  }
+  return SERVICE_RE;
+}
+
+/**
+ * Validates a language tag against bcp47 spec.
+ * Actual value is assigned on first run.
+ */
+var LANGUAGE_TAG_RE = undefined;
+
+function GetLanguageTagRE() {
+  if (LANGUAGE_TAG_RE === undefined) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_TAG_RE;
+}
+
+/**
+ * Helps find duplicate variants in the language tag.
+ */
+var LANGUAGE_VARIANT_RE = undefined;
+
+function GetLanguageVariantRE() {
+  if (LANGUAGE_VARIANT_RE === undefined) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_VARIANT_RE;
+}
+
+/**
+ * Helps find duplicate singletons in the language tag.
+ */
+var LANGUAGE_SINGLETON_RE = undefined;
+
+function GetLanguageSingletonRE() {
+  if (LANGUAGE_SINGLETON_RE === undefined) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_SINGLETON_RE;
+}
+
+/**
+ * Matches valid IANA time zone names.
+ */
+var TIMEZONE_NAME_CHECK_RE = undefined;
+
+function GetTimezoneNameCheckRE() {
+  if (TIMEZONE_NAME_CHECK_RE === undefined) {
+    TIMEZONE_NAME_CHECK_RE =
+        new $RegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
+  }
+  return TIMEZONE_NAME_CHECK_RE;
+}
+
+/**
+ * Maps ICU calendar names into LDML type.
+ */
+var ICU_CALENDAR_MAP = {
+  'gregorian': 'gregory',
+  'japanese': 'japanese',
+  'buddhist': 'buddhist',
+  'roc': 'roc',
+  'persian': 'persian',
+  'islamic-civil': 'islamicc',
+  'islamic': 'islamic',
+  'hebrew': 'hebrew',
+  'chinese': 'chinese',
+  'indian': 'indian',
+  'coptic': 'coptic',
+  'ethiopic': 'ethiopic',
+  'ethiopic-amete-alem': 'ethioaa'
+};
+
+/**
+ * Map of Unicode extensions to option properties, and their values and types,
+ * for a collator.
+ */
+var COLLATOR_KEY_MAP = {
+  'kn': {'property': 'numeric', 'type': 'boolean'},
+  'kf': {'property': 'caseFirst', 'type': 'string',
+         'values': ['false', 'lower', 'upper']}
+};
+
+/**
+ * Map of Unicode extensions to option properties, and their values and types,
+ * for a number format.
+ */
+var NUMBER_FORMAT_KEY_MAP = {
+  'nu': {'property': undefined, 'type': 'string'}
+};
+
+/**
+ * Map of Unicode extensions to option properties, and their values and types,
+ * for a date/time format.
+ */
+var DATETIME_FORMAT_KEY_MAP = {
+  'ca': {'property': undefined, 'type': 'string'},
+  'nu': {'property': undefined, 'type': 'string'}
+};
+
+/**
+ * Allowed -u-co- values. List taken from:
+ * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml
+ */
+var ALLOWED_CO_VALUES = [
+  'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic',
+  'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin'
+];
+
+/**
+ * Error message for when function object is created with new and it's not
+ * a constructor.
+ */
+var ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR =
+  'Function object that\'s not a constructor was created with new';
+
+
+/**
+ * Adds bound method to the prototype of the given object.
+ */
+function addBoundMethod(obj, methodName, implementation, length) {
+  function getter() {
+    if (!this || typeof this !== 'object' ||
+        this.__initializedIntlObject === undefined) {
+        throw new $TypeError('Method ' + methodName + ' called on a ' +
+                            'non-object or on a wrong type of object.');
+    }
+    var internalName = '__bound' + methodName + '__';
+    if (this[internalName] === undefined) {
+      var that = this;
+      var boundMethod;
+      if (length === undefined || length === 2) {
+        boundMethod = function(x, y) {
+          if (%_IsConstructCall()) {
+            throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+          }
+          return implementation(that, x, y);
+        }
+      } else if (length === 1) {
+        boundMethod = function(x) {
+          if (%_IsConstructCall()) {
+            throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+          }
+          return implementation(that, x);
+        }
+      } else {
+        boundMethod = function() {
+          if (%_IsConstructCall()) {
+            throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+          }
+          // DateTimeFormat.format needs to be 0 arg method, but can stil
+          // receive optional dateValue param. If one was provided, pass it
+          // along.
+          if (arguments.length > 0) {
+            return implementation(that, arguments[0]);
+          } else {
+            return implementation(that);
+          }
+        }
+      }
+      %FunctionSetName(boundMethod, internalName);
+      %FunctionRemovePrototype(boundMethod);
+      %SetNativeFlag(boundMethod);
+      this[internalName] = boundMethod;
+    }
+    return this[internalName];
+  }
+
+  %FunctionSetName(getter, methodName);
+  %FunctionRemovePrototype(getter);
+  %SetNativeFlag(getter);
+
+  $Object.defineProperty(obj.prototype, methodName, {
+    get: getter,
+    enumerable: false,
+    configurable: true
+  });
+}
+
+
+/**
+ * Returns an intersection of locales and service supported locales.
+ * Parameter locales is treated as a priority list.
+ */
+function supportedLocalesOf(service, locales, options) {
+  if (service.match(GetServiceRE()) === null) {
+    throw new $Error('Internal error, wrong service type: ' + service);
+  }
+
+  // Provide defaults if matcher was not specified.
+  if (options === undefined) {
+    options = {};
+  } else {
+    options = toObject(options);
+  }
+
+  var matcher = options.localeMatcher;
+  if (matcher !== undefined) {
+    matcher = $String(matcher);
+    if (matcher !== 'lookup' && matcher !== 'best fit') {
+      throw new $RangeError('Illegal value for localeMatcher:' + matcher);
+    }
+  } else {
+    matcher = 'best fit';
+  }
+
+  var requestedLocales = initializeLocaleList(locales);
+
+  // Cache these, they don't ever change per service.
+  if (AVAILABLE_LOCALES[service] === undefined) {
+    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
+  }
+
+  // Use either best fit or lookup algorithm to match locales.
+  if (matcher === 'best fit') {
+    return initializeLocaleList(bestFitSupportedLocalesOf(
+        requestedLocales, AVAILABLE_LOCALES[service]));
+  }
+
+  return initializeLocaleList(lookupSupportedLocalesOf(
+      requestedLocales, AVAILABLE_LOCALES[service]));
+}
+
+
+/**
+ * Returns the subset of the provided BCP 47 language priority list for which
+ * this service has a matching locale when using the BCP 47 Lookup algorithm.
+ * Locales appear in the same order in the returned list as in the input list.
+ */
+function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
+  var matchedLocales = [];
+  for (var i = 0; i < requestedLocales.length; ++i) {
+    // Remove -u- extension.
+    var locale = requestedLocales[i].replace(GetUnicodeExtensionRE(), '');
+    do {
+      if (availableLocales[locale] !== undefined) {
+        // Push requested locale not the resolved one.
+        matchedLocales.push(requestedLocales[i]);
+        break;
+      }
+      // Truncate locale if possible, if not break.
+      var pos = locale.lastIndexOf('-');
+      if (pos === -1) {
+        break;
+      }
+      locale = locale.substring(0, pos);
+    } while (true);
+  }
+
+  return matchedLocales;
+}
+
+
+/**
+ * Returns the subset of the provided BCP 47 language priority list for which
+ * this service has a matching locale when using the implementation
+ * dependent algorithm.
+ * Locales appear in the same order in the returned list as in the input list.
+ */
+function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
+  // TODO(cira): implement better best fit algorithm.
+  return lookupSupportedLocalesOf(requestedLocales, availableLocales);
+}
+
+
+/**
+ * Returns a getOption function that extracts property value for given
+ * options object. If property is missing it returns defaultValue. If value
+ * is out of range for that property it throws RangeError.
+ */
+function getGetOption(options, caller) {
+  if (options === undefined) {
+    throw new $Error('Internal ' + caller + ' error. ' +
+                    'Default options are missing.');
+  }
+
+  var getOption = function getOption(property, type, values, defaultValue) {
+    if (options[property] !== undefined) {
+      var value = options[property];
+      switch (type) {
+        case 'boolean':
+          value = $Boolean(value);
+          break;
+        case 'string':
+          value = $String(value);
+          break;
+        case 'number':
+          value = $Number(value);
+          break;
+        default:
+          throw new $Error('Internal error. Wrong value type.');
+      }
+      if (values !== undefined && values.indexOf(value) === -1) {
+        throw new $RangeError('Value ' + value + ' out of range for ' + caller +
+                             ' options property ' + property);
+      }
+
+      return value;
+    }
+
+    return defaultValue;
+  }
+
+  return getOption;
+}
+
+
+/**
+ * Compares a BCP 47 language priority list requestedLocales against the locales
+ * in availableLocales and determines the best available language to meet the
+ * request. Two algorithms are available to match the locales: the Lookup
+ * algorithm described in RFC 4647 section 3.4, and an implementation dependent
+ * best-fit algorithm. Independent of the locale matching algorithm, options
+ * specified through Unicode locale extension sequences are negotiated
+ * separately, taking the caller's relevant extension keys and locale data as
+ * well as client-provided options into consideration. Returns an object with
+ * a locale property whose value is the language tag of the selected locale,
+ * and properties for each key in relevantExtensionKeys providing the selected
+ * value for that key.
+ */
+function resolveLocale(service, requestedLocales, options) {
+  requestedLocales = initializeLocaleList(requestedLocales);
+
+  var getOption = getGetOption(options, service);
+  var matcher = getOption('localeMatcher', 'string',
+                          ['lookup', 'best fit'], 'best fit');
+  var resolved;
+  if (matcher === 'lookup') {
+    resolved = lookupMatcher(service, requestedLocales);
+  } else {
+    resolved = bestFitMatcher(service, requestedLocales);
+  }
+
+  return resolved;
+}
+
+
+/**
+ * Returns best matched supported locale and extension info using basic
+ * lookup algorithm.
+ */
+function lookupMatcher(service, requestedLocales) {
+  if (service.match(GetServiceRE()) === null) {
+    throw new $Error('Internal error, wrong service type: ' + service);
+  }
+
+  // Cache these, they don't ever change per service.
+  if (AVAILABLE_LOCALES[service] === undefined) {
+    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
+  }
+
+  for (var i = 0; i < requestedLocales.length; ++i) {
+    // Remove all extensions.
+    var locale = requestedLocales[i].replace(GetAnyExtensionRE(), '');
+    do {
+      if (AVAILABLE_LOCALES[service][locale] !== undefined) {
+        // Return the resolved locale and extension.
+        var extensionMatch = requestedLocales[i].match(GetUnicodeExtensionRE());
+        var extension = (extensionMatch === null) ? '' : extensionMatch[0];
+        return {'locale': locale, 'extension': extension, 'position': i};
+      }
+      // Truncate locale if possible.
+      var pos = locale.lastIndexOf('-');
+      if (pos === -1) {
+        break;
+      }
+      locale = locale.substring(0, pos);
+    } while (true);
+  }
+
+  // Didn't find a match, return default.
+  if (DEFAULT_ICU_LOCALE === undefined) {
+    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+  }
+
+  return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+}
+
+
+/**
+ * Returns best matched supported locale and extension info using
+ * implementation dependend algorithm.
+ */
+function bestFitMatcher(service, requestedLocales) {
+  // TODO(cira): implement better best fit algorithm.
+  return lookupMatcher(service, requestedLocales);
+}
+
+
+/**
+ * Parses Unicode extension into key - value map.
+ * Returns empty object if the extension string is invalid.
+ * We are not concerned with the validity of the values at this point.
+ */
+function parseExtension(extension) {
+  var extensionSplit = extension.split('-');
+
+  // Assume ['', 'u', ...] input, but don't throw.
+  if (extensionSplit.length <= 2 ||
+      (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
+    return {};
+  }
+
+  // Key is {2}alphanum, value is {3,8}alphanum.
+  // Some keys may not have explicit values (booleans).
+  var extensionMap = {};
+  var previousKey = undefined;
+  for (var i = 2; i < extensionSplit.length; ++i) {
+    var length = extensionSplit[i].length;
+    var element = extensionSplit[i];
+    if (length === 2) {
+      extensionMap[element] = undefined;
+      previousKey = element;
+    } else if (length >= 3 && length <=8 && previousKey !== undefined) {
+      extensionMap[previousKey] = element;
+      previousKey = undefined;
+    } else {
+      // There is a value that's too long, or that doesn't have a key.
+      return {};
+    }
+  }
+
+  return extensionMap;
+}
+
+
+/**
+ * Converts parameter to an Object if possible.
+ */
+function toObject(value) {
+  if (value === undefined || value === null) {
+    throw new $TypeError('Value cannot be converted to an Object.');
+  }
+
+  return $Object(value);
+}
+
+
+/**
+ * Populates internalOptions object with boolean key-value pairs
+ * from extensionMap and options.
+ * Returns filtered extension (number and date format constructors use
+ * Unicode extensions for passing parameters to ICU).
+ * It's used for extension-option pairs only, e.g. kn-normalization, but not
+ * for 'sensitivity' since it doesn't have extension equivalent.
+ * Extensions like nu and ca don't have options equivalent, so we place
+ * undefined in the map.property to denote that.
+ */
+function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
+  var extension = '';
+
+  var updateExtension = function updateExtension(key, value) {
+    return '-' + key + '-' + $String(value);
+  }
+
+  var updateProperty = function updateProperty(property, type, value) {
+    if (type === 'boolean' && (typeof value === 'string')) {
+      value = (value === 'true') ? true : false;
+    }
+
+    if (property !== undefined) {
+      defineWEProperty(outOptions, property, value);
+    }
+  }
+
+  for (var key in keyValues) {
+    if (keyValues.hasOwnProperty(key)) {
+      var value = undefined;
+      var map = keyValues[key];
+      if (map.property !== undefined) {
+        // This may return true if user specifies numeric: 'false', since
+        // Boolean('nonempty') === true.
+        value = getOption(map.property, map.type, map.values);
+      }
+      if (value !== undefined) {
+        updateProperty(map.property, map.type, value);
+        extension += updateExtension(key, value);
+        continue;
+      }
+      // User options didn't have it, check Unicode extension.
+      // Here we want to convert strings 'true', 'false' into proper Boolean
+      // values (not a user error).
+      if (extensionMap.hasOwnProperty(key)) {
+        value = extensionMap[key];
+        if (value !== undefined) {
+          updateProperty(map.property, map.type, value);
+          extension += updateExtension(key, value);
+        } else if (map.type === 'boolean') {
+          // Boolean keys are allowed not to have values in Unicode extension.
+          // Those default to true.
+          updateProperty(map.property, map.type, true);
+          extension += updateExtension(key, true);
+        }
+      }
+    }
+  }
+
+  return extension === ''? '' : '-u' + extension;
+}
+
+
+/**
+ * Converts all OwnProperties into
+ * configurable: false, writable: false, enumerable: true.
+ */
+function freezeArray(array) {
+  array.forEach(function(element, index) {
+    $Object.defineProperty(array, index, {value: element,
+                                          configurable: false,
+                                          writable: false,
+                                          enumerable: true});
+  });
+
+  $Object.defineProperty(array, 'length', {value: array.length,
+                                           writable: false});
+
+  return array;
+}
+
+
+/**
+ * It's sometimes desireable to leave user requested locale instead of ICU
+ * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter
+ * one, if that was what user requested).
+ * This function returns user specified tag if its maximized form matches ICU
+ * resolved locale. If not we return ICU result.
+ */
+function getOptimalLanguageTag(original, resolved) {
+  // Returns Array<Object>, where each object has maximized and base properties.
+  // Maximized: zh -> zh-Hans-CN
+  // Base: zh-CN-u-ca-gregory -> zh-CN
+  // Take care of grandfathered or simple cases.
+  if (original === resolved) {
+    return original;
+  }
+
+  var locales = %GetLanguageTagVariants([original, resolved]);
+  if (locales[0].maximized !== locales[1].maximized) {
+    return resolved;
+  }
+
+  // Preserve extensions of resolved locale, but swap base tags with original.
+  var resolvedBase = new $RegExp('^' + locales[1].base);
+  return resolved.replace(resolvedBase, locales[0].base);
+}
+
+
+/**
+ * Returns an Object that contains all of supported locales for a given
+ * service.
+ * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ
+ * that is supported. This is required by the spec.
+ */
+function getAvailableLocalesOf(service) {
+  var available = %AvailableLocalesOf(service);
+
+  for (var i in available) {
+    if (available.hasOwnProperty(i)) {
+      var parts = i.match(/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/);
+      if (parts !== null) {
+        // Build xx-ZZ. We don't care about the actual value,
+        // as long it's not undefined.
+        available[parts[1] + '-' + parts[3]] = null;
+      }
+    }
+  }
+
+  return available;
+}
+
+
+/**
+ * Defines a property and sets writable and enumerable to true.
+ * Configurable is false by default.
+ */
+function defineWEProperty(object, property, value) {
+  $Object.defineProperty(object, property,
+                         {value: value, writable: true, enumerable: true});
+}
+
+
+/**
+ * Adds property to an object if the value is not undefined.
+ * Sets configurable descriptor to false.
+ */
+function addWEPropertyIfDefined(object, property, value) {
+  if (value !== undefined) {
+    defineWEProperty(object, property, value);
+  }
+}
+
+
+/**
+ * Defines a property and sets writable, enumerable and configurable to true.
+ */
+function defineWECProperty(object, property, value) {
+  $Object.defineProperty(object, property,
+                         {value: value,
+                          writable: true,
+                          enumerable: true,
+                          configurable: true});
+}
+
+
+/**
+ * Adds property to an object if the value is not undefined.
+ * Sets all descriptors to true.
+ */
+function addWECPropertyIfDefined(object, property, value) {
+  if (value !== undefined) {
+    defineWECProperty(object, property, value);
+  }
+}
+
+
+/**
+ * Returns titlecased word, aMeRricA -> America.
+ */
+function toTitleCaseWord(word) {
+  return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase();
+}
+
+/**
+ * Canonicalizes the language tag, or throws in case the tag is invalid.
+ */
+function canonicalizeLanguageTag(localeID) {
+  // null is typeof 'object' so we have to do extra check.
+  if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+      localeID === null) {
+    throw new $TypeError('Language ID should be string or object.');
+  }
+
+  var localeString = $String(localeID);
+
+  if (isValidLanguageTag(localeString) === false) {
+    throw new $RangeError('Invalid language tag: ' + localeString);
+  }
+
+  // This call will strip -kn but not -kn-true extensions.
+  // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
+  // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
+  // upgrade to ICU 4.9.
+  var tag = %CanonicalizeLanguageTag(localeString);
+  if (tag === 'invalid-tag') {
+    throw new $RangeError('Invalid language tag: ' + localeString);
+  }
+
+  return tag;
+}
+
+
+/**
+ * Returns an array where all locales are canonicalized and duplicates removed.
+ * Throws on locales that are not well formed BCP47 tags.
+ */
+function initializeLocaleList(locales) {
+  var seen = [];
+  if (locales === undefined) {
+    // Constructor is called without arguments.
+    seen = [];
+  } else {
+    // We allow single string localeID.
+    if (typeof locales === 'string') {
+      seen.push(canonicalizeLanguageTag(locales));
+      return freezeArray(seen);
+    }
+
+    var o = toObject(locales);
+    // Converts it to UInt32 (>>> is shr on 32bit integers).
+    var len = o.length >>> 0;
+
+    for (var k = 0; k < len; k++) {
+      if (k in o) {
+        var value = o[k];
+
+        var tag = canonicalizeLanguageTag(value);
+
+        if (seen.indexOf(tag) === -1) {
+          seen.push(tag);
+        }
+      }
+    }
+  }
+
+  return freezeArray(seen);
+}
+
+
+/**
+ * Validates the language tag. Section 2.2.9 of the bcp47 spec
+ * defines a valid tag.
+ *
+ * ICU is too permissible and lets invalid tags, like
+ * hant-cmn-cn, through.
+ *
+ * Returns false if the language tag is invalid.
+ */
+function isValidLanguageTag(locale) {
+  // Check if it's well-formed, including grandfadered tags.
+  if (GetLanguageTagRE().test(locale) === false) {
+    return false;
+  }
+
+  // Just return if it's a x- form. It's all private.
+  if (locale.indexOf('x-') === 0) {
+    return true;
+  }
+
+  // Check if there are any duplicate variants or singletons (extensions).
+
+  // Remove private use section.
+  locale = locale.split(/-x-/)[0];
+
+  // Skip language since it can match variant regex, so we start from 1.
+  // We are matching i-klingon here, but that's ok, since i-klingon-klingon
+  // is not valid and would fail LANGUAGE_TAG_RE test.
+  var variants = [];
+  var extensions = [];
+  var parts = locale.split(/-/);
+  for (var i = 1; i < parts.length; i++) {
+    var value = parts[i];
+    if (GetLanguageVariantRE().test(value) === true && extensions.length === 0) {
+      if (variants.indexOf(value) === -1) {
+        variants.push(value);
+      } else {
+        return false;
+      }
+    }
+
+    if (GetLanguageSingletonRE().test(value) === true) {
+      if (extensions.indexOf(value) === -1) {
+        extensions.push(value);
+      } else {
+        return false;
+      }
+    }
+  }
+
+  return true;
+ }
+
+
+/**
+ * Builds a regular expresion that validates the language tag
+ * against bcp47 spec.
+ * Uses http://tools.ietf.org/html/bcp47, section 2.1, ABNF.
+ * Runs on load and initializes the global REs.
+ */
+function BuildLanguageTagREs() {
+  var alpha = '[a-zA-Z]';
+  var digit = '[0-9]';
+  var alphanum = '(' + alpha + '|' + digit + ')';
+  var regular = '(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|' +
+                'zh-min|zh-min-nan|zh-xiang)';
+  var irregular = '(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|' +
+                  'i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|' +
+                  'i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)';
+  var grandfathered = '(' + irregular + '|' + regular + ')';
+  var privateUse = '(x(-' + alphanum + '{1,8})+)';
+
+  var singleton = '(' + digit + '|[A-WY-Za-wy-z])';
+  LANGUAGE_SINGLETON_RE = new $RegExp('^' + singleton + '$', 'i');
+
+  var extension = '(' + singleton + '(-' + alphanum + '{2,8})+)';
+
+  var variant = '(' + alphanum + '{5,8}|(' + digit + alphanum + '{3}))';
+  LANGUAGE_VARIANT_RE = new $RegExp('^' + variant + '$', 'i');
+
+  var region = '(' + alpha + '{2}|' + digit + '{3})';
+  var script = '(' + alpha + '{4})';
+  var extLang = '(' + alpha + '{3}(-' + alpha + '{3}){0,2})';
+  var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' +
+                 alpha + '{5,8})';
+  var langTag = language + '(-' + script + ')?(-' + region + ')?(-' +
+                variant + ')*(-' + extension + ')*(-' + privateUse + ')?';
+
+  var languageTag =
+      '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$';
+  LANGUAGE_TAG_RE = new $RegExp(languageTag, 'i');
+}
+
+/**
+ * Initializes the given object so it's a valid Collator instance.
+ * Useful for subclassing.
+ */
+function initializeCollator(collator, locales, options) {
+  if (collator.hasOwnProperty('__initializedIntlObject')) {
+    throw new $TypeError('Trying to re-initialize Collator object.');
+  }
+
+  if (options === undefined) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'collator');
+
+  var internalOptions = {};
+
+  defineWEProperty(internalOptions, 'usage', getOption(
+    'usage', 'string', ['sort', 'search'], 'sort'));
+
+  var sensitivity = getOption('sensitivity', 'string',
+                              ['base', 'accent', 'case', 'variant']);
+  if (sensitivity === undefined && internalOptions.usage === 'sort') {
+    sensitivity = 'variant';
+  }
+  defineWEProperty(internalOptions, 'sensitivity', sensitivity);
+
+  defineWEProperty(internalOptions, 'ignorePunctuation', getOption(
+    'ignorePunctuation', 'boolean', undefined, false));
+
+  var locale = resolveLocale('collator', locales, options);
+
+  // ICU can't take kb, kc... parameters through localeID, so we need to pass
+  // them as options.
+  // One exception is -co- which has to be part of the extension, but only for
+  // usage: sort, and its value can't be 'standard' or 'search'.
+  var extensionMap = parseExtension(locale.extension);
+  setOptions(
+      options, extensionMap, COLLATOR_KEY_MAP, getOption, internalOptions);
+
+  var collation = 'default';
+  var extension = '';
+  if (extensionMap.hasOwnProperty('co') && internalOptions.usage === 'sort') {
+    if (ALLOWED_CO_VALUES.indexOf(extensionMap.co) !== -1) {
+      extension = '-u-co-' + extensionMap.co;
+      // ICU can't tell us what the collation is, so save user's input.
+      collation = extensionMap.co;
+    }
+  } else if (internalOptions.usage === 'search') {
+    extension = '-u-co-search';
+  }
+  defineWEProperty(internalOptions, 'collation', collation);
+
+  var requestedLocale = locale.locale + extension;
+
+  // We define all properties C++ code may produce, to prevent security
+  // problems. If malicious user decides to redefine Object.prototype.locale
+  // we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
+  // Object.defineProperties will either succeed defining or throw an error.
+  var resolved = $Object.defineProperties({}, {
+    caseFirst: {writable: true},
+    collation: {value: internalOptions.collation, writable: true},
+    ignorePunctuation: {writable: true},
+    locale: {writable: true},
+    numeric: {writable: true},
+    requestedLocale: {value: requestedLocale, writable: true},
+    sensitivity: {writable: true},
+    strength: {writable: true},
+    usage: {value: internalOptions.usage, writable: true}
+  });
+
+  var internalCollator = %CreateCollator(requestedLocale,
+                                         internalOptions,
+                                         resolved);
+
+  // Writable, configurable and enumerable are set to false by default.
+  $Object.defineProperty(collator, 'collator', {value: internalCollator});
+  $Object.defineProperty(collator, '__initializedIntlObject',
+                         {value: 'collator'});
+  $Object.defineProperty(collator, 'resolved', {value: resolved});
+
+  return collator;
+}
+
+
+/**
+ * Constructs Intl.Collator object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%SetProperty(Intl, 'Collator', function() {
+    var locales = arguments[0];
+    var options = arguments[1];
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.Collator(locales, options);
+    }
+
+    return initializeCollator(toObject(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * Collator resolvedOptions method.
+ */
+%SetProperty(Intl.Collator.prototype, 'resolvedOptions', function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (!this || typeof this !== 'object' ||
+        this.__initializedIntlObject !== 'collator') {
+      throw new $TypeError('resolvedOptions method called on a non-object ' +
+                           'or on a object that is not Intl.Collator.');
+    }
+
+    var coll = this;
+    var locale = getOptimalLanguageTag(coll.resolved.requestedLocale,
+                                       coll.resolved.locale);
+
+    return {
+      locale: locale,
+      usage: coll.resolved.usage,
+      sensitivity: coll.resolved.sensitivity,
+      ignorePunctuation: coll.resolved.ignorePunctuation,
+      numeric: coll.resolved.numeric,
+      caseFirst: coll.resolved.caseFirst,
+      collation: coll.resolved.collation
+    };
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.Collator.prototype.resolvedOptions, 'resolvedOptions');
+%FunctionRemovePrototype(Intl.Collator.prototype.resolvedOptions);
+%SetNativeFlag(Intl.Collator.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%SetProperty(Intl.Collator, 'supportedLocalesOf', function(locales) {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    return supportedLocalesOf('collator', locales, arguments[1]);
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.Collator.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.Collator.supportedLocalesOf);
+%SetNativeFlag(Intl.Collator.supportedLocalesOf);
+
+
+/**
+ * When the compare method is called with two arguments x and y, it returns a
+ * Number other than NaN that represents the result of a locale-sensitive
+ * String comparison of x with y.
+ * The result is intended to order String values in the sort order specified
+ * by the effective locale and collation options computed during construction
+ * of this Collator object, and will be negative, zero, or positive, depending
+ * on whether x comes before y in the sort order, the Strings are equal under
+ * the sort order, or x comes after y in the sort order, respectively.
+ */
+function compare(collator, x, y) {
+  return %InternalCompare(collator.collator, $String(x), $String(y));
+};
+
+
+addBoundMethod(Intl.Collator, 'compare', compare, 2);
+
+/**
+ * Verifies that the input is a well-formed ISO 4217 currency code.
+ * Don't uppercase to test. It could convert invalid code into a valid one.
+ * For example \u00DFP (Eszett+P) becomes SSP.
+ */
+function isWellFormedCurrencyCode(currency) {
+  return typeof currency == "string" &&
+      currency.length == 3 &&
+      currency.match(/[^A-Za-z]/) == null;
+}
+
+
+/**
+ * Returns the valid digit count for a property, or throws RangeError on
+ * a value out of the range.
+ */
+function getNumberOption(options, property, min, max, fallback) {
+  var value = options[property];
+  if (value !== undefined) {
+    value = $Number(value);
+    if ($isNaN(value) || value < min || value > max) {
+      throw new $RangeError(property + ' value is out of range.');
+    }
+    return $floor(value);
+  }
+
+  return fallback;
+}
+
+
+/**
+ * Initializes the given object so it's a valid NumberFormat instance.
+ * Useful for subclassing.
+ */
+function initializeNumberFormat(numberFormat, locales, options) {
+  if (numberFormat.hasOwnProperty('__initializedIntlObject')) {
+    throw new $TypeError('Trying to re-initialize NumberFormat object.');
+  }
+
+  if (options === undefined) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'numberformat');
+
+  var locale = resolveLocale('numberformat', locales, options);
+
+  var internalOptions = {};
+  defineWEProperty(internalOptions, 'style', getOption(
+    'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
+
+  var currency = getOption('currency', 'string');
+  if (currency !== undefined && !isWellFormedCurrencyCode(currency)) {
+    throw new $RangeError('Invalid currency code: ' + currency);
+  }
+
+  if (internalOptions.style === 'currency' && currency === undefined) {
+    throw new $TypeError('Currency code is required with currency style.');
+  }
+
+  var currencyDisplay = getOption(
+      'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
+  if (internalOptions.style === 'currency') {
+    defineWEProperty(internalOptions, 'currency', currency.toUpperCase());
+    defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
+  }
+
+  // Digit ranges.
+  var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
+  defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
+
+  var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
+  defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
+
+  var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3);
+  defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
+
+  var mnsd = options['minimumSignificantDigits'];
+  var mxsd = options['maximumSignificantDigits'];
+  if (mnsd !== undefined || mxsd !== undefined) {
+    mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0);
+    defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
+
+    mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
+    defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
+  }
+
+  // Grouping.
+  defineWEProperty(internalOptions, 'useGrouping', getOption(
+    'useGrouping', 'boolean', undefined, true));
+
+  // ICU prefers options to be passed using -u- extension key/values for
+  // number format, so we need to build that.
+  var extensionMap = parseExtension(locale.extension);
+  var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
+                             getOption, internalOptions);
+
+  var requestedLocale = locale.locale + extension;
+  var resolved = $Object.defineProperties({}, {
+    currency: {writable: true},
+    currencyDisplay: {writable: true},
+    locale: {writable: true},
+    maximumFractionDigits: {writable: true},
+    minimumFractionDigits: {writable: true},
+    minimumIntegerDigits: {writable: true},
+    numberingSystem: {writable: true},
+    requestedLocale: {value: requestedLocale, writable: true},
+    style: {value: internalOptions.style, writable: true},
+    useGrouping: {writable: true}
+  });
+  if (internalOptions.hasOwnProperty('minimumSignificantDigits')) {
+    defineWEProperty(resolved, 'minimumSignificantDigits', undefined);
+  }
+  if (internalOptions.hasOwnProperty('maximumSignificantDigits')) {
+    defineWEProperty(resolved, 'maximumSignificantDigits', undefined);
+  }
+  var formatter = %CreateNumberFormat(requestedLocale,
+                                      internalOptions,
+                                      resolved);
+
+  // We can't get information about number or currency style from ICU, so we
+  // assume user request was fulfilled.
+  if (internalOptions.style === 'currency') {
+    $Object.defineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
+                                                         writable: true});
+  }
+
+  $Object.defineProperty(numberFormat, 'formatter', {value: formatter});
+  $Object.defineProperty(numberFormat, 'resolved', {value: resolved});
+  $Object.defineProperty(numberFormat, '__initializedIntlObject',
+                         {value: 'numberformat'});
+
+  return numberFormat;
+}
+
+
+/**
+ * Constructs Intl.NumberFormat object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%SetProperty(Intl, 'NumberFormat', function() {
+    var locales = arguments[0];
+    var options = arguments[1];
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.NumberFormat(locales, options);
+    }
+
+    return initializeNumberFormat(toObject(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * NumberFormat resolvedOptions method.
+ */
+%SetProperty(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (!this || typeof this !== 'object' ||
+        this.__initializedIntlObject !== 'numberformat') {
+      throw new $TypeError('resolvedOptions method called on a non-object' +
+          ' or on a object that is not Intl.NumberFormat.');
+    }
+
+    var format = this;
+    var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
+                                       format.resolved.locale);
+
+    var result = {
+      locale: locale,
+      numberingSystem: format.resolved.numberingSystem,
+      style: format.resolved.style,
+      useGrouping: format.resolved.useGrouping,
+      minimumIntegerDigits: format.resolved.minimumIntegerDigits,
+      minimumFractionDigits: format.resolved.minimumFractionDigits,
+      maximumFractionDigits: format.resolved.maximumFractionDigits,
+    };
+
+    if (result.style === 'currency') {
+      defineWECProperty(result, 'currency', format.resolved.currency);
+      defineWECProperty(result, 'currencyDisplay',
+                        format.resolved.currencyDisplay);
+    }
+
+    if (format.resolved.hasOwnProperty('minimumSignificantDigits')) {
+      defineWECProperty(result, 'minimumSignificantDigits',
+                        format.resolved.minimumSignificantDigits);
+    }
+
+    if (format.resolved.hasOwnProperty('maximumSignificantDigits')) {
+      defineWECProperty(result, 'maximumSignificantDigits',
+                        format.resolved.maximumSignificantDigits);
+    }
+
+    return result;
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.NumberFormat.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions);
+%SetNativeFlag(Intl.NumberFormat.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%SetProperty(Intl.NumberFormat, 'supportedLocalesOf', function(locales) {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    return supportedLocalesOf('numberformat', locales, arguments[1]);
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.NumberFormat.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.NumberFormat.supportedLocalesOf);
+%SetNativeFlag(Intl.NumberFormat.supportedLocalesOf);
+
+
+/**
+ * Returns a String value representing the result of calling ToNumber(value)
+ * according to the effective locale and the formatting options of this
+ * NumberFormat.
+ */
+function formatNumber(formatter, value) {
+  // Spec treats -0 and +0 as 0.
+  var number = $Number(value);
+  if (number === -0) {
+    number = 0;
+  }
+
+  return %InternalNumberFormat(formatter.formatter, number);
+}
+
+
+/**
+ * Returns a Number that represents string value that was passed in.
+ */
+function parseNumber(formatter, value) {
+  return %InternalNumberParse(formatter.formatter, $String(value));
+}
+
+
+addBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
+addBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
+
+/**
+ * Returns a string that matches LDML representation of the options object.
+ */
+function toLDMLString(options) {
+  var getOption = getGetOption(options, 'dateformat');
+
+  var ldmlString = '';
+
+  var option = getOption('weekday', 'string', ['narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(
+      option, {narrow: 'EEEEE', short: 'EEE', long: 'EEEE'});
+
+  option = getOption('era', 'string', ['narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(
+      option, {narrow: 'GGGGG', short: 'GGG', long: 'GGGG'});
+
+  option = getOption('year', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'yy', 'numeric': 'y'});
+
+  option = getOption('month', 'string',
+                     ['2-digit', 'numeric', 'narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'MM', 'numeric': 'M',
+          'narrow': 'MMMMM', 'short': 'MMM', 'long': 'MMMM'});
+
+  option = getOption('day', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(
+      option, {'2-digit': 'dd', 'numeric': 'd'});
+
+  var hr12 = getOption('hour12', 'boolean');
+  option = getOption('hour', 'string', ['2-digit', 'numeric']);
+  if (hr12 === undefined) {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'jj', 'numeric': 'j'});
+  } else if (hr12 === true) {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'hh', 'numeric': 'h'});
+  } else {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'HH', 'numeric': 'H'});
+  }
+
+  option = getOption('minute', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'mm', 'numeric': 'm'});
+
+  option = getOption('second', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'ss', 'numeric': 's'});
+
+  option = getOption('timeZoneName', 'string', ['short', 'long']);
+  ldmlString += appendToLDMLString(option, {short: 'v', long: 'vv'});
+
+  return ldmlString;
+}
+
+
+/**
+ * Returns either LDML equivalent of the current option or empty string.
+ */
+function appendToLDMLString(option, pairs) {
+  if (option !== undefined) {
+    return pairs[option];
+  } else {
+    return '';
+  }
+}
+
+
+/**
+ * Returns object that matches LDML representation of the date.
+ */
+function fromLDMLString(ldmlString) {
+  // First remove '' quoted text, so we lose 'Uhr' strings.
+  ldmlString = ldmlString.replace(GetQuotedStringRE(), '');
+
+  var options = {};
+  var match = ldmlString.match(/E{3,5}/g);
+  options = appendToDateTimeObject(
+      options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
+
+  match = ldmlString.match(/G{3,5}/g);
+  options = appendToDateTimeObject(
+      options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
+
+  match = ldmlString.match(/y{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'year', match, {y: 'numeric', yy: '2-digit'});
+
+  match = ldmlString.match(/M{1,5}/g);
+  options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
+      M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
+
+  // Sometimes we get L instead of M for month - standalone name.
+  match = ldmlString.match(/L{1,5}/g);
+  options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
+      L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
+
+  match = ldmlString.match(/d{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'day', match, {d: 'numeric', dd: '2-digit'});
+
+  match = ldmlString.match(/h{1,2}/g);
+  if (match !== null) {
+    options['hour12'] = true;
+  }
+  options = appendToDateTimeObject(
+      options, 'hour', match, {h: 'numeric', hh: '2-digit'});
+
+  match = ldmlString.match(/H{1,2}/g);
+  if (match !== null) {
+    options['hour12'] = false;
+  }
+  options = appendToDateTimeObject(
+      options, 'hour', match, {H: 'numeric', HH: '2-digit'});
+
+  match = ldmlString.match(/m{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'minute', match, {m: 'numeric', mm: '2-digit'});
+
+  match = ldmlString.match(/s{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'second', match, {s: 'numeric', ss: '2-digit'});
+
+  match = ldmlString.match(/v{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'timeZoneName', match, {v: 'short', vv: 'long'});
+
+  return options;
+}
+
+
+function appendToDateTimeObject(options, option, match, pairs) {
+  if (match === null) {
+    if (!options.hasOwnProperty(option)) {
+      defineWEProperty(options, option, undefined);
+    }
+    return options;
+  }
+
+  var property = match[0];
+  defineWEProperty(options, option, pairs[property]);
+
+  return options;
+}
+
+
+/**
+ * Returns options with at least default values in it.
+ */
+function toDateTimeOptions(options, required, defaults) {
+  if (options === undefined) {
+    options = null;
+  } else {
+    options = toObject(options);
+  }
+
+  options = $Object.apply(this, [options]);
+
+  var needsDefault = true;
+  if ((required === 'date' || required === 'any') &&
+      (options.weekday !== undefined || options.year !== undefined ||
+       options.month !== undefined || options.day !== undefined)) {
+    needsDefault = false;
+  }
+
+  if ((required === 'time' || required === 'any') &&
+      (options.hour !== undefined || options.minute !== undefined ||
+       options.second !== undefined)) {
+    needsDefault = false;
+  }
+
+  if (needsDefault && (defaults === 'date' || defaults === 'all')) {
+    $Object.defineProperty(options, 'year', {value: 'numeric',
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
+    $Object.defineProperty(options, 'month', {value: 'numeric',
+                                              writable: true,
+                                              enumerable: true,
+                                              configurable: true});
+    $Object.defineProperty(options, 'day', {value: 'numeric',
+                                            writable: true,
+                                            enumerable: true,
+                                            configurable: true});
+  }
+
+  if (needsDefault && (defaults === 'time' || defaults === 'all')) {
+    $Object.defineProperty(options, 'hour', {value: 'numeric',
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
+    $Object.defineProperty(options, 'minute', {value: 'numeric',
+                                               writable: true,
+                                               enumerable: true,
+                                               configurable: true});
+    $Object.defineProperty(options, 'second', {value: 'numeric',
+                                               writable: true,
+                                               enumerable: true,
+                                               configurable: true});
+  }
+
+  return options;
+}
+
+
+/**
+ * Initializes the given object so it's a valid DateTimeFormat instance.
+ * Useful for subclassing.
+ */
+function initializeDateTimeFormat(dateFormat, locales, options) {
+
+  if (dateFormat.hasOwnProperty('__initializedIntlObject')) {
+    throw new $TypeError('Trying to re-initialize DateTimeFormat object.');
+  }
+
+  if (options === undefined) {
+    options = {};
+  }
+
+  var locale = resolveLocale('dateformat', locales, options);
+
+  options = toDateTimeOptions(options, 'any', 'date');
+
+  var getOption = getGetOption(options, 'dateformat');
+
+  // We implement only best fit algorithm, but still need to check
+  // if the formatMatcher values are in range.
+  var matcher = getOption('formatMatcher', 'string',
+                          ['basic', 'best fit'], 'best fit');
+
+  // Build LDML string for the skeleton that we pass to the formatter.
+  var ldmlString = toLDMLString(options);
+
+  // Filter out supported extension keys so we know what to put in resolved
+  // section later on.
+  // We need to pass calendar and number system to the method.
+  var tz = canonicalizeTimeZoneID(options.timeZone);
+
+  // ICU prefers options to be passed using -u- extension key/values, so
+  // we need to build that.
+  var internalOptions = {};
+  var extensionMap = parseExtension(locale.extension);
+  var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP,
+                             getOption, internalOptions);
+
+  var requestedLocale = locale.locale + extension;
+  var resolved = $Object.defineProperties({}, {
+    calendar: {writable: true},
+    day: {writable: true},
+    era: {writable: true},
+    hour12: {writable: true},
+    hour: {writable: true},
+    locale: {writable: true},
+    minute: {writable: true},
+    month: {writable: true},
+    numberingSystem: {writable: true},
+    pattern: {writable: true},
+    requestedLocale: {value: requestedLocale, writable: true},
+    second: {writable: true},
+    timeZone: {writable: true},
+    timeZoneName: {writable: true},
+    tz: {value: tz, writable: true},
+    weekday: {writable: true},
+    year: {writable: true}
+  });
+
+  var formatter = %CreateDateTimeFormat(
+    requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
+
+  if (tz !== undefined && tz !== resolved.timeZone) {
+    throw new $RangeError('Unsupported time zone specified ' + tz);
+  }
+
+  $Object.defineProperty(dateFormat, 'formatter', {value: formatter});
+  $Object.defineProperty(dateFormat, 'resolved', {value: resolved});
+  $Object.defineProperty(dateFormat, '__initializedIntlObject',
+                         {value: 'dateformat'});
+
+  return dateFormat;
+}
+
+
+/**
+ * Constructs Intl.DateTimeFormat object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%SetProperty(Intl, 'DateTimeFormat', function() {
+    var locales = arguments[0];
+    var options = arguments[1];
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.DateTimeFormat(locales, options);
+    }
+
+    return initializeDateTimeFormat(toObject(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * DateTimeFormat resolvedOptions method.
+ */
+%SetProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (!this || typeof this !== 'object' ||
+        this.__initializedIntlObject !== 'dateformat') {
+      throw new $TypeError('resolvedOptions method called on a non-object or ' +
+          'on a object that is not Intl.DateTimeFormat.');
+    }
+
+    var format = this;
+    var fromPattern = fromLDMLString(format.resolved.pattern);
+    var userCalendar = ICU_CALENDAR_MAP[format.resolved.calendar];
+    if (userCalendar === undefined) {
+      // Use ICU name if we don't have a match. It shouldn't happen, but
+      // it would be too strict to throw for this.
+      userCalendar = format.resolved.calendar;
+    }
+
+    var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
+                                       format.resolved.locale);
+
+    var result = {
+      locale: locale,
+      numberingSystem: format.resolved.numberingSystem,
+      calendar: userCalendar,
+      timeZone: format.resolved.timeZone
+    };
+
+    addWECPropertyIfDefined(result, 'timeZoneName', fromPattern.timeZoneName);
+    addWECPropertyIfDefined(result, 'era', fromPattern.era);
+    addWECPropertyIfDefined(result, 'year', fromPattern.year);
+    addWECPropertyIfDefined(result, 'month', fromPattern.month);
+    addWECPropertyIfDefined(result, 'day', fromPattern.day);
+    addWECPropertyIfDefined(result, 'weekday', fromPattern.weekday);
+    addWECPropertyIfDefined(result, 'hour12', fromPattern.hour12);
+    addWECPropertyIfDefined(result, 'hour', fromPattern.hour);
+    addWECPropertyIfDefined(result, 'minute', fromPattern.minute);
+    addWECPropertyIfDefined(result, 'second', fromPattern.second);
+
+    return result;
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.DateTimeFormat.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.DateTimeFormat.prototype.resolvedOptions);
+%SetNativeFlag(Intl.DateTimeFormat.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%SetProperty(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    return supportedLocalesOf('dateformat', locales, arguments[1]);
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.DateTimeFormat.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.DateTimeFormat.supportedLocalesOf);
+%SetNativeFlag(Intl.DateTimeFormat.supportedLocalesOf);
+
+
+/**
+ * Returns a String value representing the result of calling ToNumber(date)
+ * according to the effective locale and the formatting options of this
+ * DateTimeFormat.
+ */
+function formatDate(formatter, dateValue) {
+  var dateMs;
+  if (dateValue === undefined) {
+    dateMs = $Date.now();
+  } else {
+    dateMs = $Number(dateValue);
+  }
+
+  if (!$isFinite(dateMs)) {
+    throw new $RangeError('Provided date is not in valid range.');
+  }
+
+  return %InternalDateFormat(formatter.formatter, new $Date(dateMs));
+}
+
+
+/**
+ * Returns a Date object representing the result of calling ToString(value)
+ * according to the effective locale and the formatting options of this
+ * DateTimeFormat.
+ * Returns undefined if date string cannot be parsed.
+ */
+function parseDate(formatter, value) {
+  return %InternalDateParse(formatter.formatter, $String(value));
+}
+
+
+// 0 because date is optional argument.
+addBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
+addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
+
+
+/**
+ * Returns canonical Area/Location name, or throws an exception if the zone
+ * name is invalid IANA name.
+ */
+function canonicalizeTimeZoneID(tzID) {
+  // Skip undefined zones.
+  if (tzID === undefined) {
+    return tzID;
+  }
+
+  // Special case handling (UTC, GMT).
+  var upperID = tzID.toUpperCase();
+  if (upperID === 'UTC' || upperID === 'GMT' ||
+      upperID === 'ETC/UTC' || upperID === 'ETC/GMT') {
+    return 'UTC';
+  }
+
+  // We expect only _ and / beside ASCII letters.
+  // All inputs should conform to Area/Location from now on.
+  var match = GetTimezoneNameCheckRE().exec(tzID);
+  if (match === null) {
+    throw new $RangeError('Expected Area/Location for time zone, got ' + tzID);
+  }
+
+  var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]);
+  var i = 3;
+  while (match[i] !== undefined && i < match.length) {
+    result = result + '_' + toTitleCaseWord(match[i]);
+    i++;
+  }
+
+  return result;
+}
+
+/**
+ * Initializes the given object so it's a valid BreakIterator instance.
+ * Useful for subclassing.
+ */
+function initializeBreakIterator(iterator, locales, options) {
+  if (iterator.hasOwnProperty('__initializedIntlObject')) {
+    throw new $TypeError('Trying to re-initialize v8BreakIterator object.');
+  }
+
+  if (options === undefined) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'breakiterator');
+
+  var internalOptions = {};
+
+  defineWEProperty(internalOptions, 'type', getOption(
+    'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
+
+  var locale = resolveLocale('breakiterator', locales, options);
+  var resolved = $Object.defineProperties({}, {
+    requestedLocale: {value: locale.locale, writable: true},
+    type: {value: internalOptions.type, writable: true},
+    locale: {writable: true}
+  });
+
+  var internalIterator = %CreateBreakIterator(locale.locale,
+                                              internalOptions,
+                                              resolved);
+
+  $Object.defineProperty(iterator, 'iterator', {value: internalIterator});
+  $Object.defineProperty(iterator, 'resolved', {value: resolved});
+  $Object.defineProperty(iterator, '__initializedIntlObject',
+                         {value: 'breakiterator'});
+
+  return iterator;
+}
+
+
+/**
+ * Constructs Intl.v8BreakIterator object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%SetProperty(Intl, 'v8BreakIterator', function() {
+    var locales = arguments[0];
+    var options = arguments[1];
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.v8BreakIterator(locales, options);
+    }
+
+    return initializeBreakIterator(toObject(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * BreakIterator resolvedOptions method.
+ */
+%SetProperty(Intl.v8BreakIterator.prototype, 'resolvedOptions', function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (!this || typeof this !== 'object' ||
+        this.__initializedIntlObject !== 'breakiterator') {
+      throw new $TypeError('resolvedOptions method called on a non-object or ' +
+          'on a object that is not Intl.v8BreakIterator.');
+    }
+
+    var segmenter = this;
+    var locale = getOptimalLanguageTag(segmenter.resolved.requestedLocale,
+                                       segmenter.resolved.locale);
+
+    return {
+      locale: locale,
+      type: segmenter.resolved.type
+    };
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.v8BreakIterator.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.v8BreakIterator.prototype.resolvedOptions);
+%SetNativeFlag(Intl.v8BreakIterator.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%SetProperty(Intl.v8BreakIterator, 'supportedLocalesOf', function(locales) {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    return supportedLocalesOf('breakiterator', locales, arguments[1]);
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.v8BreakIterator.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.v8BreakIterator.supportedLocalesOf);
+%SetNativeFlag(Intl.v8BreakIterator.supportedLocalesOf);
+
+
+/**
+ * Adopts text to segment using the iterator. Old text, if present,
+ * gets discarded.
+ */
+function adoptText(iterator, text) {
+  %BreakIteratorAdoptText(iterator.iterator, $String(text));
+}
+
+
+/**
+ * Returns index of the first break in the string and moves current pointer.
+ */
+function first(iterator) {
+  return %BreakIteratorFirst(iterator.iterator);
+}
+
+
+/**
+ * Returns the index of the next break and moves the pointer.
+ */
+function next(iterator) {
+  return %BreakIteratorNext(iterator.iterator);
+}
+
+
+/**
+ * Returns index of the current break.
+ */
+function current(iterator) {
+  return %BreakIteratorCurrent(iterator.iterator);
+}
+
+
+/**
+ * Returns type of the current break.
+ */
+function breakType(iterator) {
+  return %BreakIteratorBreakType(iterator.iterator);
+}
+
+
+addBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
+addBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
+addBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
+addBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
+addBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
+
+// Save references to Intl objects and methods we use, for added security.
+var savedObjects = {
+  'collator': Intl.Collator,
+  'numberformat': Intl.NumberFormat,
+  'dateformatall': Intl.DateTimeFormat,
+  'dateformatdate': Intl.DateTimeFormat,
+  'dateformattime': Intl.DateTimeFormat
+};
+
+
+// Default (created with undefined locales and options parameters) collator,
+// number and date format instances. They'll be created as needed.
+var defaultObjects = {
+  'collator': undefined,
+  'numberformat': undefined,
+  'dateformatall': undefined,
+  'dateformatdate': undefined,
+  'dateformattime': undefined,
+};
+
+
+/**
+ * Returns cached or newly created instance of a given service.
+ * We cache only default instances (where no locales or options are provided).
+ */
+function cachedOrNewService(service, locales, options, defaults) {
+  var useOptions = (defaults === undefined) ? options : defaults;
+  if (locales === undefined && options === undefined) {
+    if (defaultObjects[service] === undefined) {
+      defaultObjects[service] = new savedObjects[service](locales, useOptions);
+    }
+    return defaultObjects[service];
+  }
+  return new savedObjects[service](locales, useOptions);
+}
+
+
+/**
+ * Compares this and that, and returns less than 0, 0 or greater than 0 value.
+ * Overrides the built-in method.
+ */
+$Object.defineProperty($String.prototype, 'localeCompare', {
+  value: function(that) {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (this === undefined || this === null) {
+      throw new $TypeError('Method invoked on undefined or null value.');
+    }
+
+    var locales = arguments[1];
+    var options = arguments[2];
+    var collator = cachedOrNewService('collator', locales, options);
+    return compare(collator, this, that);
+  },
+  writable: true,
+  configurable: true,
+  enumerable: false
+});
+%FunctionSetName($String.prototype.localeCompare, 'localeCompare');
+%FunctionRemovePrototype($String.prototype.localeCompare);
+%SetNativeFlag($String.prototype.localeCompare);
+
+
+/**
+ * Formats a Number object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used.
+ */
+$Object.defineProperty($Number.prototype, 'toLocaleString', {
+  value: function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    if (!(this instanceof $Number) && typeof(this) !== 'number') {
+      throw new $TypeError('Method invoked on an object that is not Number.');
+    }
+
+    var locales = arguments[0];
+    var options = arguments[1];
+    var numberFormat = cachedOrNewService('numberformat', locales, options);
+    return formatNumber(numberFormat, this);
+  },
+  writable: true,
+  configurable: true,
+  enumerable: false
+});
+%FunctionSetName($Number.prototype.toLocaleString, 'toLocaleString');
+%FunctionRemovePrototype($Number.prototype.toLocaleString);
+%SetNativeFlag($Number.prototype.toLocaleString);
+
+
+/**
+ * Returns actual formatted date or fails if date parameter is invalid.
+ */
+function toLocaleDateTime(date, locales, options, required, defaults, service) {
+  if (!(date instanceof $Date)) {
+    throw new $TypeError('Method invoked on an object that is not Date.');
+  }
+
+  if ($isNaN(date)) {
+    return 'Invalid Date';
+  }
+
+  var internalOptions = toDateTimeOptions(options, required, defaults);
+
+  var dateFormat =
+      cachedOrNewService(service, locales, options, internalOptions);
+
+  return formatDate(dateFormat, date);
+}
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - both date and time are
+ * present in the output.
+ */
+$Object.defineProperty($Date.prototype, 'toLocaleString', {
+  value: function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    var locales = arguments[0];
+    var options = arguments[1];
+    return toLocaleDateTime(
+        this, locales, options, 'any', 'all', 'dateformatall');
+  },
+  writable: true,
+  configurable: true,
+  enumerable: false
+});
+%FunctionSetName($Date.prototype.toLocaleString, 'toLocaleString');
+%FunctionRemovePrototype($Date.prototype.toLocaleString);
+%SetNativeFlag($Date.prototype.toLocaleString);
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - only date is present
+ * in the output.
+ */
+$Object.defineProperty($Date.prototype, 'toLocaleDateString', {
+  value: function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    var locales = arguments[0];
+    var options = arguments[1];
+    return toLocaleDateTime(
+        this, locales, options, 'date', 'date', 'dateformatdate');
+  },
+  writable: true,
+  configurable: true,
+  enumerable: false
+});
+%FunctionSetName($Date.prototype.toLocaleDateString, 'toLocaleDateString');
+%FunctionRemovePrototype($Date.prototype.toLocaleDateString);
+%SetNativeFlag($Date.prototype.toLocaleDateString);
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - only time is present
+ * in the output.
+ */
+$Object.defineProperty($Date.prototype, 'toLocaleTimeString', {
+  value: function() {
+    if (%_IsConstructCall()) {
+      throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
+    }
+
+    var locales = arguments[0];
+    var options = arguments[1];
+    return toLocaleDateTime(
+        this, locales, options, 'time', 'time', 'dateformattime');
+  },
+  writable: true,
+  configurable: true,
+  enumerable: false
+});
+%FunctionSetName($Date.prototype.toLocaleTimeString, 'toLocaleTimeString');
+%FunctionRemovePrototype($Date.prototype.toLocaleTimeString);
+%SetNativeFlag($Date.prototype.toLocaleTimeString);
+
+return Intl;
+}())});
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 5f5d397..a159748 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -74,6 +74,24 @@
 }
 
 
+static void CallRuntimePassFunction(MacroAssembler* masm,
+                                    Runtime::FunctionId function_id) {
+  FrameScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function.
+  __ push(edi);
+  // Push call kind information.
+  __ push(ecx);
+  // Function is also the parameter to the runtime call.
+  __ push(edi);
+
+  __ CallRuntime(function_id, 1);
+  // Restore call kind information.
+  __ pop(ecx);
+  // Restore receiver.
+  __ pop(edi);
+}
+
+
 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
   __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
   __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset));
@@ -83,56 +101,29 @@
 
 
 void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+  // Checking whether the queued function is ready for install is optional,
+  // since we come across interrupts and stack checks elsewhere.  However,
+  // not checking may delay installing ready functions, and always checking
+  // would be quite expensive.  A good compromise is to first check against
+  // stack limit as a cue for an interrupt signal.
+  Label ok;
+  ExternalReference stack_limit =
+      ExternalReference::address_of_stack_limit(masm->isolate());
+  __ cmp(esp, Operand::StaticVariable(stack_limit));
+  __ j(above_equal, &ok, Label::kNear);
+
+  CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode);
+  // Tail call to returned code.
+  __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
+  __ jmp(eax);
+
+  __ bind(&ok);
   GenerateTailCallToSharedCode(masm);
 }
 
 
-void Builtins::Generate_InstallRecompiledCode(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function.
-    __ push(edi);
-    // Push call kind information.
-    __ push(ecx);
-
-    __ push(edi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kInstallRecompiledCode, 1);
-
-    // Restore call kind information.
-    __ pop(ecx);
-    // Restore receiver.
-    __ pop(edi);
-
-    // Tear down internal frame.
-  }
-
-  // Do a tail-call of the compiled function.
-  __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
-  __ jmp(eax);
-}
-
-
 void Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(edi);
-    // Push call kind information.
-    __ push(ecx);
-
-    __ push(edi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kConcurrentRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(ecx);
-    // Restore receiver.
-    __ pop(edi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile);
   GenerateTailCallToSharedCode(masm);
 }
 
@@ -519,25 +510,7 @@
 
 
 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function.
-    __ push(edi);
-    // Push call kind information.
-    __ push(ecx);
-
-    __ push(edi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kLazyCompile, 1);
-
-    // Restore call kind information.
-    __ pop(ecx);
-    // Restore receiver.
-    __ pop(edi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyCompile);
   // Do a tail-call of the compiled function.
   __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
   __ jmp(eax);
@@ -545,25 +518,7 @@
 
 
 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(edi);
-    // Push call kind information.
-    __ push(ecx);
-
-    __ push(edi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kLazyRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(ecx);
-    // Restore receiver.
-    __ pop(edi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyRecompile);
   // Do a tail-call of the compiled function.
   __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
   __ jmp(eax);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index ee9e535..a83c1ae 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -5515,7 +5515,6 @@
   __ j(below, &done);
 
   // Check the number to string cache.
-  Label not_cached;
   __ bind(&not_string);
   // Puts the cached result into scratch1.
   NumberToStringStub::GenerateLookupNumberStringCache(masm,
@@ -5523,22 +5522,9 @@
                                                       scratch1,
                                                       scratch2,
                                                       scratch3,
-                                                      &not_cached);
+                                                      slow);
   __ mov(arg, scratch1);
   __ mov(Operand(esp, stack_offset), arg);
-  __ jmp(&done);
-
-  // Check if the argument is a safe string wrapper.
-  __ bind(&not_cached);
-  __ JumpIfSmi(arg, slow);
-  __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1);  // map -> scratch1.
-  __ j(not_equal, slow);
-  __ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
-            1 << Map::kStringWrapperSafeForDefaultValueOf);
-  __ j(zero, slow);
-  __ mov(arg, FieldOperand(arg, JSValue::kValueOffset));
-  __ mov(Operand(esp, stack_offset), arg);
-
   __ bind(&done);
 }
 
@@ -7239,96 +7225,128 @@
 
 
 template<class T>
-static void CreateArrayDispatch(MacroAssembler* masm) {
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmp(edx, kind);
-    __ j(not_equal, &next);
-    T stub(kind);
+static void CreateArrayDispatch(MacroAssembler* masm,
+                                AllocationSiteOverrideMode mode) {
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    T stub(GetInitialFastElementsKind(),
+           CONTEXT_CHECK_REQUIRED,
+           mode);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmp(edx, kind);
+      __ j(not_equal, &next);
+      T stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
-static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
-  // ebx - type info cell
-  // edx - kind
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
+                                           AllocationSiteOverrideMode mode) {
+  // ebx - type info cell (if mode != DISABLE_ALLOCATION_SITES)
+  // edx - kind (if mode != DISABLE_ALLOCATION_SITES)
   // eax - number of arguments
   // edi - constructor?
   // esp[0] - return address
   // esp[4] - last argument
-  ASSERT(FAST_SMI_ELEMENTS == 0);
-  ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
-  ASSERT(FAST_ELEMENTS == 2);
-  ASSERT(FAST_HOLEY_ELEMENTS == 3);
-  ASSERT(FAST_DOUBLE_ELEMENTS == 4);
-  ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
-
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
-
-  // is the low bit set? If so, we are holey and that is good.
-  __ test_b(edx, 1);
   Label normal_sequence;
-  __ j(not_zero, &normal_sequence);
+  if (mode == DONT_OVERRIDE) {
+    ASSERT(FAST_SMI_ELEMENTS == 0);
+    ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+    ASSERT(FAST_ELEMENTS == 2);
+    ASSERT(FAST_HOLEY_ELEMENTS == 3);
+    ASSERT(FAST_DOUBLE_ELEMENTS == 4);
+    ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
+
+    // is the low bit set? If so, we are holey and that is good.
+    __ test_b(edx, 1);
+    __ j(not_zero, &normal_sequence);
+  }
 
   // look at the first argument
   __ mov(ecx, Operand(esp, kPointerSize));
   __ test(ecx, ecx);
   __ j(zero, &normal_sequence);
 
-  // We are going to create a holey array, but our kind is non-holey.
-  // Fix kind and retry (only if we have an allocation site in the cell).
-  __ inc(edx);
-  __ cmp(ebx, Immediate(undefined_sentinel));
-  __ j(equal, &normal_sequence);
-  __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset));
-  Handle<Map> allocation_site_map(
-      masm->isolate()->heap()->allocation_site_map(),
-      masm->isolate());
-  __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
-  __ j(not_equal, &normal_sequence);
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    ElementsKind initial = GetInitialFastElementsKind();
+    ElementsKind holey_initial = GetHoleyElementsKind(initial);
 
-  // Save the resulting elements kind in type info
-  __ SmiTag(edx);
-  __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx);
-  __ SmiUntag(edx);
+    ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+                                                  CONTEXT_CHECK_REQUIRED,
+                                                  DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub_holey);
 
-  __ bind(&normal_sequence);
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmp(edx, kind);
-    __ j(not_equal, &next);
-    ArraySingleArgumentConstructorStub stub(kind);
+    __ bind(&normal_sequence);
+    ArraySingleArgumentConstructorStub stub(initial,
+                                            CONTEXT_CHECK_REQUIRED,
+                                            DISABLE_ALLOCATION_SITES);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    // We are going to create a holey array, but our kind is non-holey.
+    // Fix kind and retry.
+    __ inc(edx);
+    __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset));
+    if (FLAG_debug_code) {
+      Handle<Map> allocation_site_map(
+          masm->isolate()->heap()->allocation_site_map(),
+          masm->isolate());
+      __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
+      __ Assert(equal, kExpectedAllocationSiteInCell);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // Save the resulting elements kind in type info
+    __ SmiTag(edx);
+    __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx);
+    __ SmiUntag(edx);
+
+    __ bind(&normal_sequence);
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmp(edx, kind);
+      __ j(not_equal, &next);
+      ArraySingleArgumentConstructorStub stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
 template<class T>
 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
+  ElementsKind initial_kind = GetInitialFastElementsKind();
+  ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
+
   int to_index = GetSequenceIndexFromFastElementsKind(
       TERMINAL_FAST_ELEMENTS_KIND);
   for (int i = 0; i <= to_index; ++i) {
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
-    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
+        (!FLAG_track_allocation_sites &&
+         (kind == initial_kind || kind == initial_holey_kind))) {
       T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
       stub1.GetCode(isolate)->set_is_pregenerated(true);
     }
@@ -7361,6 +7379,34 @@
 }
 
 
+void ArrayConstructorStub::GenerateDispatchToArrayStub(
+    MacroAssembler* masm,
+    AllocationSiteOverrideMode mode) {
+  if (argument_count_ == ANY) {
+    Label not_zero_case, not_one_case;
+    __ test(eax, eax);
+    __ j(not_zero, &not_zero_case);
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+
+    __ bind(&not_zero_case);
+    __ cmp(eax, 1);
+    __ j(greater, &not_one_case);
+    CreateArrayDispatchOneArgument(masm, mode);
+
+    __ bind(&not_one_case);
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else if (argument_count_ == NONE) {
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+  } else if (argument_count_ == ONE) {
+    CreateArrayDispatchOneArgument(masm, mode);
+  } else if (argument_count_ == MORE_THAN_ONE) {
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax : argc (only if argument_count_ == ANY)
@@ -7395,50 +7441,22 @@
     __ bind(&okay_here);
   }
 
-  Label no_info, switch_ready;
-  // Get the elements kind and case on that.
+  Label no_info;
+  // If the type cell is undefined, or contains anything other than an
+  // AllocationSite, call an array constructor that doesn't use AllocationSites.
   __ cmp(ebx, Immediate(undefined_sentinel));
   __ j(equal, &no_info);
   __ mov(edx, FieldOperand(ebx, Cell::kValueOffset));
-
-  // The type cell may have undefined in its value.
-  __ cmp(edx, Immediate(undefined_sentinel));
-  __ j(equal, &no_info);
-
-  // The type cell has either an AllocationSite or a JSFunction
   __ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>(
       masm->isolate()->heap()->allocation_site_map())));
   __ j(not_equal, &no_info);
 
   __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset));
   __ SmiUntag(edx);
-  __ jmp(&switch_ready);
+  GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
+
   __ bind(&no_info);
-  __ mov(edx, Immediate(GetInitialFastElementsKind()));
-  __ bind(&switch_ready);
-
-  if (argument_count_ == ANY) {
-    Label not_zero_case, not_one_case;
-    __ test(eax, eax);
-    __ j(not_zero, &not_zero_case);
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-
-    __ bind(&not_zero_case);
-    __ cmp(eax, 1);
-    __ j(greater, &not_one_case);
-    CreateArrayDispatchOneArgument(masm);
-
-    __ bind(&not_one_case);
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else if (argument_count_ == NONE) {
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-  } else if (argument_count_ == ONE) {
-    CreateArrayDispatchOneArgument(masm);
-  } else if (argument_count_ == MORE_THAN_ONE) {
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else {
-    UNREACHABLE();
-  }
+  GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
 }
 
 
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index db82b39..6d39cc1 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2956,7 +2956,7 @@
 
   VisitForAccumulatorValue(args->at(0));
 
-  Label materialize_true, materialize_false;
+  Label materialize_true, materialize_false, skip_lookup;
   Label* if_true = NULL;
   Label* if_false = NULL;
   Label* fall_through = NULL;
@@ -2970,7 +2970,7 @@
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   __ test_b(FieldOperand(ebx, Map::kBitField2Offset),
             1 << Map::kStringWrapperSafeForDefaultValueOf);
-  __ j(not_zero, if_true);
+  __ j(not_zero, &skip_lookup);
 
   // Check for fast case object. Return false for slow case objects.
   __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset));
@@ -3016,6 +3016,12 @@
   // Reload map as register ebx was used as temporary above.
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
 
+  // Set the bit in the map to indicate that there is no local valueOf field.
+  __ or_(FieldOperand(ebx, Map::kBitField2Offset),
+         Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
+
+  __ bind(&skip_lookup);
+
   // If a valueOf property is not found on the object check that its
   // prototype is the un-modified String prototype. If not result is false.
   __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
@@ -3027,10 +3033,9 @@
   __ cmp(ecx,
          ContextOperand(edx,
                         Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
-  __ j(not_equal, if_false);
-  __ jmp(if_true);
-
   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(equal, if_true, if_false, fall_through);
+
   context()->Plug(if_true, if_false);
 }
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 860646c..d50b780 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -382,9 +382,13 @@
 
     instr->CompileToNative(this);
 
-    if (!CpuFeatures::IsSupported(SSE2) &&
-        FLAG_debug_code && FLAG_enable_slow_asserts) {
+    if (!CpuFeatures::IsSupported(SSE2)) {
+      if (instr->IsGoto()) {
+        x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
+      } else if (FLAG_debug_code && FLAG_enable_slow_asserts &&
+                 !instr->IsGap() && !instr->IsReturn()) {
         __ VerifyX87StackDepth(x87_stack_.depth());
+      }
     }
   }
   EnsureSpaceForLazyDeopt();
@@ -682,6 +686,21 @@
       __ fstp(0);
       stack_depth_--;
     }
+    if (FLAG_debug_code && FLAG_enable_slow_asserts) __ VerifyX87StackDepth(0);
+  }
+}
+
+
+void LCodeGen::X87Stack::LeavingBlock(int current_block_id, LGoto* goto_instr) {
+  ASSERT(stack_depth_ <= 1);
+  // If ever used for new stubs producing two pairs of doubles joined into two
+  // phis this assert hits. That situation is not handled, since the two stacks
+  // might have st0 and st1 swapped.
+  if (current_block_id + 1 != goto_instr->block_id()) {
+    // If we have a value on the x87 stack on leaving a block, it must be a
+    // phi input. If the next block we compile is not the join block, we have
+    // to discard the stack state.
+    stack_depth_ = 0;
   }
 }
 
@@ -2486,6 +2505,10 @@
 }
 
 
+void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) {
+}
+
+
 void LCodeGen::DoGoto(LGoto* instr) {
   EmitGoto(instr->block_id());
 }
@@ -4103,85 +4126,66 @@
 
 
 void LCodeGen::DoRandom(LRandom* instr) {
-  class DeferredDoRandom V8_FINAL : public LDeferredCode {
-   public:
-    DeferredDoRandom(LCodeGen* codegen,
-                     LRandom* instr,
-                     const X87Stack& x87_stack)
-        : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
-    virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
-   private:
-    LRandom* instr_;
-  };
-
-  DeferredDoRandom* deferred =
-      new(zone()) DeferredDoRandom(this, instr, x87_stack_);
-
   CpuFeatureScope scope(masm(), SSE2);
-  // Having marked this instruction as a call we can use any
-  // registers.
-  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
-  ASSERT(ToRegister(instr->global_object()).is(eax));
+
   // Assert that the register size is indeed the size of each seed.
   static const int kSeedSize = sizeof(uint32_t);
   STATIC_ASSERT(kPointerSize == kSeedSize);
 
-  __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
+  // Load native context
+  Register global_object = ToRegister(instr->global_object());
+  Register native_context = global_object;
+  __ mov(native_context, FieldOperand(
+          global_object, GlobalObject::kNativeContextOffset));
+
+  // Load state (FixedArray of the native context's random seeds)
   static const int kRandomSeedOffset =
       FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
-  __ mov(ebx, FieldOperand(eax, kRandomSeedOffset));
-  // ebx: FixedArray of the native context's random seeds
+  Register state = native_context;
+  __ mov(state, FieldOperand(native_context, kRandomSeedOffset));
 
   // Load state[0].
-  __ mov(ecx, FieldOperand(ebx, ByteArray::kHeaderSize));
-  // If state[0] == 0, call runtime to initialize seeds.
-  __ test(ecx, ecx);
-  __ j(zero, deferred->entry());
+  Register state0 = ToRegister(instr->scratch());
+  __ mov(state0, FieldOperand(state, ByteArray::kHeaderSize));
   // Load state[1].
-  __ mov(eax, FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize));
-  // ecx: state[0]
-  // eax: state[1]
+  Register state1 = ToRegister(instr->scratch2());
+  __ mov(state1, FieldOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
-  __ movzx_w(edx, ecx);
-  __ imul(edx, edx, 18273);
-  __ shr(ecx, 16);
-  __ add(ecx, edx);
+  Register scratch3 = ToRegister(instr->scratch3());
+  __ movzx_w(scratch3, state0);
+  __ imul(scratch3, scratch3, 18273);
+  __ shr(state0, 16);
+  __ add(state0, scratch3);
   // Save state[0].
-  __ mov(FieldOperand(ebx, ByteArray::kHeaderSize), ecx);
+  __ mov(FieldOperand(state, ByteArray::kHeaderSize), state0);
 
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
-  __ movzx_w(edx, eax);
-  __ imul(edx, edx, 36969);
-  __ shr(eax, 16);
-  __ add(eax, edx);
+  __ movzx_w(scratch3, state1);
+  __ imul(scratch3, scratch3, 36969);
+  __ shr(state1, 16);
+  __ add(state1, scratch3);
   // Save state[1].
-  __ mov(FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize), eax);
+  __ mov(FieldOperand(state, ByteArray::kHeaderSize + kSeedSize), state1);
 
   // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
-  __ shl(ecx, 14);
-  __ and_(eax, Immediate(0x3FFFF));
-  __ add(eax, ecx);
+  Register random = state0;
+  __ shl(random, 14);
+  __ and_(state1, Immediate(0x3FFFF));
+  __ add(random, state1);
 
-  __ bind(deferred->exit());
-  // Convert 32 random bits in eax to 0.(32 random bits) in a double
+  // Convert 32 random bits in random to 0.(32 random bits) in a double
   // by computing:
   // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
-  __ mov(ebx, Immediate(0x49800000));  // 1.0 x 2^20 as single.
-  __ movd(xmm2, ebx);
-  __ movd(xmm1, eax);
-  __ cvtss2sd(xmm2, xmm2);
-  __ xorps(xmm1, xmm2);
-  __ subsd(xmm1, xmm2);
-}
-
-
-void LCodeGen::DoDeferredRandom(LRandom* instr) {
-  __ PrepareCallCFunction(1, ebx);
-  __ mov(Operand(esp, 0), eax);
-  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
-  // Return value is in eax.
+  XMMRegister result = ToDoubleRegister(instr->result());
+  // We use xmm0 as fixed scratch register here.
+  XMMRegister scratch4 = xmm0;
+  __ mov(scratch3, Immediate(0x49800000));  // 1.0 x 2^20 as single.
+  __ movd(scratch4, scratch3);
+  __ movd(result, random);
+  __ cvtss2sd(scratch4, scratch4);
+  __ xorps(result, scratch4);
+  __ subsd(result, scratch4);
 }
 
 
@@ -5285,11 +5289,13 @@
   }
 
   __ bind(&load_smi);
-  __ SmiUntag(input_reg);  // Untag smi before converting to float.
-  __ push(input_reg);
+  // Clobbering a temp is faster than re-tagging the
+  // input register since we avoid dependencies.
+  __ mov(temp_reg, input_reg);
+  __ SmiUntag(temp_reg);  // Untag smi before converting to float.
+  __ push(temp_reg);
   __ fild_s(Operand(esp, 0));
-  __ pop(input_reg);
-  __ SmiTag(input_reg);  // Retag smi.
+  __ add(esp, Immediate(kPointerSize));
   __ bind(&done);
   X87CommitWrite(res_reg);
 }
@@ -5345,11 +5351,12 @@
     ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
   }
 
-  // Smi to XMM conversion
   __ bind(&load_smi);
-  __ SmiUntag(input_reg);  // Untag smi before converting to float.
-  __ cvtsi2sd(result_reg, Operand(input_reg));
-  __ SmiTag(input_reg);  // Retag smi.
+  // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the
+  // input register since we avoid dependencies.
+  __ mov(temp_reg, input_reg);
+  __ SmiUntag(temp_reg);  // Untag smi before converting to float.
+  __ cvtsi2sd(result_reg, Operand(temp_reg));
   __ bind(&done);
 }
 
@@ -5423,14 +5430,14 @@
   LOperand* input = instr->value();
   ASSERT(input->IsRegister());
   LOperand* temp = instr->temp();
-  ASSERT(temp == NULL || temp->IsRegister());
+  ASSERT(temp->IsRegister());
   LOperand* result = instr->result();
   ASSERT(result->IsDoubleRegister());
 
   Register input_reg = ToRegister(input);
   bool deoptimize_on_minus_zero =
       instr->hydrogen()->deoptimize_on_minus_zero();
-  Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
+  Register temp_reg = ToRegister(temp);
 
   HValue* value = instr->hydrogen()->value();
   NumberUntagDMode mode = value->representation().IsSmi()
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index cc1747d..769917f 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -166,7 +166,6 @@
   void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
-  void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredAllocate(LAllocate* instr);
@@ -471,6 +470,7 @@
     void PrepareToWrite(X87Register reg);
     void CommitWrite(X87Register reg);
     void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
+    void LeavingBlock(int current_block_id, LGoto* goto_instr);
     int depth() const { return stack_depth_; }
     void pop() {
       ASSERT(is_mutable_);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 07dbf13..ca1e60d 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -954,6 +954,16 @@
     if (FLAG_stress_environments && !instr->HasEnvironment()) {
       instr = AssignEnvironment(instr);
     }
+    if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() &&
+        LGoto::cast(instr)->jumps_to_join()) {
+      // TODO(olivf) Since phis of spilled values are joined as registers
+      // (not in the stack slot), we need to allow the goto gaps to keep one
+      // x87 register alive. To ensure all other values are still spilled, we
+      // insert a fpu register barrier right before.
+      LClobberDoubles* clobber = new(zone()) LClobberDoubles();
+      clobber->set_hydrogen_value(current);
+      chunk_->AddInstruction(clobber, current_block_);
+    }
     instr->set_hydrogen_value(current);
     chunk_->AddInstruction(instr, current_block_);
   }
@@ -1046,7 +1056,7 @@
 
 
 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
+  return new(zone()) LGoto(instr->FirstSuccessor());
 }
 
 
@@ -1058,7 +1068,7 @@
     HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
-    return new(zone()) LGoto(successor->block_id());
+    return new(zone()) LGoto(successor);
   }
 
   ToBooleanStub::Types expected = instr->expected_input_types();
@@ -1705,10 +1715,14 @@
 
 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
   ASSERT(instr->representation().IsDouble());
-  ASSERT(instr->global_object()->representation().IsSmiOrTagged());
-  LOperand* global_object = UseFixed(instr->global_object(), eax);
-  LRandom* result = new(zone()) LRandom(global_object);
-  return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+  ASSERT(instr->global_object()->representation().IsTagged());
+  LOperand* global_object = UseTempRegister(instr->global_object());
+  LOperand* scratch = TempRegister();
+  LOperand* scratch2 = TempRegister();
+  LOperand* scratch3 = TempRegister();
+  LRandom* result = new(zone()) LRandom(
+      global_object, scratch, scratch2, scratch3);
+  return DefineFixedDouble(result, xmm1);
 }
 
 
@@ -1933,9 +1947,7 @@
       info()->MarkAsDeferredCalling();
       LOperand* value = UseRegister(instr->value());
       // Temp register only necessary for minus zero check.
-      LOperand* temp = instr->deoptimize_on_minus_zero()
-                       ? TempRegister()
-                       : NULL;
+      LOperand* temp = TempRegister();
       LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
       return AssignEnvironment(DefineAsRegister(res));
     } else if (to.IsSmi()) {
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index ab964af..3a609c9 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -73,6 +73,7 @@
   V(ClampTToUint8)                              \
   V(ClampTToUint8NoSSE2)                        \
   V(ClassOfTestAndBranch)                       \
+  V(ClobberDoubles)                             \
   V(CompareNumericAndBranch)                    \
   V(CmpObjectEqAndBranch)                       \
   V(CmpHoleAndBranch)                           \
@@ -406,19 +407,32 @@
 };
 
 
+class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); }
+
+  virtual bool ClobbersDoubleRegisters() const { return true; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d")
+};
+
+
 class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  explicit LGoto(int block_id) : block_id_(block_id) { }
+  explicit LGoto(HBasicBlock* block) : block_(block) { }
 
   virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
   virtual bool IsControl() const V8_OVERRIDE { return true; }
 
-  int block_id() const { return block_id_; }
+  int block_id() const { return block_->block_id(); }
+  virtual bool ClobbersDoubleRegisters() const { return false; }
+
+  bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
 
  private:
-  int block_id_;
+  HBasicBlock* block_;
 };
 
 
@@ -1448,13 +1462,22 @@
 };
 
 
-class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
-  explicit LRandom(LOperand* global_object) {
+  LRandom(LOperand* global_object,
+          LOperand* scratch,
+          LOperand* scratch2,
+          LOperand* scratch3) {
     inputs_[0] = global_object;
+    temps_[0] = scratch;
+    temps_[1] = scratch2;
+    temps_[2] = scratch3;
   }
 
-  LOperand* global_object() { return inputs_[0]; }
+  LOperand* global_object() const { return inputs_[0]; }
+  LOperand* scratch() const { return temps_[0]; }
+  LOperand* scratch2() const { return temps_[1]; }
+  LOperand* scratch3() const { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(Random, "random")
   DECLARE_HYDROGEN_ACCESSOR(Random)
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index fbfe9dd..b65d328 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -2798,6 +2798,8 @@
 void MacroAssembler::VerifyX87StackDepth(uint32_t depth) {
   // Make sure the floating point stack is either empty or has depth items.
   ASSERT(depth <= 7);
+  // This is very expensive.
+  ASSERT(FLAG_debug_code && FLAG_enable_slow_asserts);
 
   // The top-of-stack (tos) is 7 if there is one item pushed.
   int tos = (8 - depth) % 8;
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index d2da43e..354c2fd 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -392,6 +392,11 @@
                                      Register holder,
                                      Register name,
                                      Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
   __ push(name);
   Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
   ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
@@ -400,8 +405,6 @@
   __ push(scratch);
   __ push(receiver);
   __ push(holder);
-  __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
-  __ push(Immediate(reinterpret_cast<int>(masm->isolate())));
 }
 
 
@@ -415,7 +418,7 @@
   __ CallExternalReference(
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate()),
-      6);
+      StubCache::kInterceptorArgsLength);
 }
 
 
@@ -733,7 +736,7 @@
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        6);
+        StubCache::kInterceptorArgsLength);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -1401,14 +1404,20 @@
   ASSERT(!scratch3().is(reg));
   __ pop(scratch3());  // Get return address to place it below.
 
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4);
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5);
   __ push(receiver());  // receiver
   __ mov(scratch2(), esp);
   ASSERT(!scratch2().is(reg));
-  __ push(reg);  // holder
   // Push data from ExecutableAccessorInfo.
   if (isolate()->heap()->InNewSpace(callback->data())) {
-    __ mov(scratch1(), Immediate(callback));
-    __ push(FieldOperand(scratch1(), ExecutableAccessorInfo::kDataOffset));
+    Register scratch = reg.is(scratch1()) ? receiver() : scratch1();
+    __ mov(scratch, Immediate(callback));
+    __ push(FieldOperand(scratch, ExecutableAccessorInfo::kDataOffset));
   } else {
     __ push(Immediate(Handle<Object>(callback->data(), isolate())));
   }
@@ -1416,6 +1425,7 @@
   // ReturnValue default value
   __ push(Immediate(isolate()->factory()->undefined_value()));
   __ push(Immediate(reinterpret_cast<int>(isolate())));
+  __ push(reg);  // holder
 
   // Save a pointer to where we pushed the arguments pointer.  This will be
   // passed as the const ExecutableAccessorInfo& to the C++ callback.
@@ -1450,7 +1460,7 @@
                               thunk_address,
                               ApiParameterOperand(2),
                               kStackSpace,
-                              6);
+                              7);
 }
 
 
@@ -1557,7 +1567,7 @@
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
                           isolate());
-    __ TailCallExternalReference(ref, 6, 1);
+    __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
   }
 }
 
diff --git a/src/ic.cc b/src/ic.cc
index 7211ad9..5518751 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -996,7 +996,7 @@
 
 
 bool IC::UpdatePolymorphicIC(State state,
-                             Handle<JSObject> receiver,
+                             Handle<HeapObject> receiver,
                              Handle<String> name,
                              Handle<Code> code,
                              StrictModeFlag strict_mode) {
@@ -1077,44 +1077,44 @@
 }
 
 
-void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
+void LoadIC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                  Handle<Code> handler,
                                  Handle<String> name,
                                  StrictModeFlag strict_mode) {
-  if (handler->type() == Code::NORMAL) return set_target(*handler);
+  if (handler->is_load_stub()) return set_target(*handler);
   Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicLoadIC(
       receiver, handler, name);
   set_target(*ic);
 }
 
 
-void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
+void KeyedLoadIC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                       Handle<Code> handler,
                                       Handle<String> name,
                                       StrictModeFlag strict_mode) {
-  if (handler->type() == Code::NORMAL) return set_target(*handler);
+  if (handler->is_keyed_load_stub()) return set_target(*handler);
   Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicKeyedLoadIC(
       receiver, handler, name);
   set_target(*ic);
 }
 
 
-void StoreIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
+void StoreIC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                   Handle<Code> handler,
                                   Handle<String> name,
                                   StrictModeFlag strict_mode) {
-  if (handler->type() == Code::NORMAL) return set_target(*handler);
+  if (handler->is_store_stub()) return set_target(*handler);
   Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicStoreIC(
       receiver, handler, name, strict_mode);
   set_target(*ic);
 }
 
 
-void KeyedStoreIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
+void KeyedStoreIC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                        Handle<Code> handler,
                                        Handle<String> name,
                                        StrictModeFlag strict_mode) {
-  if (handler->type() == Code::NORMAL) return set_target(*handler);
+  if (handler->is_keyed_store_stub()) return set_target(*handler);
   Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicKeyedStoreIC(
       receiver, handler, name, strict_mode);
   set_target(*ic);
@@ -1155,7 +1155,7 @@
 // not necessarily equal to target()->state().
 void IC::PatchCache(State state,
                     StrictModeFlag strict_mode,
-                    Handle<JSObject> receiver,
+                    Handle<HeapObject> receiver,
                     Handle<String> name,
                     Handle<Code> code) {
   switch (state) {
@@ -1265,32 +1265,26 @@
                           State state,
                           Handle<Object> object,
                           Handle<String> name) {
-  // Bail out if the result is not cacheable.
-  if (!lookup->IsCacheable()) {
-    set_target(*generic_stub());
-    return;
-  }
+  if (!object->IsHeapObject()) return;
 
-  // TODO(jkummerow): It would be nice to support non-JSObjects in
-  // UpdateCaches, then we wouldn't need to go generic here.
-  if (!object->IsJSObject()) {
-    set_target(*generic_stub());
-    return;
-  }
+  Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
 
-  Handle<JSObject> receiver = Handle<JSObject>::cast(object);
   Handle<Code> code;
   if (state == UNINITIALIZED) {
     // This is the first time we execute this inline cache.
     // Set the target to the pre monomorphic stub to delay
     // setting the monomorphic state.
     code = pre_monomorphic_stub();
+  } else if (!lookup->IsCacheable()) {
+    // Bail out if the result is not cacheable.
+    code = slow_stub();
+  } else if (!object->IsJSObject()) {
+    // TODO(jkummerow): It would be nice to support non-JSObjects in
+    // ComputeLoadHandler, then we wouldn't need to go generic here.
+    code = slow_stub();
   } else {
-    code = ComputeLoadHandler(lookup, receiver, name);
-    if (code.is_null()) {
-      set_target(*generic_stub());
-      return;
-    }
+    code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
+    if (code.is_null()) code = slow_stub();
   }
 
   PatchCache(state, kNonStrictMode, receiver, name, code);
diff --git a/src/ic.h b/src/ic.h
index 5c883cd..8f09e1d 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -167,14 +167,14 @@
   static inline void SetTargetAtAddress(Address address, Code* target);
   static void PostPatching(Address address, Code* target, Code* old_target);
 
-  virtual void UpdateMonomorphicIC(Handle<JSObject> receiver,
+  virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                    Handle<Code> handler,
                                    Handle<String> name,
                                    StrictModeFlag strict_mode) {
     set_target(*handler);
   }
   bool UpdatePolymorphicIC(State state,
-                           Handle<JSObject> receiver,
+                           Handle<HeapObject> receiver,
                            Handle<String> name,
                            Handle<Code> code,
                            StrictModeFlag strict_mode);
@@ -192,7 +192,7 @@
   bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map);
   void PatchCache(State state,
                   StrictModeFlag strict_mode,
-                  Handle<JSObject> receiver,
+                  Handle<HeapObject> receiver,
                   Handle<String> name,
                   Handle<Code> code);
   virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code);
@@ -388,7 +388,7 @@
  protected:
   virtual Code::Kind kind() const { return Code::LOAD_IC; }
 
-  virtual Handle<Code> generic_stub() const {
+  virtual Handle<Code> slow_stub() const {
     return isolate()->builtins()->LoadIC_Slow();
   }
 
@@ -403,7 +403,7 @@
                     Handle<Object> object,
                     Handle<String> name);
 
-  virtual void UpdateMonomorphicIC(Handle<JSObject> receiver,
+  virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                    Handle<Code> handler,
                                    Handle<String> name,
                                    StrictModeFlag strict_mode);
@@ -483,9 +483,12 @@
   virtual Handle<Code> generic_stub() const {
     return isolate()->builtins()->KeyedLoadIC_Generic();
   }
+  virtual Handle<Code> slow_stub() const {
+    return isolate()->builtins()->KeyedLoadIC_Slow();
+  }
 
   // Update the inline cache.
-  virtual void UpdateMonomorphicIC(Handle<JSObject> receiver,
+  virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                    Handle<Code> handler,
                                    Handle<String> name,
                                    StrictModeFlag strict_mode);
@@ -574,7 +577,7 @@
     return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
   }
 
-  virtual void UpdateMonomorphicIC(Handle<JSObject> receiver,
+  virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                    Handle<Code> handler,
                                    Handle<String> name,
                                    StrictModeFlag strict_mode);
@@ -689,7 +692,7 @@
                                 KeyedAccessStoreMode store_mode,
                                 StrictModeFlag strict_mode);
 
-  virtual void UpdateMonomorphicIC(Handle<JSObject> receiver,
+  virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
                                    Handle<Code> handler,
                                    Handle<String> name,
                                    StrictModeFlag strict_mode);
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index f27ded7..3aabd97 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -299,6 +299,24 @@
 }
 
 
+static void CallRuntimePassFunction(MacroAssembler* masm,
+                                    Runtime::FunctionId function_id) {
+  FrameScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function onto the stack.
+  __ push(a1);
+  // Push call kind information.
+  __ push(t1);
+  // Function is also the parameter to the runtime call.
+  __ push(a1);
+
+  __ CallRuntime(function_id, 1);
+  // Restore call kind information.
+  __ pop(t1);
+  // Restore receiver.
+  __ pop(a1);
+}
+
+
 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
   __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
@@ -308,59 +326,27 @@
 
 
 void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+  // Checking whether the queued function is ready for install is optional,
+  // since we come across interrupts and stack checks elsewhere.  However,
+  // not checking may delay installing ready functions, and always checking
+  // would be quite expensive.  A good compromise is to first check against
+  // stack limit as a cue for an interrupt signal.
+  Label ok;
+  __ LoadRoot(t0, Heap::kStackLimitRootIndex);
+  __ Branch(&ok, hs, sp, Operand(t0));
+
+  CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode);
+  // Tail call to returned code.
+  __ Addu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ Jump(at);
+
+  __ bind(&ok);
   GenerateTailCallToSharedCode(masm);
 }
 
 
-void Builtins::Generate_InstallRecompiledCode(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(a1);
-    // Push call kind information.
-    __ push(t1);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(a1);
-    __ CallRuntime(Runtime::kInstallRecompiledCode, 1);
-    // Calculate the entry point.
-    __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Restore call kind information.
-    __ pop(t1);
-    // Restore saved function.
-    __ pop(a1);
-
-    // Tear down temporary frame.
-  }
-
-  // Do a tail-call of the compiled function.
-  __ Jump(t9);
-}
-
-
 void Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(a1);
-    // Push call kind information.
-    __ push(t1);
-
-    __ push(a1);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kConcurrentRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(t1);
-    // Restore receiver.
-    __ pop(a1);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile);
   GenerateTailCallToSharedCode(masm);
 }
 
@@ -815,60 +801,17 @@
 
 
 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(a1);
-    // Push call kind information.
-    __ push(t1);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(a1);
-    // Call the runtime function.
-    __ CallRuntime(Runtime::kLazyCompile, 1);
-    // Calculate the entry point.
-    __ addiu(t9, v0, Code::kHeaderSize - kHeapObjectTag);
-
-    // Restore call kind information.
-    __ pop(t1);
-    // Restore saved function.
-    __ pop(a1);
-
-    // Tear down temporary frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyCompile);
   // Do a tail-call of the compiled function.
+  __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ Jump(t9);
 }
 
 
 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Preserve the function.
-    __ push(a1);
-    // Push call kind information.
-    __ push(t1);
-
-    // Push the function on the stack as the argument to the runtime function.
-    __ push(a1);
-    __ CallRuntime(Runtime::kLazyRecompile, 1);
-    // Calculate the entry point.
-    __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Restore call kind information.
-    __ pop(t1);
-    // Restore saved function.
-    __ pop(a1);
-
-    // Tear down temporary frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyRecompile);
   // Do a tail-call of the compiled function.
+  __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ Jump(t9);
 }
 
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index b536209..0589bf0 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -5861,7 +5861,6 @@
   __ Branch(&done, lt, scratch1, Operand(FIRST_NONSTRING_TYPE));
 
   // Check the number to string cache.
-  Label not_cached;
   __ bind(&not_string);
   // Puts the cached result into scratch1.
   NumberToStringStub::GenerateLookupNumberStringCache(masm,
@@ -5870,23 +5869,9 @@
                                                       scratch2,
                                                       scratch3,
                                                       scratch4,
-                                                      &not_cached);
+                                                      slow);
   __ mov(arg, scratch1);
   __ sw(arg, MemOperand(sp, stack_offset));
-  __ jmp(&done);
-
-  // Check if the argument is a safe string wrapper.
-  __ bind(&not_cached);
-  __ JumpIfSmi(arg, slow);
-  __ GetObjectType(arg, scratch1, scratch2);  // map -> scratch1.
-  __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE));
-  __ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
-  __ li(scratch4, 1 << Map::kStringWrapperSafeForDefaultValueOf);
-  __ And(scratch2, scratch2, scratch4);
-  __ Branch(slow, ne, scratch2, Operand(scratch4));
-  __ lw(arg, FieldMemOperand(arg, JSValue::kValueOffset));
-  __ sw(arg, MemOperand(sp, stack_offset));
-
   __ bind(&done);
 }
 
@@ -6983,87 +6968,125 @@
 
 
 template<class T>
-static void CreateArrayDispatch(MacroAssembler* masm) {
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ Branch(&next, ne, a3, Operand(kind));
-    T stub(kind);
+static void CreateArrayDispatch(MacroAssembler* masm,
+                                AllocationSiteOverrideMode mode) {
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    T stub(GetInitialFastElementsKind(),
+           CONTEXT_CHECK_REQUIRED,
+           mode);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ Branch(&next, ne, a3, Operand(kind));
+      T stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
-static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
-  // a2 - type info cell
-  // a3 - kind
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
+                                           AllocationSiteOverrideMode mode) {
+  // a2 - type info cell (if mode != DISABLE_ALLOCATION_SITES)
+  // a3 - kind (if mode != DISABLE_ALLOCATION_SITES)
   // a0 - number of arguments
   // a1 - constructor?
   // sp[0] - last argument
-  ASSERT(FAST_SMI_ELEMENTS == 0);
-  ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
-  ASSERT(FAST_ELEMENTS == 2);
-  ASSERT(FAST_HOLEY_ELEMENTS == 3);
-  ASSERT(FAST_DOUBLE_ELEMENTS == 4);
-  ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
-
-  // is the low bit set? If so, we are holey and that is good.
   Label normal_sequence;
-  __ And(at, a3, Operand(1));
-  __ Branch(&normal_sequence, ne, at, Operand(zero_reg));
+  if (mode == DONT_OVERRIDE) {
+    ASSERT(FAST_SMI_ELEMENTS == 0);
+    ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+    ASSERT(FAST_ELEMENTS == 2);
+    ASSERT(FAST_HOLEY_ELEMENTS == 3);
+    ASSERT(FAST_DOUBLE_ELEMENTS == 4);
+    ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
+
+    // is the low bit set? If so, we are holey and that is good.
+    __ And(at, a3, Operand(1));
+    __ Branch(&normal_sequence, ne, at, Operand(zero_reg));
+  }
 
   // look at the first argument
   __ lw(t1, MemOperand(sp, 0));
   __ Branch(&normal_sequence, eq, t1, Operand(zero_reg));
 
-  // We are going to create a holey array, but our kind is non-holey.
-  // Fix kind and retry (only if we have an allocation site in the cell).
-  __ Addu(a3, a3, Operand(1));
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(&normal_sequence, eq, a2, Operand(at));
-  __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
-  __ lw(t1, FieldMemOperand(t1, 0));
-  __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
-  __ Branch(&normal_sequence, ne, t1, Operand(at));
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    ElementsKind initial = GetInitialFastElementsKind();
+    ElementsKind holey_initial = GetHoleyElementsKind(initial);
 
-  // Save the resulting elements kind in type info
-  __ SmiTag(a3);
-  __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
-  __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset));
-  __ SmiUntag(a3);
+    ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+                                                  CONTEXT_CHECK_REQUIRED,
+                                                  DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub_holey);
 
-  __ bind(&normal_sequence);
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ Branch(&next, ne, a3, Operand(kind));
-    ArraySingleArgumentConstructorStub stub(kind);
+    __ bind(&normal_sequence);
+    ArraySingleArgumentConstructorStub stub(initial,
+                                            CONTEXT_CHECK_REQUIRED,
+                                            DISABLE_ALLOCATION_SITES);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    // We are going to create a holey array, but our kind is non-holey.
+    // Fix kind and retry (only if we have an allocation site in the cell).
+    __ Addu(a3, a3, Operand(1));
+    __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    if (FLAG_debug_code) {
+      __ lw(t1, FieldMemOperand(t1, 0));
+      __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
+      __ Assert(eq, kExpectedAllocationSiteInCell, t1, Operand(at));
+      __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
+    }
+
+    // Save the resulting elements kind in type info
+    __ SmiTag(a3);
+    __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
+    __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset));
+    __ SmiUntag(a3);
+
+    __ bind(&normal_sequence);
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ Branch(&next, ne, a3, Operand(kind));
+      ArraySingleArgumentConstructorStub stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
 template<class T>
 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
+  ElementsKind initial_kind = GetInitialFastElementsKind();
+  ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
+
   int to_index = GetSequenceIndexFromFastElementsKind(
       TERMINAL_FAST_ELEMENTS_KIND);
   for (int i = 0; i <= to_index; ++i) {
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
-    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
+        (!FLAG_track_allocation_sites &&
+         (kind == initial_kind || kind == initial_holey_kind))) {
       T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
       stub1.GetCode(isolate)->set_is_pregenerated(true);
     }
@@ -7096,6 +7119,33 @@
 }
 
 
+void ArrayConstructorStub::GenerateDispatchToArrayStub(
+    MacroAssembler* masm,
+    AllocationSiteOverrideMode mode) {
+  if (argument_count_ == ANY) {
+    Label not_zero_case, not_one_case;
+    __ And(at, a0, a0);
+    __ Branch(&not_zero_case, ne, at, Operand(zero_reg));
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+
+    __ bind(&not_zero_case);
+    __ Branch(&not_one_case, gt, a0, Operand(1));
+    CreateArrayDispatchOneArgument(masm, mode);
+
+    __ bind(&not_one_case);
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else if (argument_count_ == NONE) {
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+  } else if (argument_count_ == ONE) {
+    CreateArrayDispatchOneArgument(masm, mode);
+  } else if (argument_count_ == MORE_THAN_ONE) {
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- a0 : argc (only if argument_count_ == ANY)
@@ -7129,49 +7179,24 @@
     __ bind(&okay_here);
   }
 
-  Label no_info, switch_ready;
+  Label no_info;
   // Get the elements kind and case on that.
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
   __ Branch(&no_info, eq, a2, Operand(at));
   __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
 
-  // The type cell may have undefined in its value.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(&no_info, eq, a3, Operand(at));
-
-  // The type cell has either an AllocationSite or a JSFunction.
+  // If the type cell is undefined, or contains anything other than an
+  // AllocationSite, call an array constructor that doesn't use AllocationSites.
   __ lw(t0, FieldMemOperand(a3, 0));
   __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
   __ Branch(&no_info, ne, t0, Operand(at));
 
   __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset));
   __ SmiUntag(a3);
-  __ jmp(&switch_ready);
+  GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
+
   __ bind(&no_info);
-  __ li(a3, Operand(GetInitialFastElementsKind()));
-  __ bind(&switch_ready);
-
-  if (argument_count_ == ANY) {
-    Label not_zero_case, not_one_case;
-    __ And(at, a0, a0);
-    __ Branch(&not_zero_case, ne, at, Operand(zero_reg));
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-
-    __ bind(&not_zero_case);
-    __ Branch(&not_one_case, gt, a0, Operand(1));
-    CreateArrayDispatchOneArgument(masm);
-
-    __ bind(&not_one_case);
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else if (argument_count_ == NONE) {
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-  } else if (argument_count_ == ONE) {
-    CreateArrayDispatchOneArgument(masm);
-  } else if (argument_count_ == MORE_THAN_ONE) {
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else {
-    UNREACHABLE();
-  }
+  GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
 }
 
 
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index bf6f1c8..df3f417 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -3028,7 +3028,7 @@
 
   VisitForAccumulatorValue(args->at(0));
 
-  Label materialize_true, materialize_false;
+  Label materialize_true, materialize_false, skip_lookup;
   Label* if_true = NULL;
   Label* if_false = NULL;
   Label* fall_through = NULL;
@@ -3040,7 +3040,7 @@
   __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
   __ lbu(t0, FieldMemOperand(a1, Map::kBitField2Offset));
   __ And(t0, t0, 1 << Map::kStringWrapperSafeForDefaultValueOf);
-  __ Branch(if_true, ne, t0, Operand(zero_reg));
+  __ Branch(&skip_lookup, ne, t0, Operand(zero_reg));
 
   // Check for fast case object. Generate false result for slow case object.
   __ lw(a2, FieldMemOperand(v0, JSObject::kPropertiesOffset));
@@ -3086,6 +3086,14 @@
   __ Branch(&loop, ne, t0, Operand(a2));
 
   __ bind(&done);
+
+  // Set the bit in the map to indicate that there is no local valueOf field.
+  __ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset));
+  __ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
+  __ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset));
+
+  __ bind(&skip_lookup);
+
   // If a valueOf property is not found on the object check that its
   // prototype is the un-modified String prototype. If not result is false.
   __ lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
@@ -3094,11 +3102,9 @@
   __ lw(a3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
   __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
   __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
-  __ Branch(if_false, ne, a2, Operand(a3));
-
-  __ jmp(if_true);
-
   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, a2, Operand(a3), if_true, if_false, fall_through);
+
   context()->Plug(if_true, if_false);
 }
 
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index ab713a3..b37c7e0 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -3813,79 +3813,64 @@
 
 
 void LCodeGen::DoRandom(LRandom* instr) {
-  class DeferredDoRandom V8_FINAL : public LDeferredCode {
-   public:
-    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
-    virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
-   private:
-    LRandom* instr_;
-  };
-
-  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
-  // Having marked this instruction as a call we can use any
-  // registers.
-  ASSERT(ToDoubleRegister(instr->result()).is(f0));
-  ASSERT(ToRegister(instr->global_object()).is(a0));
-
+  // Assert that the register size is indeed the size of each seed.
   static const int kSeedSize = sizeof(uint32_t);
   STATIC_ASSERT(kPointerSize == kSeedSize);
 
-  __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
+  // Load native context.
+  Register global_object = ToRegister(instr->global_object());
+  Register native_context = global_object;
+  __ lw(native_context, FieldMemOperand(
+          global_object, GlobalObject::kNativeContextOffset));
+
+  // Load state (FixedArray of the native context's random seeds).
   static const int kRandomSeedOffset =
       FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
-  __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset));
-  // a2: FixedArray of the native context's random seeds
+  Register state = native_context;
+  __ lw(state, FieldMemOperand(native_context, kRandomSeedOffset));
 
   // Load state[0].
-  __ lw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize));
-  __ Branch(deferred->entry(), eq, a1, Operand(zero_reg));
+  Register state0 = ToRegister(instr->scratch());
+  __ lw(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
   // Load state[1].
-  __ lw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize));
-  // a1: state[0].
-  // a0: state[1].
+  Register state1 = ToRegister(instr->scratch2());
+  __ lw(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
-  __ And(a3, a1, Operand(0xFFFF));
-  __ li(t0, Operand(18273));
-  __ Mul(a3, a3, t0);
-  __ srl(a1, a1, 16);
-  __ Addu(a1, a3, a1);
+  Register scratch3 = ToRegister(instr->scratch3());
+  Register scratch4 = scratch0();
+  __ And(scratch3, state0, Operand(0xFFFF));
+  __ li(scratch4, Operand(18273));
+  __ Mul(scratch3, scratch3, scratch4);
+  __ srl(state0, state0, 16);
+  __ Addu(state0, scratch3, state0);
   // Save state[0].
-  __ sw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize));
+  __ sw(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
 
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
-  __ And(a3, a0, Operand(0xFFFF));
-  __ li(t0, Operand(36969));
-  __ Mul(a3, a3, t0);
-  __ srl(a0, a0, 16),
-  __ Addu(a0, a3, a0);
+  __ And(scratch3, state1, Operand(0xFFFF));
+  __ li(scratch4, Operand(36969));
+  __ Mul(scratch3, scratch3, scratch4);
+  __ srl(state1, state1, 16),
+  __ Addu(state1, scratch3, state1);
   // Save state[1].
-  __ sw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize));
+  __ sw(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
-  __ And(a0, a0, Operand(0x3FFFF));
-  __ sll(a1, a1, 14);
-  __ Addu(v0, a0, a1);
-
-  __ bind(deferred->exit());
+  Register random = scratch4;
+  __ And(random, state1, Operand(0x3FFFF));
+  __ sll(state0, state0, 14);
+  __ Addu(random, random, state0);
 
   // 0x41300000 is the top half of 1.0 x 2^20 as a double.
-  __ li(a2, Operand(0x41300000));
+  __ li(scratch3, Operand(0x41300000));
   // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU.
-  __ Move(f12, v0, a2);
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  __ Move(result, random, scratch3);
   // Move 0x4130000000000000 to FPU.
-  __ Move(f14, zero_reg, a2);
-  // Subtract to get the result.
-  __ sub_d(f0, f12, f14);
-}
-
-
-void LCodeGen::DoDeferredRandom(LRandom* instr) {
-  __ PrepareCallCFunction(1, scratch0());
-  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
-  // Return value is in v0.
+  DoubleRegister scratch5 = double_scratch0();
+  __ Move(scratch5, zero_reg, scratch3);
+  __ sub_d(result, result, scratch5);
 }
 
 
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 8437435..84105ca 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -147,7 +147,6 @@
   void DoDeferredTaggedToI(LTaggedToI* instr);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
-  void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredAllocate(LAllocate* instr);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 9476f4d..4dc8022 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1624,9 +1624,13 @@
 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->global_object()->representation().IsTagged());
-  LOperand* global_object = UseFixed(instr->global_object(), a0);
-  LRandom* result = new(zone()) LRandom(global_object);
-  return MarkAsCall(DefineFixedDouble(result, f0), instr);
+  LOperand* global_object = UseTempRegister(instr->global_object());
+  LOperand* scratch = TempRegister();
+  LOperand* scratch2 = TempRegister();
+  LOperand* scratch3 = TempRegister();
+  LRandom* result = new(zone()) LRandom(
+      global_object, scratch, scratch2, scratch3);
+  return DefineFixedDouble(result, f0);
 }
 
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index fa2aed5..29a8eac 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -1444,13 +1444,22 @@
 };
 
 
-class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
-  explicit LRandom(LOperand* global_object) {
+  LRandom(LOperand* global_object,
+          LOperand* scratch,
+          LOperand* scratch2,
+          LOperand* scratch3) {
     inputs_[0] = global_object;
+    temps_[0] = scratch;
+    temps_[1] = scratch2;
+    temps_[2] = scratch3;
   }
 
-  LOperand* global_object() { return inputs_[0]; }
+  LOperand* global_object() const { return inputs_[0]; }
+  LOperand* scratch() const { return temps_[0]; }
+  LOperand* scratch2() const { return temps_[1]; }
+  LOperand* scratch3() const { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(Random, "random")
   DECLARE_HYDROGEN_ACCESSOR(Random)
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index a8004d9..58452ca 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -777,16 +777,17 @@
                                      Register holder,
                                      Register name,
                                      Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
   __ push(name);
   Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
   ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
   Register scratch = name;
   __ li(scratch, Operand(interceptor));
   __ Push(scratch, receiver, holder);
-  __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
-  __ push(scratch);
-  __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ push(scratch);
 }
 
 
@@ -801,7 +802,7 @@
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
           masm->isolate());
-  __ PrepareCEntryArgs(6);
+  __ PrepareCEntryArgs(StubCache::kInterceptorArgsLength);
   __ PrepareCEntryFunction(ref);
 
   CEntryStub stub(1);
@@ -1107,7 +1108,7 @@
           ExternalReference(
               IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
               masm->isolate()),
-          6);
+          StubCache::kInterceptorArgsLength);
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1415,6 +1416,15 @@
     Handle<ExecutableAccessorInfo> callback) {
   // Build AccessorInfo::args_ list on the stack and push property name below
   // the exit frame to make GC aware of them and store pointers to them.
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4);
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5);
+  ASSERT(!scratch2().is(reg));
+  ASSERT(!scratch3().is(reg));
+  ASSERT(!scratch4().is(reg));
   __ push(receiver());
   __ mov(scratch2(), sp);  // scratch2 = AccessorInfo::args_
   if (heap()->InNewSpace(callback->data())) {
@@ -1425,14 +1435,14 @@
     __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
   }
   __ Subu(sp, sp, 6 * kPointerSize);
-  __ sw(reg, MemOperand(sp, 5 * kPointerSize));
-  __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize));
+  __ sw(scratch3(), MemOperand(sp, 5 * kPointerSize));
   __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
+  __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize));
   __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
-  __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize));
   __ li(scratch4(),
         Operand(ExternalReference::isolate_address(isolate())));
-  __ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
+  __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
+  __ sw(reg, MemOperand(sp, 1 * kPointerSize));
   __ sw(name(), MemOperand(sp, 0 * kPointerSize));
 
   __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
@@ -1465,7 +1475,7 @@
                               thunk_ref,
                               a2,
                               kStackUnwindSpace,
-                              5);
+                              6);
 }
 
 
@@ -1550,7 +1560,7 @@
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
-    __ TailCallExternalReference(ref, 6, 1);
+    __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
   }
 }
 
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index efd6e79..9cf9e2e 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -314,9 +314,6 @@
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
 
-  // Disable the i18n extension, as it doesn't support being snapshotted yet.
-  i::FLAG_enable_i18n = false;
-
   // Print the usage if an error occurs when parsing the command line
   // flags or if the help flag is set.
   int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
diff --git a/src/natives.h b/src/natives.h
index e3f69d1..5f34420 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -36,7 +36,7 @@
                                      int index);
 
 enum NativeType {
-  CORE, EXPERIMENTAL, D8, TEST, I18N
+  CORE, EXPERIMENTAL, D8, TEST
 };
 
 template <NativeType type>
@@ -61,7 +61,6 @@
 
 typedef NativesCollection<CORE> Natives;
 typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;
-typedef NativesCollection<I18N> I18NNatives;
 
 } }  // namespace v8::internal
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index c2dc750..89abe50 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4970,12 +4970,6 @@
 }
 
 
-bool JSFunction::IsMarkedForInstallingRecompiledCode() {
-  return code() == GetIsolate()->builtins()->builtin(
-      Builtins::kInstallRecompiledCode);
-}
-
-
 bool JSFunction::IsMarkedForConcurrentRecompilation() {
   return code() == GetIsolate()->builtins()->builtin(
       Builtins::kConcurrentRecompile);
diff --git a/src/objects.cc b/src/objects.cc
index 43e3f53..e37f6d1 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4479,18 +4479,19 @@
 }
 
 
-void JSObject::UpdateMapCodeCache(Handle<JSObject> object,
-                                  Handle<Name> name,
-                                  Handle<Code> code) {
+void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
+                                    Handle<Name> name,
+                                    Handle<Code> code) {
   Handle<Map> map(object->map());
   if (map->is_shared()) {
+    Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     // Fast case maps are never marked as shared.
-    ASSERT(!object->HasFastProperties());
+    ASSERT(!receiver->HasFastProperties());
     // Replace the map with an identical copy that can be safely modified.
     map = Map::CopyNormalized(map, KEEP_INOBJECT_PROPERTIES,
                               UNIQUE_NORMALIZED_MAP);
-    object->GetIsolate()->counters()->normalized_maps()->Increment();
-    object->set_map(*map);
+    receiver->GetIsolate()->counters()->normalized_maps()->Increment();
+    receiver->set_map(*map);
   }
   Map::UpdateCodeCache(map, name, code);
 }
@@ -9321,18 +9322,6 @@
 }
 
 
-void JSFunction::MarkForInstallingRecompiledCode() {
-  // The debugger could have switched the builtin to lazy compile.
-  // In that case, simply carry on.  It will be dealt with later.
-  ASSERT(!IsOptimized());
-  ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
-  ASSERT(FLAG_concurrent_recompilation);
-  set_code_no_write_barrier(
-      GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode));
-  // No write barrier required, since the builtin is part of the root set.
-}
-
-
 void JSFunction::MarkInRecompileQueue() {
   // We can only arrive here via the concurrent-recompilation builtin.  If
   // break points were set, the code would point to the lazy-compile builtin.
@@ -13806,6 +13795,74 @@
 
 
 template<typename Shape, typename Key>
+uint32_t HashTable<Shape, Key>::EntryForProbe(Key key,
+                                              Object* k,
+                                              int probe,
+                                              uint32_t expected) {
+  uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
+  uint32_t capacity = Capacity();
+  uint32_t entry = FirstProbe(hash, capacity);
+  for (int i = 1; i < probe; i++) {
+    if (entry == expected) return expected;
+    entry = NextProbe(entry, i, capacity);
+  }
+  return entry;
+}
+
+
+template<typename Shape, typename Key>
+void HashTable<Shape, Key>::Swap(uint32_t entry1,
+                                 uint32_t entry2,
+                                 WriteBarrierMode mode) {
+  int index1 = EntryToIndex(entry1);
+  int index2 = EntryToIndex(entry2);
+  Object* temp[Shape::kEntrySize];
+  for (int j = 0; j < Shape::kEntrySize; j++) {
+    temp[j] = get(index1 + j);
+  }
+  for (int j = 0; j < Shape::kEntrySize; j++) {
+    set(index1 + j, get(index2 + j), mode);
+  }
+  for (int j = 0; j < Shape::kEntrySize; j++) {
+    set(index2 + j, temp[j], mode);
+  }
+}
+
+
+template<typename Shape, typename Key>
+void HashTable<Shape, Key>::Rehash(Key key) {
+  DisallowHeapAllocation no_gc;
+  WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
+  uint32_t capacity = Capacity();
+  bool done = false;
+  for (int probe = 1; !done; probe++) {
+    // All elements at entries given by one of the first _probe_ probes
+    // are placed correctly. Other elements might need to be moved.
+    done = true;
+    for (uint32_t current = 0; current < capacity; current++) {
+      Object* current_key = get(EntryToIndex(current));
+      if (IsKey(current_key)) {
+        uint32_t target = EntryForProbe(key, current_key, probe, current);
+        if (current == target) continue;
+        Object* target_key = get(EntryToIndex(target));
+        if (!IsKey(target_key) ||
+            EntryForProbe(key, target_key, probe, target) != target) {
+          // Put the current element into the correct position.
+          Swap(current, target, mode);
+          // The other element will be processed on the next iteration.
+          current--;
+        } else {
+          // The place for the current element is occupied. Leave the element
+          // for the next probe.
+          done = false;
+        }
+      }
+    }
+  }
+}
+
+
+template<typename Shape, typename Key>
 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
   int capacity = Capacity();
   int nof = NumberOfElements() + n;
diff --git a/src/objects.h b/src/objects.h
index af0a891..d3593b6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1113,6 +1113,8 @@
   V(kEval, "eval")                                                            \
   V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel")                 \
   V(kExpectedAlignmentMarker, "expected alignment marker")                    \
+  V(kExpectedAllocationSiteInCell,                                            \
+    "Expected AllocationSite in property cell")                               \
   V(kExpectedPropertyCellInRegisterA2,                                        \
     "Expected property cell in register a2")                                  \
   V(kExpectedPropertyCellInRegisterEbx,                                       \
@@ -1756,6 +1758,13 @@
   // during marking GC.
   static inline Object** RawField(HeapObject* obj, int offset);
 
+  // Adds the |code| object related to |name| to the code cache of this map. If
+  // this map is a dictionary map that is shared, the map copied and installed
+  // onto the object.
+  static void UpdateMapCodeCache(Handle<HeapObject> object,
+                                 Handle<Name> name,
+                                 Handle<Code> code);
+
   // Casting.
   static inline HeapObject* cast(Object* obj);
 
@@ -2188,13 +2197,6 @@
   inline MUST_USE_RESULT MaybeObject* TryMigrateInstance();
 
   // Can cause GC.
-  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
-      Name* key,
-      Object* value,
-      PropertyAttributes attributes,
-      ValueType value_type = OPTIMAL_REPRESENTATION,
-      StoreMode mode = ALLOW_AS_CONSTANT,
-      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
   MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributesTrampoline(
       Name* key,
       Object* value,
@@ -2574,10 +2576,6 @@
 
   MUST_USE_RESULT MaybeObject* NormalizeElements();
 
-  static void UpdateMapCodeCache(Handle<JSObject> object,
-                                 Handle<Name> name,
-                                 Handle<Code> code);
-
   // Transform slow named properties to fast variants.
   // Returns failure if allocation failed.
   static void TransformToFastProperties(Handle<JSObject> object,
@@ -2736,6 +2734,15 @@
   friend class DictionaryElementsAccessor;
   friend class JSReceiver;
 
+  // TODO(mstarzinger): Soon to be handlified.
+  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
+      Name* key,
+      Object* value,
+      PropertyAttributes attributes,
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT,
+      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
+
   MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
                                                       Object* structure,
                                                       uint32_t index,
@@ -3473,6 +3480,9 @@
   inline int FindEntry(Key key);
   int FindEntry(Isolate* isolate, Key key);
 
+  // Rehashes the table in-place.
+  void Rehash(Key key);
+
  protected:
   // Find the entry at which to insert element with the given key that
   // has the given hash value.
@@ -3519,6 +3529,13 @@
     return (last + number) & (size - 1);
   }
 
+  // Returns _expected_ if one of entries given by the first _probe_ probes is
+  // equal to  _expected_. Otherwise, returns the entry given by the probe
+  // number _probe_.
+  uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
+
+  void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
+
   // Rehashes this hash-table into the new table.
   MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
 
@@ -5909,6 +5926,10 @@
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
 
+  bool IsJSObjectMap() {
+    return instance_type() >= FIRST_JS_OBJECT_TYPE;
+  }
+
   // Fires when the layout of an object with a leaf map changes.
   // This includes adding transitions to the leaf map or changing
   // the descriptor array.
@@ -6979,7 +7000,6 @@
   // recompiled the next time it is executed.
   void MarkForLazyRecompilation();
   void MarkForConcurrentRecompilation();
-  void MarkForInstallingRecompiledCode();
   void MarkInRecompileQueue();
 
   // Helpers to compile this function.  Returns true on success, false on
@@ -6998,7 +7018,6 @@
   // recompilation.
   inline bool IsMarkedForLazyRecompilation();
   inline bool IsMarkedForConcurrentRecompilation();
-  inline bool IsMarkedForInstallingRecompiledCode();
 
   // Tells whether or not the function is on the concurrent recompilation queue.
   inline bool IsInRecompileQueue();
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index a040453..085143d 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -114,11 +114,8 @@
     osr_candidates_.RemoveElement(optimizing_compiler);
     ready_for_osr_.Add(optimizing_compiler);
   } else {
-    LockGuard<Mutex> mark_and_queue(&install_mutex_);
-    Heap::RelocationLock relocation_lock(isolate_->heap());
-    AllowHandleDereference ahd;
-    optimizing_compiler->info()->closure()->MarkForInstallingRecompiledCode();
     output_queue_.Enqueue(optimizing_compiler);
+    isolate_->stack_guard()->RequestInstallCode();
   }
 }
 
@@ -201,10 +198,7 @@
   HandleScope handle_scope(isolate_);
   OptimizingCompiler* compiler;
   while (true) {
-    { // Memory barrier to ensure marked functions are queued.
-      LockGuard<Mutex> marked_and_queued(&install_mutex_);
-      if (!output_queue_.Dequeue(&compiler)) return;
-    }
+    if (!output_queue_.Dequeue(&compiler)) return;
     Compiler::InstallOptimizedCode(compiler);
   }
 
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index f45665b..d1ed6a2 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -120,7 +120,6 @@
   // List of recompilation tasks ready for OSR.
   List<OptimizingCompiler*> ready_for_osr_;
 
-  Mutex install_mutex_;
   volatile AtomicWord stop_thread_;
   volatile Atomic32 queue_length_;
   TimeDelta time_spent_compiling_;
diff --git a/src/platform/elapsed-timer.h b/src/platform/elapsed-timer.h
index 8044bd0..2311db2 100644
--- a/src/platform/elapsed-timer.h
+++ b/src/platform/elapsed-timer.h
@@ -103,7 +103,7 @@
   }
 
  private:
-  V8_INLINE(static TimeTicks Now()) {
+  static V8_INLINE TimeTicks Now() {
     TimeTicks now = TimeTicks::HighResNow();
     ASSERT(!now.IsNull());
     return now;
diff --git a/src/platform/mutex.cc b/src/platform/mutex.cc
index 1a7c69a..ad97740 100644
--- a/src/platform/mutex.cc
+++ b/src/platform/mutex.cc
@@ -34,7 +34,7 @@
 
 #if V8_OS_POSIX
 
-static V8_INLINE(void InitializeNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE void InitializeNativeHandle(pthread_mutex_t* mutex) {
   int result;
 #if defined(DEBUG)
   // Use an error checking mutex in debug mode.
@@ -55,7 +55,7 @@
 }
 
 
-static V8_INLINE(void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
   pthread_mutexattr_t attr;
   int result = pthread_mutexattr_init(&attr);
   ASSERT_EQ(0, result);
@@ -69,28 +69,28 @@
 }
 
 
-static V8_INLINE(void DestroyNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
   int result = pthread_mutex_destroy(mutex);
   ASSERT_EQ(0, result);
   USE(result);
 }
 
 
-static V8_INLINE(void LockNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
   int result = pthread_mutex_lock(mutex);
   ASSERT_EQ(0, result);
   USE(result);
 }
 
 
-static V8_INLINE(void UnlockNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
   int result = pthread_mutex_unlock(mutex);
   ASSERT_EQ(0, result);
   USE(result);
 }
 
 
-static V8_INLINE(bool TryLockNativeHandle(pthread_mutex_t* mutex)) {
+static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
   int result = pthread_mutex_trylock(mutex);
   if (result == EBUSY) {
     return false;
@@ -101,32 +101,32 @@
 
 #elif V8_OS_WIN
 
-static V8_INLINE(void InitializeNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE void InitializeNativeHandle(PCRITICAL_SECTION cs) {
   InitializeCriticalSection(cs);
 }
 
 
-static V8_INLINE(void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs) {
   InitializeCriticalSection(cs);
 }
 
 
-static V8_INLINE(void DestroyNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE void DestroyNativeHandle(PCRITICAL_SECTION cs) {
   DeleteCriticalSection(cs);
 }
 
 
-static V8_INLINE(void LockNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE void LockNativeHandle(PCRITICAL_SECTION cs) {
   EnterCriticalSection(cs);
 }
 
 
-static V8_INLINE(void UnlockNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE void UnlockNativeHandle(PCRITICAL_SECTION cs) {
   LeaveCriticalSection(cs);
 }
 
 
-static V8_INLINE(bool TryLockNativeHandle(PCRITICAL_SECTION cs)) {
+static V8_INLINE bool TryLockNativeHandle(PCRITICAL_SECTION cs) {
   return TryEnterCriticalSection(cs);
 }
 
diff --git a/src/platform/mutex.h b/src/platform/mutex.h
index f08de4f..0f899ca 100644
--- a/src/platform/mutex.h
+++ b/src/platform/mutex.h
@@ -94,14 +94,14 @@
   int level_;
 #endif
 
-  V8_INLINE(void AssertHeldAndUnmark()) {
+  V8_INLINE void AssertHeldAndUnmark() {
 #ifdef DEBUG
     ASSERT_EQ(1, level_);
     level_--;
 #endif
   }
 
-  V8_INLINE(void AssertUnheldAndMark()) {
+  V8_INLINE void AssertUnheldAndMark() {
 #ifdef DEBUG
     ASSERT_EQ(0, level_);
     level_++;
diff --git a/src/platform/socket.h b/src/platform/socket.h
index e9e2fa2..ff8c1de 100644
--- a/src/platform/socket.h
+++ b/src/platform/socket.h
@@ -66,7 +66,7 @@
   // Set the value of the SO_REUSEADDR socket option.
   bool SetReuseAddress(bool reuse_address);
 
-  V8_INLINE(bool IsValid()) const {
+  V8_INLINE bool IsValid() const {
     return native_handle_ != kInvalidNativeHandle;
   }
 
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 8676d81..95dcc4f 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -149,7 +149,6 @@
       // recompilation race.  This goes away as soon as OSR becomes one-shot.
       return;
     }
-    ASSERT(!function->IsMarkedForInstallingRecompiledCode());
     ASSERT(!function->IsInRecompileQueue());
     function->MarkForConcurrentRecompilation();
   } else {
@@ -227,12 +226,6 @@
 
   if (isolate_->DebuggerHasBreakPoints()) return;
 
-  if (FLAG_concurrent_recompilation) {
-    // Take this as opportunity to process the optimizing compiler thread's
-    // output queue so that it does not unnecessarily keep objects alive.
-    isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
-  }
-
   DisallowHeapAllocation no_gc;
 
   // Run through the JavaScript frames and collect them. If we already
diff --git a/src/runtime.cc b/src/runtime.cc
index 00efa51..c09fb1d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2276,9 +2276,13 @@
   LookupResult lookup(isolate);
   global->LocalLookup(*name, &lookup);
   if (!lookup.IsFound()) {
-    return global->SetLocalPropertyIgnoreAttributes(*name,
-                                                    *value,
-                                                    attributes);
+    HandleScope handle_scope(isolate);
+    Handle<GlobalObject> global(isolate->context()->global_object());
+    RETURN_IF_EMPTY_HANDLE(
+        isolate,
+        JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
+                                                   attributes));
+    return *value;
   }
 
   if (!lookup.IsReadOnly()) {
@@ -2495,41 +2499,41 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   DisallowHeapAllocation no_allocation;
   ASSERT(args.length() == 5);
-  CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
-  CONVERT_ARG_CHECKED(String, source, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   // If source is the empty string we set it to "(?:)" instead as
   // suggested by ECMA-262, 5th, section 15.10.4.1.
-  if (source->length() == 0) source = isolate->heap()->query_colon_string();
+  if (source->length() == 0) source = isolate->factory()->query_colon_string();
 
-  Object* global = args[2];
-  if (!global->IsTrue()) global = isolate->heap()->false_value();
+  CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
+  if (!global->IsTrue()) global = isolate->factory()->false_value();
 
-  Object* ignoreCase = args[3];
-  if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value();
+  CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
+  if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
 
-  Object* multiline = args[4];
-  if (!multiline->IsTrue()) multiline = isolate->heap()->false_value();
+  CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
+  if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
 
   Map* map = regexp->map();
   Object* constructor = map->constructor();
   if (constructor->IsJSFunction() &&
       JSFunction::cast(constructor)->initial_map() == map) {
     // If we still have the original map, set in-object properties directly.
-    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
+    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
     // Both true and false are immovable immortal objects so no need for write
     // barrier.
     regexp->InObjectPropertyAtPut(
-        JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
+        JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
     regexp->InObjectPropertyAtPut(
-        JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
+        JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
     regexp->InObjectPropertyAtPut(
-        JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
+        JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
     regexp->InObjectPropertyAtPut(
         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
-    return regexp;
+    return *regexp;
   }
 
   // Map has changed, so use generic, but slower, method.
@@ -2537,34 +2541,19 @@
       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
   PropertyAttributes writable =
       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
-  Heap* heap = isolate->heap();
-  MaybeObject* result;
-  result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(),
-                                                    source,
-                                                    final);
-  // TODO(jkummerow): Turn these back into ASSERTs when we can be certain
-  // that it never fires in Release mode in the wild.
-  CHECK(!result->IsFailure());
-  result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(),
-                                                    global,
-                                                    final);
-  CHECK(!result->IsFailure());
-  result =
-      regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(),
-                                               ignoreCase,
-                                               final);
-  CHECK(!result->IsFailure());
-  result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(),
-                                                    multiline,
-                                                    final);
-  CHECK(!result->IsFailure());
-  result =
-      regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(),
-                                               Smi::FromInt(0),
-                                               writable);
-  CHECK(!result->IsFailure());
-  USE(result);
-  return regexp;
+  Handle<Object> zero(Smi::FromInt(0), isolate);
+  Factory* factory = isolate->factory();
+  CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+      regexp, factory->source_string(), source, final));
+  CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+      regexp, factory->global_string(), global, final));
+  CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+      regexp, factory->ignore_case_string(), ignoreCase, final));
+  CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+      regexp, factory->multiline_string(), multiline, final));
+  CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+      regexp, factory->last_index_string(), zero, writable));
+  return *regexp;
 }
 
 
@@ -5064,9 +5053,10 @@
     JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
     // Use IgnoreAttributes version since a readonly property may be
     // overridden and SetProperty does not allow this.
-    return js_object->SetLocalPropertyIgnoreAttributes(*name,
-                                                       *obj_value,
-                                                       attr);
+    Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+        js_object, name, obj_value, attr);
+    RETURN_IF_EMPTY_HANDLE(isolate, result);
+    return *result;
   }
 
   return Runtime::ForceSetObjectProperty(isolate,
@@ -5252,7 +5242,10 @@
           index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
     } else {
       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
-      return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
+      Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+          js_object, name, value, attr);
+      RETURN_IF_EMPTY_HANDLE(isolate, result);
+      return *result;
     }
   }
 
@@ -5267,7 +5260,10 @@
     return js_object->SetElement(
         index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
   } else {
-    return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
+    Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+        js_object, name, value, attr);
+    RETURN_IF_EMPTY_HANDLE(isolate, result);
+    return *result;
   }
 }
 
@@ -5470,10 +5466,11 @@
 // Set a local property, even if it is READ_ONLY.  If the property does not
 // exist, it will be added with attributes NONE.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
-  CONVERT_ARG_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   // Compute attributes.
   PropertyAttributes attributes = NONE;
   if (args.length() == 4) {
@@ -5483,9 +5480,10 @@
         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
     attributes = static_cast<PropertyAttributes>(unchecked_value);
   }
-
-  return object->
-      SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
+  Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+      object, name, value, attributes);
+  RETURN_IF_EMPTY_HANDLE(isolate, result);
+  return *result;
 }
 
 
@@ -8346,16 +8344,6 @@
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
-  HandleScope handle_scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  ASSERT(isolate->use_crankshaft() && FLAG_concurrent_recompilation);
-  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
-  return function->code();
-}
-
-
 class ActivationsFinder : public ThreadVisitor {
  public:
   Code* code_;
@@ -8553,8 +8541,7 @@
   }
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   if (FLAG_concurrent_recompilation && sync_with_compiler_thread) {
-    while (function->IsInRecompileQueue() ||
-           function->IsMarkedForInstallingRecompiledCode()) {
+    while (function->IsInRecompileQueue()) {
       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
       OS::Sleep(50);
     }
@@ -9382,7 +9369,6 @@
 
   // First check if this is a real stack overflow.
   if (isolate->stack_guard()->IsStackOverflow()) {
-    SealHandleScope shs(isolate);
     return isolate->StackOverflow();
   }
 
@@ -9390,6 +9376,23 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_TryInstallRecompiledCode) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+  // First check if this is a real stack overflow.
+  if (isolate->stack_guard()->IsStackOverflow()) {
+    SealHandleScope shs(isolate);
+    return isolate->StackOverflow();
+  }
+
+  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+  return (function->IsOptimized()) ? function->code()
+                                   : function->shared()->code();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 0);
diff --git a/src/runtime.h b/src/runtime.h
index bce09a4..60c6677 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -88,7 +88,7 @@
   F(LazyCompile, 1, 1) \
   F(LazyRecompile, 1, 1) \
   F(ConcurrentRecompile, 1, 1) \
-  F(InstallRecompiledCode, 1, 1) \
+  F(TryInstallRecompiledCode, 1, 1) \
   F(NotifyDeoptimized, 1, 1) \
   F(NotifyStubFailure, 0, 1) \
   F(NotifyOSR, 0, 1) \
diff --git a/src/spaces.h b/src/spaces.h
index 1ccdacb..43f44a5 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1085,7 +1085,7 @@
 
   // Returns an indication of whether a pointer is in a space that has
   // been allocated by this MemoryAllocator.
-  V8_INLINE(bool IsOutsideAllocatedSpace(const void* address)) const {
+  V8_INLINE bool IsOutsideAllocatedSpace(const void* address) const {
     return address < lowest_ever_allocated_ ||
         address >= highest_ever_allocated_;
   }
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index bdfb32f..7b23d0c 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -166,68 +166,68 @@
 }
 
 
-Handle<Code> StubCache::ComputeMonomorphicLoadIC(Handle<JSObject> receiver,
+Handle<Code> StubCache::ComputeMonomorphicLoadIC(Handle<HeapObject> receiver,
                                                  Handle<Code> handler,
                                                  Handle<Name> name) {
-  Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type());
+  Handle<Map> map(receiver->map());
+  Handle<Code> ic = FindIC(name, map, Code::LOAD_IC, handler->type());
   if (!ic.is_null()) return ic;
 
   LoadStubCompiler ic_compiler(isolate());
-  ic = ic_compiler.CompileMonomorphicIC(
-      Handle<Map>(receiver->map()), handler, name);
+  ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
 
-  JSObject::UpdateMapCodeCache(receiver, name, ic);
+  HeapObject::UpdateMapCodeCache(receiver, name, ic);
   return ic;
 }
 
 
-Handle<Code> StubCache::ComputeMonomorphicKeyedLoadIC(Handle<JSObject> receiver,
-                                                      Handle<Code> handler,
-                                                      Handle<Name> name) {
-  Handle<Code> ic = FindIC(
-      name, receiver, Code::KEYED_LOAD_IC, handler->type());
+Handle<Code> StubCache::ComputeMonomorphicKeyedLoadIC(
+    Handle<HeapObject> receiver,
+    Handle<Code> handler,
+    Handle<Name> name) {
+  Handle<Map> map(receiver->map());
+  Handle<Code> ic = FindIC(name, map, Code::KEYED_LOAD_IC, handler->type());
   if (!ic.is_null()) return ic;
 
   KeyedLoadStubCompiler ic_compiler(isolate());
-  ic = ic_compiler.CompileMonomorphicIC(
-      Handle<Map>(receiver->map()), handler, name);
+  ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
 
-  JSObject::UpdateMapCodeCache(receiver, name, ic);
+  HeapObject::UpdateMapCodeCache(receiver, name, ic);
   return ic;
 }
 
 
-Handle<Code> StubCache::ComputeMonomorphicStoreIC(Handle<JSObject> receiver,
+Handle<Code> StubCache::ComputeMonomorphicStoreIC(Handle<HeapObject> receiver,
                                                   Handle<Code> handler,
                                                   Handle<Name> name,
                                                   StrictModeFlag strict_mode) {
+  Handle<Map> map(receiver->map());
   Handle<Code> ic = FindIC(
-      name, receiver, Code::STORE_IC, handler->type(), strict_mode);
+      name, map, Code::STORE_IC, handler->type(), strict_mode);
   if (!ic.is_null()) return ic;
 
   StoreStubCompiler ic_compiler(isolate(), strict_mode);
-  ic = ic_compiler.CompileMonomorphicIC(
-      Handle<Map>(receiver->map()), handler, name);
+  ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
 
-  JSObject::UpdateMapCodeCache(receiver, name, ic);
+  HeapObject::UpdateMapCodeCache(receiver, name, ic);
   return ic;
 }
 
 
 Handle<Code> StubCache::ComputeMonomorphicKeyedStoreIC(
-    Handle<JSObject> receiver,
+    Handle<HeapObject> receiver,
     Handle<Code> handler,
     Handle<Name> name,
     StrictModeFlag strict_mode) {
+  Handle<Map> map(receiver->map());
   Handle<Code> ic = FindIC(
-      name, receiver, Code::KEYED_STORE_IC, handler->type(), strict_mode);
+      name, map, Code::KEYED_STORE_IC, handler->type(), strict_mode);
   if (!ic.is_null()) return ic;
 
   KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE);
-  ic = ic_compiler.CompileMonomorphicIC(
-      Handle<Map>(receiver->map()), handler, name);
+  ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
 
-  JSObject::UpdateMapCodeCache(receiver, name, ic);
+  HeapObject::UpdateMapCodeCache(receiver, name, ic);
   return ic;
 }
 
@@ -264,7 +264,7 @@
   LoadStubCompiler compiler(isolate_);
   handler =
       compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
-  JSObject::UpdateMapCodeCache(receiver, cache_name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, cache_name, handler);
   return handler;
 }
 
@@ -289,7 +289,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadField(receiver, holder, name, field, representation);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -308,7 +308,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadCallback(receiver, holder, name, callback);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -326,7 +326,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -343,7 +343,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadViaGetter(receiver, holder, name, getter);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -359,7 +359,7 @@
 
   LoadStubCompiler compiler(isolate_);
   handler = compiler.CompileLoadConstant(receiver, holder, name, value);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
 
   return handler;
 }
@@ -376,7 +376,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
         compiler.CompileLoadInterceptor(receiver, holder, name);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -399,7 +399,7 @@
   LoadStubCompiler compiler(isolate_);
   Handle<Code> ic =
       compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
-  JSObject::UpdateMapCodeCache(stub_holder, name, ic);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, ic);
   return ic;
 }
 
@@ -425,7 +425,7 @@
   KeyedLoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadField(receiver, holder, name, field, representation);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -442,7 +442,7 @@
 
   KeyedLoadStubCompiler compiler(isolate_);
   handler = compiler.CompileLoadConstant(receiver, holder, name, value);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -458,7 +458,7 @@
   KeyedLoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadInterceptor(receiver, holder, name);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -476,7 +476,7 @@
   KeyedLoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadCallback(receiver, holder, name, callback);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -494,7 +494,7 @@
   KeyedLoadStubCompiler compiler(isolate_);
   Handle<Code> handler =
       compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
-  JSObject::UpdateMapCodeCache(stub_holder, name, handler);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, handler);
   return handler;
 }
 
@@ -509,7 +509,7 @@
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -526,7 +526,7 @@
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler =
       compiler.CompileStoreTransition(receiver, lookup, transition, name);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -606,7 +606,7 @@
   Handle<Map> cell_map(isolate_->heap()->global_property_cell_map());
   code->ReplaceNthObject(1, *cell_map, *cell);
 
-  JSObject::UpdateMapCodeCache(receiver, name, code);
+  HeapObject::UpdateMapCodeCache(receiver, name, code);
 
   return code;
 }
@@ -626,7 +626,7 @@
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler = compiler.CompileStoreCallback(
       receiver, holder, name, callback);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -644,7 +644,7 @@
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler = compiler.CompileStoreCallback(
       receiver, holder, name, call_optimization);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -661,7 +661,7 @@
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler = compiler.CompileStoreViaSetter(
       receiver, holder, name, setter);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -675,7 +675,7 @@
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> handler = compiler.CompileStoreInterceptor(receiver, name);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -690,7 +690,7 @@
 
   KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
   Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -708,7 +708,7 @@
   KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
   Handle<Code> handler =
       compiler.CompileStoreTransition(receiver, lookup, transition, name);
-  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  HeapObject::UpdateMapCodeCache(receiver, name, handler);
   return handler;
 }
 
@@ -765,7 +765,7 @@
   GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
 
   if (CallStubCompiler::CanBeCached(function)) {
-    JSObject::UpdateMapCodeCache(stub_holder, name, code);
+    HeapObject::UpdateMapCodeCache(stub_holder, name, code);
   }
   return code;
 }
@@ -806,7 +806,7 @@
   PROFILE(isolate_,
           CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
   GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
-  JSObject::UpdateMapCodeCache(stub_holder, name, code);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, code);
   return code;
 }
 
@@ -845,7 +845,7 @@
   PROFILE(isolate(),
           CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
   GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
-  JSObject::UpdateMapCodeCache(stub_holder, name, code);
+  HeapObject::UpdateMapCodeCache(stub_holder, name, code);
   return code;
 }
 
@@ -876,7 +876,7 @@
           CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
   GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
   if (CallStubCompiler::CanBeCached(function)) {
-    JSObject::UpdateMapCodeCache(stub_holder, name, code);
+    HeapObject::UpdateMapCodeCache(stub_holder, name, code);
   }
   return code;
 }
@@ -1249,9 +1249,6 @@
 }
 
 
-static const int kAccessorInfoOffsetInInterceptorArgs = 2;
-
-
 /**
  * Attempts to load a property with an interceptor (which must be present),
  * but doesn't search the prototype chain.
@@ -1260,13 +1257,11 @@
  * provide any value for the given name.
  */
 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
-  typedef PropertyCallbackArguments PCA;
-  static const int kArgsOffset = kAccessorInfoOffsetInInterceptorArgs;
-  Handle<Name> name_handle = args.at<Name>(0);
-  Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
-  ASSERT(kArgsOffset == 2);
-  // No ReturnValue in interceptors.
-  ASSERT_EQ(kArgsOffset + PCA::kArgsLength - 2, args.length());
+  ASSERT(args.length() == StubCache::kInterceptorArgsLength);
+  Handle<Name> name_handle =
+      args.at<Name>(StubCache::kInterceptorArgsNameIndex);
+  Handle<InterceptorInfo> interceptor_info =
+      args.at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex);
 
   // TODO(rossberg): Support symbols in the API.
   if (name_handle->IsSymbol())
@@ -1279,13 +1274,11 @@
   ASSERT(getter != NULL);
 
   Handle<JSObject> receiver =
-      args.at<JSObject>(kArgsOffset - PCA::kThisIndex);
+      args.at<JSObject>(StubCache::kInterceptorArgsThisIndex);
   Handle<JSObject> holder =
-      args.at<JSObject>(kArgsOffset - PCA::kHolderIndex);
-  PropertyCallbackArguments callback_args(isolate,
-                                          interceptor_info->data(),
-                                          *receiver,
-                                          *holder);
+      args.at<JSObject>(StubCache::kInterceptorArgsHolderIndex);
+  PropertyCallbackArguments callback_args(
+      isolate, interceptor_info->data(), *receiver, *holder);
   {
     // Use the interceptor getter.
     HandleScope scope(isolate);
@@ -1323,17 +1316,15 @@
 
 static MaybeObject* LoadWithInterceptor(Arguments* args,
                                         PropertyAttributes* attrs) {
-  typedef PropertyCallbackArguments PCA;
-  static const int kArgsOffset = kAccessorInfoOffsetInInterceptorArgs;
-  Handle<Name> name_handle = args->at<Name>(0);
-  Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
-  ASSERT(kArgsOffset == 2);
-  // No ReturnValue in interceptors.
-  ASSERT_EQ(kArgsOffset + PCA::kArgsLength - 2, args->length());
+  ASSERT(args->length() == StubCache::kInterceptorArgsLength);
+  Handle<Name> name_handle =
+      args->at<Name>(StubCache::kInterceptorArgsNameIndex);
+  Handle<InterceptorInfo> interceptor_info =
+      args->at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex);
   Handle<JSObject> receiver_handle =
-      args->at<JSObject>(kArgsOffset - PCA::kThisIndex);
+      args->at<JSObject>(StubCache::kInterceptorArgsThisIndex);
   Handle<JSObject> holder_handle =
-      args->at<JSObject>(kArgsOffset - PCA::kHolderIndex);
+      args->at<JSObject>(StubCache::kInterceptorArgsHolderIndex);
 
   Isolate* isolate = receiver_handle->GetIsolate();
 
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 141e567..63cb42b 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -104,20 +104,20 @@
                                 Code::StubType type,
                                 StrictModeFlag strict_mode);
 
-  Handle<Code> ComputeMonomorphicLoadIC(Handle<JSObject> receiver,
+  Handle<Code> ComputeMonomorphicLoadIC(Handle<HeapObject> receiver,
                                         Handle<Code> handler,
                                         Handle<Name> name);
 
-  Handle<Code> ComputeMonomorphicKeyedLoadIC(Handle<JSObject> receiver,
+  Handle<Code> ComputeMonomorphicKeyedLoadIC(Handle<HeapObject> receiver,
                                              Handle<Code> handler,
                                              Handle<Name> name);
 
-  Handle<Code> ComputeMonomorphicStoreIC(Handle<JSObject> receiver,
+  Handle<Code> ComputeMonomorphicStoreIC(Handle<HeapObject> receiver,
                                          Handle<Code> handler,
                                          Handle<Name> name,
                                          StrictModeFlag strict_mode);
 
-  Handle<Code> ComputeMonomorphicKeyedStoreIC(Handle<JSObject> receiver,
+  Handle<Code> ComputeMonomorphicKeyedStoreIC(Handle<HeapObject> receiver,
                                               Handle<Code> handler,
                                               Handle<Name> name,
                                               StrictModeFlag strict_mode);
@@ -408,6 +408,16 @@
   Heap* heap() { return isolate()->heap(); }
   Factory* factory() { return isolate()->factory(); }
 
+  // These constants describe the structure of the interceptor arguments on the
+  // stack. The arguments are pushed by the (platform-specific)
+  // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
+  // LoadWithInterceptor.
+  static const int kInterceptorArgsNameIndex = 0;
+  static const int kInterceptorArgsInfoIndex = 1;
+  static const int kInterceptorArgsThisIndex = 2;
+  static const int kInterceptorArgsHolderIndex = 3;
+  static const int kInterceptorArgsLength = 4;
+
  private:
   explicit StubCache(Isolate* isolate);
 
diff --git a/src/unique.h b/src/unique.h
new file mode 100644
index 0000000..7ae704a
--- /dev/null
+++ b/src/unique.h
@@ -0,0 +1,266 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_HYDROGEN_UNIQUE_H_
+#define V8_HYDROGEN_UNIQUE_H_
+
+#include "handles.h"
+#include "utils.h"
+#include "zone.h"
+
+namespace v8 {
+namespace internal {
+
+
+template <typename T>
+class UniqueSet;
+
+
+// Represents a handle to an object on the heap, but with the additional
+// ability of checking for equality and hashing without accessing the heap.
+//
+// Creating a Unique<T> requires first dereferencing the handle to obtain
+// the address of the object, which is used as the hashcode and the basis for
+// comparison. The object can be moved later by the GC, but comparison
+// and hashing use the old address of the object, without dereferencing it.
+//
+// Careful! Comparison of two Uniques is only correct if both were created
+// in the same "era" of GC or if at least one is a non-movable object.
+template <typename T>
+class Unique V8_FINAL {
+ public:
+  // TODO(titzer): make private and introduce some builder/owner class.
+  explicit Unique(Handle<T> handle) {
+    if (handle.is_null()) {
+      raw_address_ = NULL;
+    } else {
+      raw_address_ = reinterpret_cast<Address>(*handle);
+      ASSERT_NE(raw_address_, NULL);
+    }
+    handle_ = handle;
+  }
+
+  // Constructor for handling automatic up casting.
+  // Ex. Unique<JSFunction> can be passed when Unique<Object> is expected.
+  template <class S> Unique(Unique<S> uniq) {
+#ifdef DEBUG
+    T* a = NULL;
+    S* b = NULL;
+    a = b;  // Fake assignment to enforce type checks.
+    USE(a);
+#endif
+    raw_address_ = uniq.raw_address_;
+    handle_ = uniq.handle_;  // Creates a new handle sharing the same location.
+  }
+
+  template <typename U>
+  bool operator==(const Unique<U>& other) const {
+    return raw_address_ == other.raw_address_;
+  }
+
+  template <typename U>
+  bool operator!=(const Unique<U>& other) const {
+    return raw_address_ != other.raw_address_;
+  }
+
+  intptr_t Hashcode() const {
+    return reinterpret_cast<intptr_t>(raw_address_);
+  }
+
+  bool IsNull() {
+    return raw_address_ == NULL;
+  }
+
+  // Don't do this unless you have access to the heap!
+  // No, seriously! You can compare and hash and set-ify uniques that were
+  // all created at the same time; please don't dereference.
+  Handle<T> handle() {
+    return handle_;
+  }
+
+  friend class UniqueSet<T>;  // Uses internal details for speed.
+  template <class U>
+  friend class Unique;  // For comparing raw_address values.
+
+ private:
+  Address raw_address_;
+  Handle<T> handle_;
+};
+
+
+template <typename T>
+class UniqueSet V8_FINAL : public ZoneObject {
+ public:
+  // Constructor. A new set will be empty.
+  UniqueSet() : size_(0), capacity_(0), array_(NULL) { }
+
+  // Add a new element to this unique set. Mutates this set. O(|this|).
+  void Add(Unique<T> uniq, Zone* zone) {
+    // Keep the set sorted by the {raw_address} of the unique elements.
+    for (int i = 0; i < size_; i++) {
+      if (array_[i] == uniq) return;
+      if (array_[i].raw_address_ > uniq.raw_address_) {
+        // Insert in the middle.
+        Grow(size_ + 1, zone);
+        for (int j = size_ - 1; j >= i; j--) array_[j + 1] = array_[j];
+        array_[i] = uniq;
+        size_++;
+        return;
+      }
+    }
+    // Append the element to the the end.
+    Grow(size_ + 1, zone);
+    array_[size_++] = uniq;
+  }
+
+  // Compare this set against another set. O(|this|).
+  bool Equals(UniqueSet<T>* that) {
+    if (that->size_ != this->size_) return false;
+    for (int i = 0; i < this->size_; i++) {
+      if (this->array_[i] != that->array_[i]) return false;
+    }
+    return true;
+  }
+
+  // Check if this set is a subset of the given set. O(|this| + |that|).
+  bool IsSubset(UniqueSet<T>* that) {
+    if (that->size_ < this->size_) return false;
+    int j = 0;
+    for (int i = 0; i < this->size_; i++) {
+      Unique<T> sought = this->array_[i];
+      while (true) {
+        if (sought == that->array_[j++]) break;
+        // Fail whenever there are more elements in {this} than {that}.
+        if ((this->size_ - i) > (that->size_ - j)) return false;
+      }
+    }
+    return true;
+  }
+
+  // Returns a new set representing the intersection of this set and the other.
+  // O(|this| + |that|).
+  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) {
+    if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>();
+
+    UniqueSet<T>* out = new(zone) UniqueSet<T>();
+    out->Grow(Min(this->size_, that->size_), zone);
+
+    int i = 0, j = 0, k = 0;
+    while (i < this->size_ && j < that->size_) {
+      Unique<T> a = this->array_[i];
+      Unique<T> b = that->array_[j];
+      if (a == b) {
+        out->array_[k++] = a;
+        i++;
+        j++;
+      } else if (a.raw_address_ < b.raw_address_) {
+        i++;
+      } else {
+        j++;
+      }
+    }
+
+    out->size_ = k;
+    return out;
+  }
+
+  // Returns a new set representing the union of this set and the other.
+  // O(|this| + |that|).
+  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) {
+    if (that->size_ == 0) return this->Copy(zone);
+    if (this->size_ == 0) return that->Copy(zone);
+
+    UniqueSet<T>* out = new(zone) UniqueSet<T>();
+    out->Grow(this->size_ + that->size_, zone);
+
+    int i = 0, j = 0, k = 0;
+    while (i < this->size_ && j < that->size_) {
+      Unique<T> a = this->array_[i];
+      Unique<T> b = that->array_[j];
+      if (a == b) {
+        out->array_[k++] = a;
+        i++;
+        j++;
+      } else if (a.raw_address_ < b.raw_address_) {
+        out->array_[k++] = a;
+        i++;
+      } else {
+        out->array_[k++] = b;
+        j++;
+      }
+    }
+
+    while (i < this->size_) out->array_[k++] = this->array_[i++];
+    while (j < that->size_) out->array_[k++] = that->array_[j++];
+
+    out->size_ = k;
+    return out;
+  }
+
+  // Makes an exact copy of this set. O(|this| + |that|).
+  UniqueSet<T>* Copy(Zone* zone) {
+    UniqueSet<T>* copy = new(zone) UniqueSet<T>();
+    copy->size_ = this->size_;
+    copy->capacity_ = this->size_;
+    copy->array_ = zone->NewArray<Unique<T> >(this->size_);
+    memcpy(copy->array_, this->array_, this->size_ * sizeof(Unique<T>));
+    return copy;
+  }
+
+  inline int size() {
+    return size_;
+  }
+
+ private:
+  // These sets should be small, since operations are implemented with simple
+  // linear algorithms. Enforce a maximum size.
+  static const int kMaxCapacity = 65535;
+
+  uint16_t size_;
+  uint16_t capacity_;
+  Unique<T>* array_;
+
+  // Grow the size of internal storage to be at least {size} elements.
+  void Grow(int size, Zone* zone) {
+    CHECK(size < kMaxCapacity);  // Enforce maximum size.
+    if (capacity_ < size) {
+      int new_capacity = 2 * capacity_ + size;
+      if (new_capacity > kMaxCapacity) new_capacity = kMaxCapacity;
+      Unique<T>* new_array = zone->NewArray<Unique<T> >(new_capacity);
+      if (size_ > 0) {
+        memcpy(new_array, array_, size_ * sizeof(Unique<T>));
+      }
+      capacity_ = new_capacity;
+      array_ = new_array;
+    }
+  }
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_HYDROGEN_UNIQUE_H_
diff --git a/src/utils/random-number-generator.h b/src/utils/random-number-generator.h
index fc14ef4..bd7dca7 100644
--- a/src/utils/random-number-generator.h
+++ b/src/utils/random-number-generator.h
@@ -59,7 +59,7 @@
   // that one int value is pseudorandomly generated and returned.
   // All 2^32 possible integer values are produced with (approximately) equal
   // probability.
-  V8_INLINE(int NextInt()) V8_WARN_UNUSED_RESULT {
+  V8_INLINE int NextInt() V8_WARN_UNUSED_RESULT {
     return Next(32);
   }
 
@@ -76,7 +76,7 @@
   // |NextBoolean()| is that one boolean value is pseudorandomly generated and
   // returned. The values true and false are produced with (approximately) equal
   // probability.
-  V8_INLINE(bool NextBool()) V8_WARN_UNUSED_RESULT {
+  V8_INLINE bool NextBool() V8_WARN_UNUSED_RESULT {
     return Next(1) != 0;
   }
 
diff --git a/src/version.cc b/src/version.cc
index a491a4f..da82885 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     21
-#define BUILD_NUMBER      14
+#define BUILD_NUMBER      15
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 1960c3c..81721c2 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -73,6 +73,24 @@
 }
 
 
+static void CallRuntimePassFunction(MacroAssembler* masm,
+                                    Runtime::FunctionId function_id) {
+  FrameScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function onto the stack.
+  __ push(rdi);
+  // Push call kind information.
+  __ push(rcx);
+  // Function is also the parameter to the runtime call.
+  __ push(rdi);
+
+  __ CallRuntime(function_id, 1);
+  // Restore call kind information.
+  __ pop(rcx);
+  // Restore receiver.
+  __ pop(rdi);
+}
+
+
 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
   __ movq(kScratchRegister,
           FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
@@ -84,57 +102,27 @@
 
 
 void Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
+  // Checking whether the queued function is ready for install is optional,
+  // since we come across interrupts and stack checks elsewhere.  However,
+  // not checking may delay installing ready functions, and always checking
+  // would be quite expensive.  A good compromise is to first check against
+  // stack limit as a cue for an interrupt signal.
+  Label ok;
+  __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
+  __ j(above_equal, &ok);
+
+  CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode);
+  // Tail call to returned code.
+  __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
+  __ jmp(rax);
+
+  __ bind(&ok);
   GenerateTailCallToSharedCode(masm);
 }
 
 
-void Builtins::Generate_InstallRecompiledCode(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(rdi);
-    // Push call kind information.
-    __ push(rcx);
-
-    __ push(rdi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kInstallRecompiledCode, 1);
-
-    // Restore call kind information.
-    __ pop(rcx);
-    // Restore function.
-    __ pop(rdi);
-
-    // Tear down internal frame.
-  }
-
-  // Do a tail-call of the compiled function.
-  __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
-  __ jmp(rax);
-}
-
-
 void Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(rdi);
-    // Push call kind information.
-    __ push(rcx);
-
-    __ push(rdi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kConcurrentRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(rcx);
-    // Restore receiver.
-    __ pop(rdi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile);
   GenerateTailCallToSharedCode(masm);
 }
 
@@ -586,26 +574,7 @@
 
 
 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(rdi);
-    // Push call kind information.
-    __ push(rcx);
-
-    __ push(rdi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kLazyCompile, 1);
-
-    // Restore call kind information.
-    __ pop(rcx);
-    // Restore receiver.
-    __ pop(rdi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyCompile);
   // Do a tail-call of the compiled function.
   __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
   __ jmp(rax);
@@ -613,26 +582,7 @@
 
 
 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Push a copy of the function onto the stack.
-    __ push(rdi);
-    // Push call kind information.
-    __ push(rcx);
-
-    __ push(rdi);  // Function is also the parameter to the runtime call.
-    __ CallRuntime(Runtime::kLazyRecompile, 1);
-
-    // Restore call kind information.
-    __ pop(rcx);
-    // Restore function.
-    __ pop(rdi);
-
-    // Tear down internal frame.
-  }
-
+  CallRuntimePassFunction(masm, Runtime::kLazyRecompile);
   // Do a tail-call of the compiled function.
   __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
   __ jmp(rax);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index f6cfb4f..51e1a53 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -4644,7 +4644,6 @@
   __ j(below, &done);
 
   // Check the number to string cache.
-  Label not_cached;
   __ bind(&not_string);
   // Puts the cached result into scratch1.
   NumberToStringStub::GenerateLookupNumberStringCache(masm,
@@ -4652,22 +4651,9 @@
                                                       scratch1,
                                                       scratch2,
                                                       scratch3,
-                                                      &not_cached);
+                                                      slow);
   __ movq(arg, scratch1);
   __ movq(Operand(rsp, stack_offset), arg);
-  __ jmp(&done);
-
-  // Check if the argument is a safe string wrapper.
-  __ bind(&not_cached);
-  __ JumpIfSmi(arg, slow);
-  __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1);  // map -> scratch1.
-  __ j(not_equal, slow);
-  __ testb(FieldOperand(scratch1, Map::kBitField2Offset),
-           Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
-  __ j(zero, slow);
-  __ movq(arg, FieldOperand(arg, JSValue::kValueOffset));
-  __ movq(Operand(rsp, stack_offset), arg);
-
   __ bind(&done);
 }
 
@@ -6326,46 +6312,59 @@
 
 
 template<class T>
-static void CreateArrayDispatch(MacroAssembler* masm) {
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmpl(rdx, Immediate(kind));
-    __ j(not_equal, &next);
-    T stub(kind);
+static void CreateArrayDispatch(MacroAssembler* masm,
+                                AllocationSiteOverrideMode mode) {
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    T stub(GetInitialFastElementsKind(),
+           CONTEXT_CHECK_REQUIRED,
+           mode);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmpl(rdx, Immediate(kind));
+      __ j(not_equal, &next);
+      T stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
-static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
-  // rbx - type info cell
-  // rdx - kind
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
+                                           AllocationSiteOverrideMode mode) {
+  // rbx - type info cell (if mode != DISABLE_ALLOCATION_SITES)
+  // rdx - kind (if mode != DISABLE_ALLOCATION_SITES)
   // rax - number of arguments
   // rdi - constructor?
   // rsp[0] - return address
   // rsp[8] - last argument
-  ASSERT(FAST_SMI_ELEMENTS == 0);
-  ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
-  ASSERT(FAST_ELEMENTS == 2);
-  ASSERT(FAST_HOLEY_ELEMENTS == 3);
-  ASSERT(FAST_DOUBLE_ELEMENTS == 4);
-  ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
-
   Handle<Object> undefined_sentinel(
       masm->isolate()->heap()->undefined_value(),
       masm->isolate());
 
-  // is the low bit set? If so, we are holey and that is good.
-  __ testb(rdx, Immediate(1));
   Label normal_sequence;
-  __ j(not_zero, &normal_sequence);
+  if (mode == DONT_OVERRIDE) {
+    ASSERT(FAST_SMI_ELEMENTS == 0);
+    ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+    ASSERT(FAST_ELEMENTS == 2);
+    ASSERT(FAST_HOLEY_ELEMENTS == 3);
+    ASSERT(FAST_DOUBLE_ELEMENTS == 4);
+    ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
+
+    // is the low bit set? If so, we are holey and that is good.
+    __ testb(rdx, Immediate(1));
+    __ j(not_zero, &normal_sequence);
+  }
 
   // look at the first argument
   StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
@@ -6373,50 +6372,73 @@
   __ testq(rcx, rcx);
   __ j(zero, &normal_sequence);
 
-  // We are going to create a holey array, but our kind is non-holey.
-  // Fix kind and retry (only if we have an allocation site in the cell).
-  __ incl(rdx);
-  __ Cmp(rbx, undefined_sentinel);
-  __ j(equal, &normal_sequence);
-  __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
-  Handle<Map> allocation_site_map(
-      masm->isolate()->heap()->allocation_site_map(),
-      masm->isolate());
-  __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
-  __ j(not_equal, &normal_sequence);
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    ElementsKind initial = GetInitialFastElementsKind();
+    ElementsKind holey_initial = GetHoleyElementsKind(initial);
 
-  // Save the resulting elements kind in type info
-  __ Integer32ToSmi(rdx, rdx);
-  __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx);
-  __ SmiToInteger32(rdx, rdx);
+    ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+                                                  CONTEXT_CHECK_REQUIRED,
+                                                  DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub_holey);
 
-  __ bind(&normal_sequence);
-  int last_index = GetSequenceIndexFromFastElementsKind(
-      TERMINAL_FAST_ELEMENTS_KIND);
-  for (int i = 0; i <= last_index; ++i) {
-    Label next;
-    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    __ cmpl(rdx, Immediate(kind));
-    __ j(not_equal, &next);
-    ArraySingleArgumentConstructorStub stub(kind);
+    __ bind(&normal_sequence);
+    ArraySingleArgumentConstructorStub stub(initial,
+                                            CONTEXT_CHECK_REQUIRED,
+                                            DISABLE_ALLOCATION_SITES);
     __ TailCallStub(&stub);
-    __ bind(&next);
-  }
+  } else if (mode == DONT_OVERRIDE) {
+    // We are going to create a holey array, but our kind is non-holey.
+    // Fix kind and retry (only if we have an allocation site in the cell).
+    __ incl(rdx);
+    __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
+    if (FLAG_debug_code) {
+      Handle<Map> allocation_site_map(
+          masm->isolate()->heap()->allocation_site_map(),
+          masm->isolate());
+      __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
+      __ Assert(equal, kExpectedAllocationSiteInCell);
+    }
 
-  // If we reached this point there is a problem.
-  __ Abort(kUnexpectedElementsKindInArrayConstructor);
+    // Save the resulting elements kind in type info
+    __ Integer32ToSmi(rdx, rdx);
+    __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx);
+    __ SmiToInteger32(rdx, rdx);
+
+    __ bind(&normal_sequence);
+    int last_index = GetSequenceIndexFromFastElementsKind(
+        TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      Label next;
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ cmpl(rdx, Immediate(kind));
+      __ j(not_equal, &next);
+      ArraySingleArgumentConstructorStub stub(kind);
+      __ TailCallStub(&stub);
+      __ bind(&next);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
 template<class T>
 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
+  ElementsKind initial_kind = GetInitialFastElementsKind();
+  ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
+
   int to_index = GetSequenceIndexFromFastElementsKind(
       TERMINAL_FAST_ELEMENTS_KIND);
   for (int i = 0; i <= to_index; ++i) {
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
-    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
+        (!FLAG_track_allocation_sites &&
+         (kind == initial_kind || kind == initial_holey_kind))) {
       T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
       stub1.GetCode(isolate)->set_is_pregenerated(true);
     }
@@ -6449,6 +6471,34 @@
 }
 
 
+void ArrayConstructorStub::GenerateDispatchToArrayStub(
+    MacroAssembler* masm,
+    AllocationSiteOverrideMode mode) {
+  if (argument_count_ == ANY) {
+    Label not_zero_case, not_one_case;
+    __ testq(rax, rax);
+    __ j(not_zero, &not_zero_case);
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+
+    __ bind(&not_zero_case);
+    __ cmpl(rax, Immediate(1));
+    __ j(greater, &not_one_case);
+    CreateArrayDispatchOneArgument(masm, mode);
+
+    __ bind(&not_one_case);
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else if (argument_count_ == NONE) {
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+  } else if (argument_count_ == ONE) {
+    CreateArrayDispatchOneArgument(masm, mode);
+  } else if (argument_count_ == MORE_THAN_ONE) {
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : argc
@@ -6484,50 +6534,22 @@
     __ bind(&okay_here);
   }
 
-  Label no_info, switch_ready;
-  // Get the elements kind and case on that.
+  Label no_info;
+  // If the type cell is undefined, or contains anything other than an
+  // AllocationSite, call an array constructor that doesn't use AllocationSites.
   __ Cmp(rbx, undefined_sentinel);
   __ j(equal, &no_info);
   __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset));
-
-  // The type cell may have undefined in its value.
-  __ Cmp(rdx, undefined_sentinel);
-  __ j(equal, &no_info);
-
-  // The type cell has either an AllocationSite or a JSFunction
   __ Cmp(FieldOperand(rdx, 0),
          Handle<Map>(masm->isolate()->heap()->allocation_site_map()));
   __ j(not_equal, &no_info);
 
   __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset));
   __ SmiToInteger32(rdx, rdx);
-  __ jmp(&switch_ready);
+  GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
+
   __ bind(&no_info);
-  __ movq(rdx, Immediate(GetInitialFastElementsKind()));
-  __ bind(&switch_ready);
-
-  if (argument_count_ == ANY) {
-    Label not_zero_case, not_one_case;
-    __ testq(rax, rax);
-    __ j(not_zero, &not_zero_case);
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-
-    __ bind(&not_zero_case);
-    __ cmpl(rax, Immediate(1));
-    __ j(greater, &not_one_case);
-    CreateArrayDispatchOneArgument(masm);
-
-    __ bind(&not_one_case);
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else if (argument_count_ == NONE) {
-    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
-  } else if (argument_count_ == ONE) {
-    CreateArrayDispatchOneArgument(masm);
-  } else if (argument_count_ == MORE_THAN_ONE) {
-    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
-  } else {
-    UNREACHABLE();
-  }
+  GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
 }
 
 
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index c182dd0..c24512e 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2935,7 +2935,7 @@
 
   VisitForAccumulatorValue(args->at(0));
 
-  Label materialize_true, materialize_false;
+  Label materialize_true, materialize_false, skip_lookup;
   Label* if_true = NULL;
   Label* if_false = NULL;
   Label* fall_through = NULL;
@@ -2949,7 +2949,7 @@
   __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
   __ testb(FieldOperand(rbx, Map::kBitField2Offset),
            Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
-  __ j(not_zero, if_true);
+  __ j(not_zero, &skip_lookup);
 
   // Check for fast case object. Generate false result for slow case object.
   __ movq(rcx, FieldOperand(rax, JSObject::kPropertiesOffset));
@@ -2967,7 +2967,7 @@
   __ cmpq(rcx, Immediate(0));
   __ j(equal, &done);
 
-  __ LoadInstanceDescriptors(rbx, rbx);
+  __ LoadInstanceDescriptors(rbx, r8);
   // rbx: descriptor array.
   // rcx: valid entries in the descriptor array.
   // Calculate the end of the descriptor array.
@@ -2975,24 +2975,28 @@
   SmiIndex index = masm_->SmiToIndex(rdx, rcx, kPointerSizeLog2);
   __ lea(rcx,
          Operand(
-             rbx, index.reg, index.scale, DescriptorArray::kFirstOffset));
+             r8, index.reg, index.scale, DescriptorArray::kFirstOffset));
   // Calculate location of the first key name.
-  __ addq(rbx, Immediate(DescriptorArray::kFirstOffset));
+  __ addq(r8, Immediate(DescriptorArray::kFirstOffset));
   // Loop through all the keys in the descriptor array. If one of these is the
   // internalized string "valueOf" the result is false.
   __ jmp(&entry);
   __ bind(&loop);
-  __ movq(rdx, FieldOperand(rbx, 0));
+  __ movq(rdx, FieldOperand(r8, 0));
   __ Cmp(rdx, isolate()->factory()->value_of_string());
   __ j(equal, if_false);
-  __ addq(rbx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
+  __ addq(r8, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
   __ bind(&entry);
-  __ cmpq(rbx, rcx);
+  __ cmpq(r8, rcx);
   __ j(not_equal, &loop);
 
   __ bind(&done);
-  // Reload map as register rbx was used as temporary above.
-  __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
+
+  // Set the bit in the map to indicate that there is no local valueOf field.
+  __ or_(FieldOperand(rbx, Map::kBitField2Offset),
+         Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
+
+  __ bind(&skip_lookup);
 
   // If a valueOf property is not found on the object check that its
   // prototype is the un-modified String prototype. If not result is false.
@@ -3004,10 +3008,9 @@
   __ movq(rdx, FieldOperand(rdx, GlobalObject::kNativeContextOffset));
   __ cmpq(rcx,
           ContextOperand(rdx, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
-  __ j(not_equal, if_false);
-  __ jmp(if_true);
-
   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(equal, if_true, if_false, fall_through);
+
   context()->Plug(if_true, if_false);
 }
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 836abe8..9dca6b3 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3667,90 +3667,64 @@
 
 
 void LCodeGen::DoRandom(LRandom* instr) {
-  class DeferredDoRandom V8_FINAL : public LDeferredCode {
-   public:
-    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
-    virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
-   private:
-    LRandom* instr_;
-  };
-
-  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
-
-  // Having marked this instruction as a call we can use any
-  // registers.
-  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
-
-  // Choose the right register for the first argument depending on
-  // calling convention.
-#ifdef _WIN64
-  ASSERT(ToRegister(instr->global_object()).is(rcx));
-  Register global_object = rcx;
-#else
-  ASSERT(ToRegister(instr->global_object()).is(rdi));
-  Register global_object = rdi;
-#endif
-
+  // Assert that register size is twice the size of each seed.
   static const int kSeedSize = sizeof(uint32_t);
   STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
 
-  __ movq(global_object,
-          FieldOperand(global_object, GlobalObject::kNativeContextOffset));
+  // Load native context
+  Register global_object = ToRegister(instr->global_object());
+  Register native_context = global_object;
+  __ movq(native_context, FieldOperand(
+          global_object, GlobalObject::kNativeContextOffset));
+
+  // Load state (FixedArray of the native context's random seeds)
   static const int kRandomSeedOffset =
       FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
-  __ movq(rbx, FieldOperand(global_object, kRandomSeedOffset));
-  // rbx: FixedArray of the native context's random seeds
+  Register state = native_context;
+  __ movq(state, FieldOperand(native_context, kRandomSeedOffset));
 
   // Load state[0].
-  __ movl(rax, FieldOperand(rbx, ByteArray::kHeaderSize));
-  // If state[0] == 0, call runtime to initialize seeds.
-  __ testl(rax, rax);
-  __ j(zero, deferred->entry());
+  Register state0 = ToRegister(instr->scratch());
+  __ movl(state0, FieldOperand(state, ByteArray::kHeaderSize));
   // Load state[1].
-  __ movl(rcx, FieldOperand(rbx, ByteArray::kHeaderSize + kSeedSize));
+  Register state1 = ToRegister(instr->scratch2());
+  __ movl(state1, FieldOperand(state, ByteArray::kHeaderSize + kSeedSize));
 
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
-  // Only operate on the lower 32 bit of rax.
-  __ movzxwl(rdx, rax);
-  __ imull(rdx, rdx, Immediate(18273));
-  __ shrl(rax, Immediate(16));
-  __ addl(rax, rdx);
+  Register scratch3 = ToRegister(instr->scratch3());
+  __ movzxwl(scratch3, state0);
+  __ imull(scratch3, scratch3, Immediate(18273));
+  __ shrl(state0, Immediate(16));
+  __ addl(state0, scratch3);
   // Save state[0].
-  __ movl(FieldOperand(rbx, ByteArray::kHeaderSize), rax);
+  __ movl(FieldOperand(state, ByteArray::kHeaderSize), state0);
 
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
-  __ movzxwl(rdx, rcx);
-  __ imull(rdx, rdx, Immediate(36969));
-  __ shrl(rcx, Immediate(16));
-  __ addl(rcx, rdx);
+  __ movzxwl(scratch3, state1);
+  __ imull(scratch3, scratch3, Immediate(36969));
+  __ shrl(state1, Immediate(16));
+  __ addl(state1, scratch3);
   // Save state[1].
-  __ movl(FieldOperand(rbx, ByteArray::kHeaderSize + kSeedSize), rcx);
+  __ movl(FieldOperand(state, ByteArray::kHeaderSize + kSeedSize), state1);
 
   // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
-  __ shll(rax, Immediate(14));
-  __ andl(rcx, Immediate(0x3FFFF));
-  __ addl(rax, rcx);
+  Register random = state0;
+  __ shll(random, Immediate(14));
+  __ andl(state1, Immediate(0x3FFFF));
+  __ addl(random, state1);
 
-  __ bind(deferred->exit());
   // Convert 32 random bits in rax to 0.(32 random bits) in a double
   // by computing:
   // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
-  __ movq(rcx, V8_INT64_C(0x4130000000000000),
+  XMMRegister result = ToDoubleRegister(instr->result());
+  // We use xmm0 as fixed scratch register here.
+  XMMRegister scratch4 = xmm0;
+  __ movq(scratch3, V8_INT64_C(0x4130000000000000),
           RelocInfo::NONE64);  // 1.0 x 2^20 as double
-  __ movq(xmm2, rcx);
-  __ movd(xmm1, rax);
-  __ xorps(xmm1, xmm2);
-  __ subsd(xmm1, xmm2);
-}
-
-
-void LCodeGen::DoDeferredRandom(LRandom* instr) {
-  __ PrepareCallCFunction(1);
-  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
-  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-  // Return value is in rax.
+  __ movq(scratch4, scratch3);
+  __ movd(result, random);
+  __ xorps(result, scratch4);
+  __ subsd(result, scratch4);
 }
 
 
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 222a419..f994645 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -126,7 +126,6 @@
   void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
-  void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredAllocate(LAllocate* instr);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index ac48b09..d9daaac 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1613,9 +1613,13 @@
 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->global_object()->representation().IsTagged());
-  LOperand* global_object = UseFixed(instr->global_object(), arg_reg_1);
-  LRandom* result = new(zone()) LRandom(global_object);
-  return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+  LOperand* global_object = UseTempRegister(instr->global_object());
+  LOperand* scratch = TempRegister();
+  LOperand* scratch2 = TempRegister();
+  LOperand* scratch3 = TempRegister();
+  LRandom* result = new(zone()) LRandom(
+      global_object, scratch, scratch2, scratch3);
+  return DefineFixedDouble(result, xmm1);
 }
 
 
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index ff0c61b..b3d08c8 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1404,13 +1404,22 @@
 };
 
 
-class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
-  explicit LRandom(LOperand* global_object) {
+  LRandom(LOperand* global_object,
+          LOperand* scratch,
+          LOperand* scratch2,
+          LOperand* scratch3) {
     inputs_[0] = global_object;
+    temps_[0] = scratch;
+    temps_[1] = scratch2;
+    temps_[2] = scratch3;
   }
 
   LOperand* global_object() { return inputs_[0]; }
+  LOperand* scratch() const { return temps_[0]; }
+  LOperand* scratch2() const { return temps_[1]; }
+  LOperand* scratch3() const { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(Random, "random")
   DECLARE_HYDROGEN_ACCESSOR(Random)
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index b2cfa86..95276d5 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -29,6 +29,7 @@
 
 #if V8_TARGET_ARCH_X64
 
+#include "arguments.h"
 #include "ic-inl.h"
 #include "codegen.h"
 #include "stub-cache.h"
@@ -366,6 +367,11 @@
                                      Register holder,
                                      Register name,
                                      Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
   __ push(name);
   Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
   ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
@@ -373,8 +379,6 @@
   __ push(kScratchRegister);
   __ push(receiver);
   __ push(holder);
-  __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
-  __ PushAddress(ExternalReference::isolate_address(masm->isolate()));
 }
 
 
@@ -389,7 +393,7 @@
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate());
-  __ Set(rax, 6);
+  __ Set(rax, StubCache::kInterceptorArgsLength);
   __ LoadAddress(rbx, ref);
 
   CEntryStub stub(1);
@@ -719,7 +723,7 @@
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        6);
+        StubCache::kInterceptorArgsLength);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -1322,19 +1326,27 @@
   ASSERT(!scratch4().is(reg));
   __ PopReturnAddressTo(scratch4());
 
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4);
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5);
   __ push(receiver());  // receiver
-  __ push(reg);  // holder
   if (heap()->InNewSpace(callback->data())) {
-    __ Move(scratch1(), callback);
-    __ push(FieldOperand(scratch1(),
+    ASSERT(!scratch2().is(reg));
+    __ Move(scratch2(), callback);
+    __ push(FieldOperand(scratch2(),
                          ExecutableAccessorInfo::kDataOffset));  // data
   } else {
     __ Push(Handle<Object>(callback->data(), isolate()));
   }
+  ASSERT(!kScratchRegister.is(reg));
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
   __ push(kScratchRegister);  // return value
   __ push(kScratchRegister);  // return value default
   __ PushAddress(ExternalReference::isolate_address(isolate()));
+  __ push(reg);  // holder
   __ push(name());  // name
   // Save a pointer to where we pushed the arguments pointer.  This will be
   // passed as the const ExecutableAccessorInfo& to the C++ callback.
@@ -1378,7 +1390,7 @@
                               thunk_address,
                               getter_arg,
                               kStackSpace,
-                              5);
+                              6);
 }
 
 
@@ -1477,7 +1489,7 @@
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
-    __ TailCallExternalReference(ref, 6, 1);
+    __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
   }
 }
 
@@ -2233,13 +2245,6 @@
   //  -- ...
   //  -- rsp[(argc + 1) * 4] : receiver
   // -----------------------------------
-
-  if (!CpuFeatures::IsSupported(SSE2)) {
-    return Handle<Code>::null();
-  }
-
-  CpuFeatureScope use_sse2(masm(), SSE2);
-
   const int argc = arguments().immediate();
 
   // If the object is not a JSObject or we got an unexpected number of
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 0775cc5..ee7ffad 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -106,6 +106,7 @@
         'test-time.cc',
         'test-types.cc',
         'test-unbound-queue.cc',
+        'test-unique.cc',
         'test-utils.cc',
         'test-version.cc',
         'test-weakmaps.cc',
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 6e47cd6..f4e40cd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -12670,8 +12670,8 @@
   typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
   static const bool kResetInDestructor = true;
   template<class S, class M>
-  V8_INLINE(static void Copy(const Persistent<S, M>& source,
-                             CopyablePersistent* dest)) {
+  static V8_INLINE void Copy(const Persistent<S, M>& source,
+                             CopyablePersistent* dest) {
     // do nothing, just allow copy
   }
 };
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
index cac162e..1a4c1ae 100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -1439,4 +1439,75 @@
 }
 
 
+TEST(code_relative_offset) {
+  // Test extracting the offset of a label from the beginning of the code
+  // in a register.
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  // Initialize a code object that will contain the code.
+  Handle<Object> code_object(isolate->heap()->undefined_value(), isolate);
+
+  Assembler assm(isolate, NULL, 0);
+
+  Label start, target_away, target_faraway;
+
+  __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
+
+  // r3 is used as the address zero, the test will crash when we load it.
+  __ mov(r3, Operand::Zero());
+
+  // r5 will be a pointer to the start of the code.
+  __ mov(r5, Operand(code_object));
+  __ mov_label_offset(r4, &start);
+
+  __ mov_label_offset(r1, &target_faraway);
+  __ str(r1, MemOperand(sp, kPointerSize, NegPreIndex));
+
+  __ mov_label_offset(r1, &target_away);
+
+  // Jump straight to 'target_away' the first time and use the relative
+  // position the second time. This covers the case when extracting the
+  // position of a label which is linked.
+  __ mov(r2, Operand::Zero());
+  __ bind(&start);
+  __ cmp(r2, Operand::Zero());
+  __ b(eq, &target_away);
+  __ add(pc, r5, r1);
+  // Emit invalid instructions to push the label between 2^8 and 2^16
+  // instructions away. The test will crash if they are reached.
+  for (int i = 0; i < (1 << 10); i++) {
+    __ ldr(r3, MemOperand(r3));
+  }
+  __ bind(&target_away);
+  // This will be hit twice: r0 = r0 + 5 + 5.
+  __ add(r0, r0, Operand(5));
+
+  __ ldr(r1, MemOperand(sp, kPointerSize, PostIndex), ne);
+  __ add(pc, r5, r4, LeaveCC, ne);
+
+  __ mov(r2, Operand(1));
+  __ b(&start);
+  // Emit invalid instructions to push the label between 2^16 and 2^24
+  // instructions away. The test will crash if they are reached.
+  for (int i = 0; i < (1 << 21); i++) {
+    __ ldr(r3, MemOperand(r3));
+  }
+  __ bind(&target_faraway);
+  // r0 = r0 + 5 + 5 + 11
+  __ add(r0, r0, Operand(11));
+
+  __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(desc,
+      Code::ComputeFlags(Code::STUB), code_object);
+  CHECK(code->IsCode());
+  F1 f = FUNCTION_CAST<F1>(code->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 21, 0, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(42, res);
+}
+
 #undef __
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-dictionary.cc
index 21c20bd..b9e8b1e 100644
--- a/test/cctest/test-dictionary.cc
+++ b/test/cctest/test-dictionary.cc
@@ -101,6 +101,57 @@
 }
 
 
+class ObjectHashTableTest: public ObjectHashTable {
+ public:
+  void insert(int entry, int key, int value) {
+    set(EntryToIndex(entry), Smi::FromInt(key));
+    set(EntryToIndex(entry) + 1, Smi::FromInt(value));
+  }
+
+  int lookup(int key) {
+    return Smi::cast(Lookup(Smi::FromInt(key)))->value();
+  }
+
+  int capacity() {
+    return Capacity();
+  }
+};
+
+
+TEST(HashTableRehash) {
+  LocalContext context;
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  v8::HandleScope scope(context->GetIsolate());
+  // Test almost filled table.
+  {
+    Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
+    ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
+    int capacity = t->capacity();
+    for (int i = 0; i < capacity - 1; i++) {
+      t->insert(i, i * i, i);
+    }
+    t->Rehash(Smi::FromInt(0));
+    for (int i = 0; i < capacity - 1; i++) {
+      CHECK_EQ(i, t->lookup(i * i));
+    }
+  }
+  // Test half-filled table.
+  {
+    Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
+    ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
+    int capacity = t->capacity();
+    for (int i = 0; i < capacity / 2; i++) {
+      t->insert(i, i * i, i);
+    }
+    t->Rehash(Smi::FromInt(0));
+    for (int i = 0; i < capacity / 2; i++) {
+      CHECK_EQ(i, t->lookup(i * i));
+    }
+  }
+}
+
+
 #ifdef DEBUG
 TEST(ObjectHashSetCausesGC) {
   i::FLAG_stress_compaction = false;
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 64075d2..9d74011 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -3141,10 +3141,6 @@
   i::FLAG_allow_natives_syntax = true;
   i::FLAG_flush_code_incrementally = true;
 
-  // Disable loading the i18n extension which breaks the assumptions of this
-  // test about the heap layout.
-  i::FLAG_enable_i18n = false;
-
   CcTest::InitializeVM();
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
diff --git a/test/cctest/test-unique.cc b/test/cctest/test-unique.cc
new file mode 100644
index 0000000..1d26858
--- /dev/null
+++ b/test/cctest/test-unique.cc
@@ -0,0 +1,488 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "factory.h"
+#include "global-handles.h"
+#include "unique.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+template <class T, class U>
+void CheckHashCodeEqual(Unique<T> a, Unique<U> b) {
+  int64_t hasha = static_cast<int64_t>(a.Hashcode());
+  int64_t hashb = static_cast<int64_t>(b.Hashcode());
+  CHECK_NE(static_cast<int64_t>(0), hasha);
+  CHECK_NE(static_cast<int64_t>(0), hashb);
+  CHECK_EQ(hasha, hashb);
+}
+
+
+template <class T, class U>
+void CheckHashCodeNotEqual(Unique<T> a, Unique<U> b) {
+  int64_t hasha = static_cast<int64_t>(a.Hashcode());
+  int64_t hashb = static_cast<int64_t>(b.Hashcode());
+  CHECK_NE(static_cast<int64_t>(0), hasha);
+  CHECK_NE(static_cast<int64_t>(0), hashb);
+  CHECK_NE(hasha, hashb);
+}
+
+
+TEST(UniqueCreate) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Handle<String> A = factory->InternalizeUtf8String("A");
+  Unique<String> HA(A);
+
+  CHECK(*HA.handle() == *A);
+  CHECK_EQ(*A, *HA.handle());
+
+  Unique<String> HA2(A);
+
+  CheckHashCodeEqual(HA, HA2);
+  CHECK(HA == HA2);
+  CHECK_EQ(*HA.handle(), *HA2.handle());
+
+  CHECK(HA2 == HA);
+  CHECK_EQ(*HA2.handle(), *HA.handle());
+
+  Handle<String> B = factory->InternalizeUtf8String("B");
+  Unique<String> HB(B);
+
+  CheckHashCodeNotEqual(HA, HB);
+  CHECK(HA != HB);
+  CHECK_NE(*HA.handle(), *HB.handle());
+
+  CHECK(HB != HA);
+  CHECK_NE(*HB.handle(), *HA.handle());
+
+  // TODO(titzer): check that Unique properly survives a GC.
+}
+
+
+TEST(UniqueSubsume) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Handle<String> A = factory->InternalizeUtf8String("A");
+  Unique<String> HA(A);
+
+  CHECK(*HA.handle() == *A);
+  CHECK_EQ(*A, *HA.handle());
+
+  Unique<Object> HO = HA;  // Here comes the subsumption, boys.
+
+  CheckHashCodeEqual(HA, HO);
+  CHECK(HA == HO);
+  CHECK_EQ(*HA.handle(), *HO.handle());
+
+  CHECK(HO == HA);
+  CHECK_EQ(*HO.handle(), *HA.handle());
+}
+
+
+TEST(UniqueSet_Add) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
+
+  CHECK_EQ(0, set->size());
+  set->Add(A, &zone);
+  CHECK_EQ(1, set->size());
+  set->Add(A, &zone);
+  CHECK_EQ(1, set->size());
+  set->Add(B, &zone);
+  CHECK_EQ(2, set->size());
+  set->Add(C, &zone);
+  CHECK_EQ(3, set->size());
+  set->Add(C, &zone);
+  CHECK_EQ(3, set->size());
+  set->Add(B, &zone);
+  CHECK_EQ(3, set->size());
+  set->Add(A, &zone);
+  CHECK_EQ(3, set->size());
+}
+
+
+template <class T>
+static void CHECK_SETS(
+    UniqueSet<T>* set1, UniqueSet<T>* set2, bool expected) {
+  CHECK(set1->Equals(set1));
+  CHECK(set2->Equals(set2));
+  CHECK(expected == set1->Equals(set2));
+  CHECK(expected == set2->Equals(set1));
+}
+
+
+TEST(UniqueSet_Equals) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+  CHECK_SETS(set1, set2, true);
+
+  set1->Add(A, &zone);
+
+  CHECK_SETS(set1, set2, false);
+
+  set2->Add(A, &zone);
+
+  CHECK_SETS(set1, set2, true);
+
+  set1->Add(B, &zone);
+
+  CHECK_SETS(set1, set2, false);
+
+  set2->Add(C, &zone);
+
+  CHECK_SETS(set1, set2, false);
+
+  set1->Add(C, &zone);
+
+  CHECK_SETS(set1, set2, false);
+
+  set2->Add(B, &zone);
+
+  CHECK_SETS(set1, set2, true);
+}
+
+
+TEST(UniqueSet_IsSubset1) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(set2->IsSubset(set1));
+
+  set1->Add(A, &zone);
+
+  CHECK(!set1->IsSubset(set2));
+  CHECK(set2->IsSubset(set1));
+
+  set2->Add(B, &zone);
+
+  CHECK(!set1->IsSubset(set2));
+  CHECK(!set2->IsSubset(set1));
+
+  set2->Add(A, &zone);
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(!set2->IsSubset(set1));
+
+  set1->Add(B, &zone);
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(set2->IsSubset(set1));
+}
+
+
+TEST(UniqueSet_IsSubset2) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+  Unique<String> D(factory->InternalizeUtf8String("D"));
+  Unique<String> E(factory->InternalizeUtf8String("E"));
+  Unique<String> F(factory->InternalizeUtf8String("F"));
+  Unique<String> G(factory->InternalizeUtf8String("G"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+  set1->Add(A, &zone);
+  set1->Add(C, &zone);
+  set1->Add(E, &zone);
+
+  set2->Add(A, &zone);
+  set2->Add(B, &zone);
+  set2->Add(C, &zone);
+  set2->Add(D, &zone);
+  set2->Add(E, &zone);
+  set2->Add(F, &zone);
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(!set2->IsSubset(set1));
+
+  set1->Add(G, &zone);
+
+  CHECK(!set1->IsSubset(set2));
+  CHECK(!set2->IsSubset(set1));
+}
+
+
+template <class T>
+static UniqueSet<T>* MakeSet(Zone* zone, int which, Unique<T>* elements) {
+  UniqueSet<T>* set = new(zone) UniqueSet<T>();
+  for (int i = 0; i < 32; i++) {
+    if ((which & (1 << i)) != 0) set->Add(elements[i], zone);
+  }
+  return set;
+}
+
+
+TEST(UniqueSet_IsSubsetExhaustive) {
+  const int kSetSize = 6;
+
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Zone zone(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+  Unique<String> D(factory->InternalizeUtf8String("D"));
+  Unique<String> E(factory->InternalizeUtf8String("E"));
+  Unique<String> F(factory->InternalizeUtf8String("F"));
+  Unique<String> G(factory->InternalizeUtf8String("G"));
+
+  Unique<String> elements[] = {
+    A, B, C, D, E, F, G
+  };
+
+  // Exhaustively test all sets with <= 6 elements.
+  for (int i = 0; i < (1 << kSetSize); i++) {
+    for (int j = 0; j < (1 << kSetSize); j++) {
+      UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+      UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+      CHECK(((i & j) == i) == set1->IsSubset(set2));
+    }
+  }
+}
+
+
+TEST(UniqueSet_Intersect1) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* result;
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(set2->IsSubset(set1));
+
+  set1->Add(A, &zone);
+
+  result = set1->Intersect(set2, &zone);
+
+  CHECK_EQ(0, result->size());
+  CHECK(set2->Equals(result));
+
+  set2->Add(A, &zone);
+
+  result = set1->Intersect(set2, &zone);
+
+  CHECK_EQ(1, result->size());
+  CHECK(set1->Equals(result));
+  CHECK(set2->Equals(result));
+
+  set2->Add(B, &zone);
+  set2->Add(C, &zone);
+
+  result = set1->Intersect(set2, &zone);
+
+  CHECK_EQ(1, result->size());
+  CHECK(set1->Equals(result));
+}
+
+
+TEST(UniqueSet_IntersectExhaustive) {
+  const int kSetSize = 6;
+
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Zone zone(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+  Unique<String> D(factory->InternalizeUtf8String("D"));
+  Unique<String> E(factory->InternalizeUtf8String("E"));
+  Unique<String> F(factory->InternalizeUtf8String("F"));
+  Unique<String> G(factory->InternalizeUtf8String("G"));
+
+  Unique<String> elements[] = {
+    A, B, C, D, E, F, G
+  };
+
+  // Exhaustively test all sets with <= 6 elements.
+  for (int i = 0; i < (1 << kSetSize); i++) {
+    for (int j = 0; j < (1 << kSetSize); j++) {
+      UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+      UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+      UniqueSet<String>* result = set1->Intersect(set2, &zone);
+      UniqueSet<String>* expected = MakeSet(&zone, i & j, elements);
+
+      CHECK(result->Equals(expected));
+      CHECK(expected->Equals(result));
+    }
+  }
+}
+
+
+TEST(UniqueSet_Union1) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+  UniqueSet<String>* result;
+
+  CHECK(set1->IsSubset(set2));
+  CHECK(set2->IsSubset(set1));
+
+  set1->Add(A, &zone);
+
+  result = set1->Union(set2, &zone);
+
+  CHECK_EQ(1, result->size());
+  CHECK(set1->Equals(result));
+
+  set2->Add(A, &zone);
+
+  result = set1->Union(set2, &zone);
+
+  CHECK_EQ(1, result->size());
+  CHECK(set1->Equals(result));
+  CHECK(set2->Equals(result));
+
+  set2->Add(B, &zone);
+  set2->Add(C, &zone);
+
+  result = set1->Union(set2, &zone);
+
+  CHECK_EQ(3, result->size());
+  CHECK(set2->Equals(result));
+}
+
+
+TEST(UniqueSet_UnionExhaustive) {
+  const int kSetSize = 6;
+
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Zone zone(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+  Unique<String> D(factory->InternalizeUtf8String("D"));
+  Unique<String> E(factory->InternalizeUtf8String("E"));
+  Unique<String> F(factory->InternalizeUtf8String("F"));
+  Unique<String> G(factory->InternalizeUtf8String("G"));
+
+  Unique<String> elements[] = {
+    A, B, C, D, E, F, G
+  };
+
+  // Exhaustively test all sets with <= 6 elements.
+  for (int i = 0; i < (1 << kSetSize); i++) {
+    for (int j = 0; j < (1 << kSetSize); j++) {
+      UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+      UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+      UniqueSet<String>* result = set1->Union(set2, &zone);
+      UniqueSet<String>* expected = MakeSet(&zone, i | j, elements);
+
+      CHECK(result->Equals(expected));
+      CHECK(expected->Equals(result));
+    }
+  }
+}
+
diff --git a/test/mjsunit/debug-script.js b/test/mjsunit/debug-script.js
index 6e673f7..1cbdb37 100644
--- a/test/mjsunit/debug-script.js
+++ b/test/mjsunit/debug-script.js
@@ -59,9 +59,9 @@
 }
 
 // This has to be updated if the number of native scripts change.
-assertEquals(16, named_native_count);
-// Only the 'gc' and (depending on flags) the 'i18n' extensions are loaded.
-assertTrue(extension_count == 1 || extension_count == 2);
+assertTrue(named_native_count == 16 || named_native_count == 17);
+// Only the 'gc' extension is loaded.
+assertEquals(1, extension_count);
 // This script and mjsunit.js has been loaded.  If using d8, d8 loads
 // a normal script during startup too.
 assertTrue(normal_count == 2 || normal_count == 3);
diff --git a/test/mjsunit/fuzz-natives-part1.js b/test/mjsunit/fuzz-natives-part1.js
index 08b7258..e76b9be 100644
--- a/test/mjsunit/fuzz-natives-part1.js
+++ b/test/mjsunit/fuzz-natives-part1.js
@@ -151,7 +151,6 @@
   "LazyCompile": true,
   "LazyRecompile": true,
   "ConcurrentRecompile": true,
-  "InstallRecompiledCode": true,
   "NotifyDeoptimized": true,
   "NotifyStubFailure": true,
   "NotifyOSR": true,
diff --git a/test/mjsunit/fuzz-natives-part2.js b/test/mjsunit/fuzz-natives-part2.js
index 1cebf41..0797deb 100644
--- a/test/mjsunit/fuzz-natives-part2.js
+++ b/test/mjsunit/fuzz-natives-part2.js
@@ -151,7 +151,6 @@
   "LazyCompile": true,
   "LazyRecompile": true,
   "ConcurrentRecompile": true,
-  "InstallRecompiledCode": true,
   "NotifyDeoptimized": true,
   "NotifyStubFailure": true,
   "NotifyOSR": true,
diff --git a/test/mjsunit/fuzz-natives-part3.js b/test/mjsunit/fuzz-natives-part3.js
index f2efee4..9a3a883 100644
--- a/test/mjsunit/fuzz-natives-part3.js
+++ b/test/mjsunit/fuzz-natives-part3.js
@@ -151,7 +151,6 @@
   "LazyCompile": true,
   "LazyRecompile": true,
   "ConcurrentRecompile": true,
-  "InstallRecompiledCode": true,
   "NotifyDeoptimized": true,
   "NotifyStubFailure": true,
   "NotifyOSR": true,
diff --git a/test/mjsunit/fuzz-natives-part4.js b/test/mjsunit/fuzz-natives-part4.js
index fa53480..83e00d2 100644
--- a/test/mjsunit/fuzz-natives-part4.js
+++ b/test/mjsunit/fuzz-natives-part4.js
@@ -151,7 +151,6 @@
   "LazyCompile": true,
   "LazyRecompile": true,
   "ConcurrentRecompile": true,
-  "InstallRecompiledCode": true,
   "NotifyDeoptimized": true,
   "NotifyStubFailure": true,
   "NotifyOSR": true,
diff --git a/test/mjsunit/regress/regress-2855.js b/test/mjsunit/regress/regress-2855.js
index ac721af..24ec452 100644
--- a/test/mjsunit/regress/regress-2855.js
+++ b/test/mjsunit/regress/regress-2855.js
@@ -39,3 +39,19 @@
   }
   assertEquals(expected, "" + foo("hello"));
 }
+
+// Make sure we look up "valueOf" only once.
+var count = 0;
+var x = new String("foo");
+Object.defineProperty(x, "valueOf",
+    { get: function() {
+             count++;
+             return function() {
+                      return 11;
+                    }
+           }
+    });
+for (var i = 0; i < 3; i++) {
+  assertEquals("11", "" + x);
+  assertEquals(i + 1, count);
+}
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 4f629ff..aa01a84 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -129,11 +129,6 @@
             ],
           },
         }],
-        ['v8_enable_i18n_support==1', {
-          'sources': [
-            '<(SHARED_INTERMEDIATE_DIR)/i18n-libraries.cc',
-          ],
-        }],
       ],
       'dependencies': [
         'v8_base.<(v8_target_arch)',
@@ -197,11 +192,6 @@
             'V8_SHARED',
           ],
         }],
-        ['v8_enable_i18n_support==1', {
-          'sources': [
-            '<(SHARED_INTERMEDIATE_DIR)/i18n-libraries.cc',
-          ],
-        }],
       ]
     },
     {
@@ -367,6 +357,8 @@
         '../../src/hydrogen-mark-deoptimize.h',
         '../../src/hydrogen-minus-zero.cc',
         '../../src/hydrogen-minus-zero.h',
+        '../../src/hydrogen-osr.cc',
+        '../../src/hydrogen-osr.h',
         '../../src/hydrogen-range-analysis.cc',
         '../../src/hydrogen-range-analysis.h',
         '../../src/hydrogen-redundant-phi.cc',
@@ -379,8 +371,6 @@
         '../../src/hydrogen-sce.h',
         '../../src/hydrogen-uint32-analysis.cc',
         '../../src/hydrogen-uint32-analysis.h',
-        '../../src/hydrogen-osr.cc',
-        '../../src/hydrogen-osr.h',
         '../../src/i18n.cc',
         '../../src/i18n.h',
         '../../src/icu_util.cc',
@@ -528,6 +518,7 @@
         '../../src/unicode-inl.h',
         '../../src/unicode.cc',
         '../../src/unicode.h',
+        '../../src/unique.h',
         '../../src/uri.h',
         '../../src/utils-inl.h',
         '../../src/utils.cc',
@@ -863,10 +854,6 @@
           ]
         }],
         ['v8_enable_i18n_support==1', {
-          'sources': [
-            '../../src/extensions/i18n/i18n-extension.cc',
-            '../../src/extensions/i18n/i18n-extension.h',
-          ],
           'dependencies': [
             '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
             '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
@@ -894,24 +881,15 @@
           'toolsets': ['target'],
         }],
         ['v8_enable_i18n_support==1', {
-          'actions': [{
-            'action_name': 'js2c_i18n',
-            'inputs': [
-              '../../tools/js2c.py',
-              '<@(i18n_library_files)',
+          'variables': {
+            'i18n_library_files': [
+              '../../src/i18n.js',
             ],
-            'outputs': [
-              '<(SHARED_INTERMEDIATE_DIR)/i18n-libraries.cc',
-            ],
-            'action': [
-              'python',
-              '../../tools/js2c.py',
-              '<@(_outputs)',
-              'I18N',
-              '<(v8_compress_startup_data)',
-              '<@(i18n_library_files)'
-            ],
-          }],
+          },
+        }, {
+          'variables': {
+            'i18n_library_files': [],
+          },
         }],
       ],
       'variables': {
@@ -945,18 +923,6 @@
           '../../src/harmony-string.js',
           '../../src/harmony-array.js',
         ],
-        'i18n_library_files': [
-          '../../src/extensions/i18n/header.js',
-          '../../src/extensions/i18n/globals.js',
-          '../../src/extensions/i18n/locale.js',
-          '../../src/extensions/i18n/collator.js',
-          '../../src/extensions/i18n/number-format.js',
-          '../../src/extensions/i18n/date-format.js',
-          '../../src/extensions/i18n/break-iterator.js',
-          '../../src/extensions/i18n/i18n-utils.js',
-          '../../src/extensions/i18n/overrides.js',
-          '../../src/extensions/i18n/footer.js',
-        ],
       },
       'actions': [
         {
@@ -964,6 +930,7 @@
           'inputs': [
             '../../tools/js2c.py',
             '<@(library_files)',
+            '<@(i18n_library_files)',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
@@ -974,7 +941,8 @@
             '<@(_outputs)',
             'CORE',
             '<(v8_compress_startup_data)',
-            '<@(library_files)'
+            '<@(library_files)',
+            '<@(i18n_library_files)',
           ],
         },
         {