Version 3.16.6

Made the Isolate parameter mandatory in Locker and Unlocker classes. (issue 2487)

Avoid pointer underflow in CopyCharsUnsigned. (issue 2493)

Generate shim headers when using system v8. (Chromium issue 165264)

Fixed arguments materialization for inlined apply(). (issue 2489)

Sync'ed laziness between BuildFunctionInfo and MakeFunctionInfo. (Chromium issue 147497)

Added sanity check to CodeFlusher::AddCandidate. (Chromium issue 169209)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13439 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 57d8d0f..16b3b0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2013-01-18: Version 3.16.6
+
+        Made the Isolate parameter mandatory in Locker and Unlocker classes.
+        (issue 2487)
+
+        Avoid pointer underflow in CopyCharsUnsigned.
+        (issue 2493)
+
+        Generate shim headers when using system v8.
+        (Chromium issue 165264)
+
+        Fixed arguments materialization for inlined apply().
+        (issue 2489)
+
+        Sync'ed laziness between BuildFunctionInfo and MakeFunctionInfo.
+        (Chromium issue 147497)
+
+        Added sanity check to CodeFlusher::AddCandidate.
+        (Chromium issue 169209)
+
+        Performance and stability improvements on all platforms.
+
+
+2013-01-15: Version 3.16.5
+
+        Removed deprecated functions from V8's external API.
+
+        Prepared API for WebKit use of Latin-1.
+
+        Fixed V8 issue 2486.
+
+        Fixed Chromium issue 169723.
+
+        Performance and stability improvements on all platforms.
+
+
 2013-01-11: Version 3.16.4
 
         Fixed Chromium issues 168545 and 169209.
diff --git a/Makefile b/Makefile
index db32a95..0cdae4b 100644
--- a/Makefile
+++ b/Makefile
@@ -83,10 +83,6 @@
 ifeq ($(gdbjit), on)
   GYPFLAGS += -Dv8_enable_gdbjit=1
 endif
-# liveobjectlist=on
-ifeq ($(liveobjectlist), on)
-  GYPFLAGS += -Dv8_use_liveobjectlist=true
-endif
 # vfp2=off
 ifeq ($(vfp2), off)
   GYPFLAGS += -Dv8_can_use_vfp2_instructions=false
diff --git a/SConstruct b/SConstruct
index 5f8616a..21d1902 100644
--- a/SConstruct
+++ b/SConstruct
@@ -67,16 +67,9 @@
     'debuggersupport:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT'],
     },
-    'inspector:on': {
-      'CPPDEFINES':   ['INSPECTOR'],
-    },
     'fasttls:off': {
       'CPPDEFINES':   ['V8_NO_FAST_TLS'],
     },
-    'liveobjectlist:on': {
-      'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
-                       'LIVE_OBJECT_LIST', 'OBJECT_PRINT'],
-    }
   },
   'gcc': {
     'all': {
@@ -1051,16 +1044,6 @@
     'default': 'on',
     'help': 'enable debugging of JavaScript code'
   },
-  'inspector': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable inspector features'
-  },
-  'liveobjectlist': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable live object list features in the debugger'
-  },
   'soname': {
     'values': ['on', 'off'],
     'default': 'off',
@@ -1418,13 +1401,6 @@
     options['msvcltcg'] = 'on'
   if (options['mipsabi'] != 'none') and (options['arch'] != 'mips') and (options['simulator'] != 'mips'):
     options['mipsabi'] = 'none'
-  if options['liveobjectlist'] == 'on':
-    if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'):
-      # Print a warning that liveobjectlist will implicitly enable the debugger
-      print "Warning: forcing debuggersupport on for liveobjectlist"
-    options['debuggersupport'] = 'on'
-    options['inspector'] = 'on'
-    options['objectprint'] = 'on'
 
 
 def ParseEnvOverrides(arg, imports):
diff --git a/build/common.gypi b/build/common.gypi
index 34bf50c..824cabe 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -92,7 +92,6 @@
 
     'v8_use_snapshot%': 'true',
     'host_os%': '<(OS)',
-    'v8_use_liveobjectlist%': 'false',
     'werror%': '-Werror',
 
     # With post mortem support enabled, metadata is embedded into libv8 that
@@ -257,14 +256,6 @@
         },
         'msvs_configuration_platform': 'x64',
       }],  # v8_target_arch=="x64"
-      ['v8_use_liveobjectlist=="true"', {
-        'defines': [
-          'ENABLE_DEBUGGER_SUPPORT',
-          'INSPECTOR',
-          'OBJECT_PRINT',
-          'LIVEOBJECTLIST',
-        ],
-      }],
       ['v8_compress_startup_data=="bz2"', {
         'defines': [
           'COMPRESS_STARTUP_DATA_BZ2',
diff --git a/include/v8.h b/include/v8.h
index 5d8c195..e5af0dd 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -38,6 +38,9 @@
 #ifndef V8_H_
 #define V8_H_
 
+// TODO(svenpanne) Remove me when the Chrome bindings are adapted.
+#define V8_DISABLE_DEPRECATIONS 1
+
 #include "v8stdint.h"
 
 #ifdef _WIN32
@@ -611,7 +614,7 @@
 /**
  * The origin, within a file, of a script.
  */
-class ScriptOrigin {
+class V8EXPORT ScriptOrigin {
  public:
   V8_INLINE(ScriptOrigin(
       Handle<Value> resource_name,
@@ -904,7 +907,7 @@
 /**
  * The superclass of all JavaScript values and objects.
  */
-class Value : public Data {
+class V8EXPORT Value : public Data {
  public:
   /**
    * Returns true if this value is the undefined value.  See ECMA-262
@@ -921,12 +924,12 @@
    /**
    * Returns true if this value is true.
    */
-  V8EXPORT bool IsTrue() const;
+  bool IsTrue() const;
 
   /**
    * Returns true if this value is false.
    */
-  V8EXPORT bool IsFalse() const;
+  bool IsFalse() const;
 
   /**
    * Returns true if this value is an instance of the String type.
@@ -937,121 +940,121 @@
   /**
    * Returns true if this value is a function.
    */
-  V8EXPORT bool IsFunction() const;
+  bool IsFunction() const;
 
   /**
    * Returns true if this value is an array.
    */
-  V8EXPORT bool IsArray() const;
+  bool IsArray() const;
 
   /**
    * Returns true if this value is an object.
    */
-  V8EXPORT bool IsObject() const;
+  bool IsObject() const;
 
   /**
    * Returns true if this value is boolean.
    */
-  V8EXPORT bool IsBoolean() const;
+  bool IsBoolean() const;
 
   /**
    * Returns true if this value is a number.
    */
-  V8EXPORT bool IsNumber() const;
+  bool IsNumber() const;
 
   /**
    * Returns true if this value is external.
    */
-  V8EXPORT bool IsExternal() const;
+  bool IsExternal() const;
 
   /**
    * Returns true if this value is a 32-bit signed integer.
    */
-  V8EXPORT bool IsInt32() const;
+  bool IsInt32() const;
 
   /**
    * Returns true if this value is a 32-bit unsigned integer.
    */
-  V8EXPORT bool IsUint32() const;
+  bool IsUint32() const;
 
   /**
    * Returns true if this value is a Date.
    */
-  V8EXPORT bool IsDate() const;
+  bool IsDate() const;
 
   /**
    * Returns true if this value is a Boolean object.
    */
-  V8EXPORT bool IsBooleanObject() const;
+  bool IsBooleanObject() const;
 
   /**
    * Returns true if this value is a Number object.
    */
-  V8EXPORT bool IsNumberObject() const;
+  bool IsNumberObject() const;
 
   /**
    * Returns true if this value is a String object.
    */
-  V8EXPORT bool IsStringObject() const;
+  bool IsStringObject() const;
 
   /**
    * Returns true if this value is a NativeError.
    */
-  V8EXPORT bool IsNativeError() const;
+  bool IsNativeError() const;
 
   /**
    * Returns true if this value is a RegExp.
    */
-  V8EXPORT bool IsRegExp() const;
+  bool IsRegExp() const;
 
-  V8EXPORT Local<Boolean> ToBoolean() const;
-  V8EXPORT Local<Number> ToNumber() const;
-  V8EXPORT Local<String> ToString() const;
-  V8EXPORT Local<String> ToDetailString() const;
-  V8EXPORT Local<Object> ToObject() const;
-  V8EXPORT Local<Integer> ToInteger() const;
-  V8EXPORT Local<Uint32> ToUint32() const;
-  V8EXPORT Local<Int32> ToInt32() const;
+  Local<Boolean> ToBoolean() const;
+  Local<Number> ToNumber() const;
+  Local<String> ToString() const;
+  Local<String> ToDetailString() const;
+  Local<Object> ToObject() const;
+  Local<Integer> ToInteger() const;
+  Local<Uint32> ToUint32() const;
+  Local<Int32> ToInt32() const;
 
   /**
    * Attempts to convert a string to an array index.
    * Returns an empty handle if the conversion fails.
    */
-  V8EXPORT Local<Uint32> ToArrayIndex() const;
+  Local<Uint32> ToArrayIndex() const;
 
-  V8EXPORT bool BooleanValue() const;
-  V8EXPORT double NumberValue() const;
-  V8EXPORT int64_t IntegerValue() const;
-  V8EXPORT uint32_t Uint32Value() const;
-  V8EXPORT int32_t Int32Value() const;
+  bool BooleanValue() const;
+  double NumberValue() const;
+  int64_t IntegerValue() const;
+  uint32_t Uint32Value() const;
+  int32_t Int32Value() const;
 
   /** JS == */
-  V8EXPORT bool Equals(Handle<Value> that) const;
-  V8EXPORT bool StrictEquals(Handle<Value> that) const;
+  bool Equals(Handle<Value> that) const;
+  bool StrictEquals(Handle<Value> that) const;
 
  private:
   V8_INLINE(bool QuickIsUndefined() const);
   V8_INLINE(bool QuickIsNull() const);
   V8_INLINE(bool QuickIsString() const);
-  V8EXPORT bool FullIsUndefined() const;
-  V8EXPORT bool FullIsNull() const;
-  V8EXPORT bool FullIsString() const;
+  bool FullIsUndefined() const;
+  bool FullIsNull() const;
+  bool FullIsString() const;
 };
 
 
 /**
  * The superclass of primitive values.  See ECMA-262 4.3.2.
  */
-class Primitive : public Value { };
+class V8EXPORT Primitive : public Value { };
 
 
 /**
  * A primitive boolean value (ECMA-262, 4.3.14).  Either the true
  * or false value.
  */
-class Boolean : public Primitive {
+class V8EXPORT Boolean : public Primitive {
  public:
-  V8EXPORT bool Value() const;
+  bool Value() const;
   V8_INLINE(static Handle<Boolean> New(bool value));
 };
 
@@ -1059,23 +1062,24 @@
 /**
  * A JavaScript string value (ECMA-262, 4.3.17).
  */
-class String : public Primitive {
+class V8EXPORT String : public Primitive {
  public:
   enum Encoding {
     UNKNOWN_ENCODING = 0x1,
     TWO_BYTE_ENCODING = 0x0,
-    ASCII_ENCODING = 0x4
+    ASCII_ENCODING = 0x4,
+    ONE_BYTE_ENCODING = 0x4
   };
   /**
    * Returns the number of characters in this string.
    */
-  V8EXPORT int Length() const;
+  int Length() const;
 
   /**
    * Returns the number of bytes in the UTF-8 encoded
    * representation of this string.
    */
-  V8EXPORT int Utf8Length() const;
+  int Utf8Length() const;
 
   /**
    * A fast conservative check for non-ASCII characters.  May
@@ -1083,7 +1087,12 @@
    * false you can be sure that all characters are in the range
    * 0-127.
    */
-  V8EXPORT bool MayContainNonAscii() const;
+  bool MayContainNonAscii() const;
+
+  /**
+   * Returns whether this string contains only one byte data.
+   */
+  bool IsOneByte() const;
 
   /**
    * Write the contents of the string to an external buffer.
@@ -1118,36 +1127,41 @@
   };
 
   // 16-bit character codes.
-  V8EXPORT int Write(uint16_t* buffer,
-                     int start = 0,
-                     int length = -1,
-                     int options = NO_OPTIONS) const;
+  int Write(uint16_t* buffer,
+            int start = 0,
+            int length = -1,
+            int options = NO_OPTIONS) const;
   // ASCII characters.
-  V8EXPORT int WriteAscii(char* buffer,
-                          int start = 0,
-                          int length = -1,
-                          int options = NO_OPTIONS) const;
+  int WriteAscii(char* buffer,
+                 int start = 0,
+                 int length = -1,
+                 int options = NO_OPTIONS) const;
+  // One byte characters.
+  int WriteOneByte(uint8_t* buffer,
+                   int start = 0,
+                   int length = -1,
+                   int options = NO_OPTIONS) const;
   // UTF-8 encoded characters.
-  V8EXPORT int WriteUtf8(char* buffer,
-                         int length = -1,
-                         int* nchars_ref = NULL,
-                         int options = NO_OPTIONS) const;
+  int WriteUtf8(char* buffer,
+                int length = -1,
+                int* nchars_ref = NULL,
+                int options = NO_OPTIONS) const;
 
   /**
    * A zero length string.
    */
-  V8EXPORT static v8::Local<v8::String> Empty();
+  static v8::Local<v8::String> Empty();
   V8_INLINE(static v8::Local<v8::String> Empty(Isolate* isolate));
 
   /**
    * Returns true if the string is external
    */
-  V8EXPORT bool IsExternal() const;
+  bool IsExternal() const;
 
   /**
    * Returns true if the string is both external and ASCII
    */
-  V8EXPORT bool IsExternalAscii() const;
+  bool IsExternalAscii() const;
 
   class V8EXPORT ExternalStringResourceBase {  // NOLINT
    public:
@@ -1228,6 +1242,8 @@
     ExternalAsciiStringResource() {}
   };
 
+  typedef ExternalAsciiStringResource ExternalOneByteStringResource;
+
   /**
    * If the string is an external string, return the ExternalStringResourceBase
    * regardless of the encoding, otherwise return NULL.  The encoding of the
@@ -1246,8 +1262,7 @@
    * Get the ExternalAsciiStringResource for an external ASCII string.
    * Returns NULL if IsExternalAscii() doesn't return true.
    */
-  V8EXPORT const ExternalAsciiStringResource* GetExternalAsciiStringResource()
-      const;
+  const ExternalAsciiStringResource* GetExternalAsciiStringResource() const;
 
   V8_INLINE(static String* Cast(v8::Value* obj));
 
@@ -1256,20 +1271,19 @@
    * The second parameter 'length' gives the buffer length. If omitted,
    * the function calls 'strlen' to determine the buffer length.
    */
-  V8EXPORT static Local<String> New(const char* data, int length = -1);
+  static Local<String> New(const char* data, int length = -1);
 
   /** Allocates a new string from 16-bit character codes.*/
-  V8EXPORT static Local<String> New(const uint16_t* data, int length = -1);
+  static Local<String> New(const uint16_t* data, int length = -1);
 
   /** Creates a symbol. Returns one if it exists already.*/
-  V8EXPORT static Local<String> NewSymbol(const char* data, int length = -1);
+  static Local<String> NewSymbol(const char* data, int length = -1);
 
   /**
    * Creates a new string by concatenating the left and the right strings
    * passed in as parameters.
    */
-  V8EXPORT static Local<String> Concat(Handle<String> left,
-                                       Handle<String> right);
+  static Local<String> Concat(Handle<String> left, Handle<String> right);
 
   /**
    * Creates a new external string using the data defined in the given
@@ -1279,7 +1293,7 @@
    * should the underlying buffer be deallocated or modified except through the
    * destructor of the external string resource.
    */
-  V8EXPORT static Local<String> NewExternal(ExternalStringResource* resource);
+  static Local<String> NewExternal(ExternalStringResource* resource);
 
   /**
    * Associate an external string resource with this string by transforming it
@@ -1290,7 +1304,7 @@
    * The string is not modified if the operation fails. See NewExternal for
    * information on the lifetime of the resource.
    */
-  V8EXPORT bool MakeExternal(ExternalStringResource* resource);
+  bool MakeExternal(ExternalStringResource* resource);
 
   /**
    * Creates a new external string using the ASCII data defined in the given
@@ -1299,8 +1313,8 @@
    * this function should not otherwise delete or modify the resource. Neither
    * should the underlying buffer be deallocated or modified except through the
    * destructor of the external string resource.
-   */ V8EXPORT static Local<String> NewExternal(
-      ExternalAsciiStringResource* resource);
+   */
+  static Local<String> NewExternal(ExternalAsciiStringResource* resource);
 
   /**
    * Associate an external string resource with this string by transforming it
@@ -1311,20 +1325,18 @@
    * The string is not modified if the operation fails. See NewExternal for
    * information on the lifetime of the resource.
    */
-  V8EXPORT bool MakeExternal(ExternalAsciiStringResource* resource);
+  bool MakeExternal(ExternalAsciiStringResource* resource);
 
   /**
    * Returns true if this string can be made external.
    */
-  V8EXPORT bool CanMakeExternal();
+  bool CanMakeExternal();
 
   /** Creates an undetectable string from the supplied ASCII or UTF-8 data.*/
-  V8EXPORT static Local<String> NewUndetectable(const char* data,
-                                                int length = -1);
+  static Local<String> NewUndetectable(const char* data, int length = -1);
 
   /** Creates an undetectable string from the supplied 16-bit character codes.*/
-  V8EXPORT static Local<String> NewUndetectable(const uint16_t* data,
-                                                int length = -1);
+  static Local<String> NewUndetectable(const uint16_t* data, int length = -1);
 
   /**
    * Converts an object to a UTF-8-encoded character array.  Useful if
@@ -1395,63 +1407,63 @@
   };
 
  private:
-  V8EXPORT void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
-                                                 Encoding encoding) const;
-  V8EXPORT void VerifyExternalStringResource(ExternalStringResource* val) const;
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
+                                        Encoding encoding) const;
+  void VerifyExternalStringResource(ExternalStringResource* val) const;
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A JavaScript number value (ECMA-262, 4.3.20)
  */
-class Number : public Primitive {
+class V8EXPORT Number : public Primitive {
  public:
-  V8EXPORT double Value() const;
-  V8EXPORT static Local<Number> New(double value);
+  double Value() const;
+  static Local<Number> New(double value);
   V8_INLINE(static Number* Cast(v8::Value* obj));
  private:
-  V8EXPORT Number();
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  Number();
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A JavaScript value representing a signed integer.
  */
-class Integer : public Number {
+class V8EXPORT Integer : public Number {
  public:
-  V8EXPORT static Local<Integer> New(int32_t value);
-  V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value);
-  V8EXPORT static Local<Integer> New(int32_t value, Isolate*);
-  V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value, Isolate*);
-  V8EXPORT int64_t Value() const;
+  static Local<Integer> New(int32_t value);
+  static Local<Integer> NewFromUnsigned(uint32_t value);
+  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));
  private:
-  V8EXPORT Integer();
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  Integer();
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A JavaScript value representing a 32-bit signed integer.
  */
-class Int32 : public Integer {
+class V8EXPORT Int32 : public Integer {
  public:
-  V8EXPORT int32_t Value() const;
+  int32_t Value() const;
  private:
-  V8EXPORT Int32();
+  Int32();
 };
 
 
 /**
  * A JavaScript value representing a 32-bit unsigned integer.
  */
-class Uint32 : public Integer {
+class V8EXPORT Uint32 : public Integer {
  public:
-  V8EXPORT uint32_t Value() const;
+  uint32_t Value() const;
  private:
-  V8EXPORT Uint32();
+  Uint32();
 };
 
 
@@ -1512,14 +1524,13 @@
 /**
  * A JavaScript object (ECMA-262, 4.3.3)
  */
-class Object : public Value {
+class V8EXPORT Object : public Value {
  public:
-  V8EXPORT bool Set(Handle<Value> key,
-                    Handle<Value> value,
-                    PropertyAttribute attribs = None);
+  bool Set(Handle<Value> key,
+           Handle<Value> value,
+           PropertyAttribute attribs = None);
 
-  V8EXPORT bool Set(uint32_t index,
-                    Handle<Value> value);
+  bool Set(uint32_t index, Handle<Value> value);
 
   // Sets a local property on this object bypassing interceptors and
   // overriding accessors or read-only properties.
@@ -1529,41 +1540,41 @@
   // will only be returned if the interceptor doesn't return a value.
   //
   // Note also that this only works for named properties.
-  V8EXPORT bool ForceSet(Handle<Value> key,
-                         Handle<Value> value,
-                         PropertyAttribute attribs = None);
+  bool ForceSet(Handle<Value> key,
+                Handle<Value> value,
+                PropertyAttribute attribs = None);
 
-  V8EXPORT Local<Value> Get(Handle<Value> key);
+  Local<Value> Get(Handle<Value> key);
 
-  V8EXPORT Local<Value> Get(uint32_t index);
+  Local<Value> Get(uint32_t index);
 
   /**
    * Gets the property attributes of a property which can be None or
    * any combination of ReadOnly, DontEnum and DontDelete. Returns
    * None when the property doesn't exist.
    */
-  V8EXPORT PropertyAttribute GetPropertyAttributes(Handle<Value> key);
+  PropertyAttribute GetPropertyAttributes(Handle<Value> key);
 
   // TODO(1245389): Replace the type-specific versions of these
   // functions with generic ones that accept a Handle<Value> key.
-  V8EXPORT bool Has(Handle<String> key);
+  bool Has(Handle<String> key);
 
-  V8EXPORT bool Delete(Handle<String> key);
+  bool Delete(Handle<String> key);
 
   // Delete a property on this object bypassing interceptors and
   // ignoring dont-delete attributes.
-  V8EXPORT bool ForceDelete(Handle<Value> key);
+  bool ForceDelete(Handle<Value> key);
 
-  V8EXPORT bool Has(uint32_t index);
+  bool Has(uint32_t index);
 
-  V8EXPORT bool Delete(uint32_t index);
+  bool Delete(uint32_t index);
 
-  V8EXPORT bool SetAccessor(Handle<String> name,
-                            AccessorGetter getter,
-                            AccessorSetter setter = 0,
-                            Handle<Value> data = Handle<Value>(),
-                            AccessControl settings = DEFAULT,
-                            PropertyAttribute attribute = None);
+  bool SetAccessor(Handle<String> name,
+                   AccessorGetter getter,
+                   AccessorSetter setter = 0,
+                   Handle<Value> data = Handle<Value>(),
+                   AccessControl settings = DEFAULT,
+                   PropertyAttribute attribute = None);
 
   /**
    * Returns an array containing the names of the enumerable properties
@@ -1571,78 +1582,61 @@
    * array returned by this method contains the same values as would
    * be enumerated by a for-in statement over this object.
    */
-  V8EXPORT Local<Array> GetPropertyNames();
+  Local<Array> GetPropertyNames();
 
   /**
    * This function has the same functionality as GetPropertyNames but
    * the returned array doesn't contain the names of properties from
    * prototype objects.
    */
-  V8EXPORT Local<Array> GetOwnPropertyNames();
+  Local<Array> GetOwnPropertyNames();
 
   /**
    * Get the prototype object.  This does not skip objects marked to
    * be skipped by __proto__ and it does not consult the security
    * handler.
    */
-  V8EXPORT Local<Value> GetPrototype();
+  Local<Value> GetPrototype();
 
   /**
    * Set the prototype object.  This does not skip objects marked to
    * be skipped by __proto__ and it does not consult the security
    * handler.
    */
-  V8EXPORT bool SetPrototype(Handle<Value> prototype);
+  bool SetPrototype(Handle<Value> prototype);
 
   /**
    * Finds an instance of the given function template in the prototype
    * chain.
    */
-  V8EXPORT Local<Object> FindInstanceInPrototypeChain(
-      Handle<FunctionTemplate> tmpl);
+  Local<Object> FindInstanceInPrototypeChain(Handle<FunctionTemplate> tmpl);
 
   /**
    * Call builtin Object.prototype.toString on this object.
    * This is different from Value::ToString() that may call
    * user-defined toString function. This one does not.
    */
-  V8EXPORT Local<String> ObjectProtoToString();
+  Local<String> ObjectProtoToString();
 
   /**
    * Returns the function invoked as a constructor for this object.
    * May be the null value.
    */
-  V8EXPORT Local<Value> GetConstructor();
+  Local<Value> GetConstructor();
 
   /**
    * Returns the name of the function invoked as a constructor for this object.
    */
-  V8EXPORT Local<String> GetConstructorName();
+  Local<String> GetConstructorName();
 
   /** Gets the number of internal fields for this Object. */
-  V8EXPORT int InternalFieldCount();
+  int InternalFieldCount();
 
   /** Gets the value from an internal field. */
   V8_INLINE(Local<Value> GetInternalField(int index));
 
   /** Sets the value in an internal field. */
-  V8EXPORT void SetInternalField(int index, Handle<Value> value);
-
-  /**
-   * Gets a native pointer from an internal field. Deprecated. If the pointer is
-   * always 2-byte-aligned, use GetAlignedPointerFromInternalField instead,
-   * otherwise use a combination of GetInternalField, External::Cast and
-   * External::Value.
-   */
-  V8EXPORT V8_DEPRECATED(void* GetPointerFromInternalField(int index));
-
-  /**
-   * Sets a native pointer in an internal field. Deprecated. If the pointer is
-   * always 2-byte aligned, use SetAlignedPointerInInternalField instead,
-   * otherwise use a combination of External::New and SetInternalField.
-   */
-  V8_DEPRECATED(V8_INLINE(void SetPointerInInternalField(int index,
-                                                         void* value)));
+  void SetInternalField(int index, Handle<Value> value);
 
   /**
    * Gets a 2-byte-aligned native pointer from an internal field. This field
@@ -1656,40 +1650,39 @@
    * a field, GetAlignedPointerFromInternalField must be used, everything else
    * leads to undefined behavior.
    */
-  V8EXPORT void SetAlignedPointerInInternalField(int index, void* value);
+  void SetAlignedPointerInInternalField(int index, void* value);
 
   // Testers for local properties.
-  V8EXPORT bool HasOwnProperty(Handle<String> key);
-  V8EXPORT bool HasRealNamedProperty(Handle<String> key);
-  V8EXPORT bool HasRealIndexedProperty(uint32_t index);
-  V8EXPORT bool HasRealNamedCallbackProperty(Handle<String> key);
+  bool HasOwnProperty(Handle<String> key);
+  bool HasRealNamedProperty(Handle<String> key);
+  bool HasRealIndexedProperty(uint32_t index);
+  bool HasRealNamedCallbackProperty(Handle<String> key);
 
   /**
    * If result.IsEmpty() no real property was located in the prototype chain.
    * This means interceptors in the prototype chain are not called.
    */
-  V8EXPORT Local<Value> GetRealNamedPropertyInPrototypeChain(
-      Handle<String> key);
+  Local<Value> GetRealNamedPropertyInPrototypeChain(Handle<String> key);
 
   /**
    * If result.IsEmpty() no real property was located on the object or
    * in the prototype chain.
    * This means interceptors in the prototype chain are not called.
    */
-  V8EXPORT Local<Value> GetRealNamedProperty(Handle<String> key);
+  Local<Value> GetRealNamedProperty(Handle<String> key);
 
   /** Tests for a named lookup interceptor.*/
-  V8EXPORT bool HasNamedLookupInterceptor();
+  bool HasNamedLookupInterceptor();
 
   /** Tests for an index lookup interceptor.*/
-  V8EXPORT bool HasIndexedLookupInterceptor();
+  bool HasIndexedLookupInterceptor();
 
   /**
    * Turns on access check on the object if the object is an instance of
    * a template that has access check callbacks. If an object has no
    * access check info, the object cannot be accessed by anyone.
    */
-  V8EXPORT void TurnOnAccessCheck();
+  void TurnOnAccessCheck();
 
   /**
    * Returns the identity hash for this object. The current implementation
@@ -1698,7 +1691,7 @@
    * The return value will never be 0. Also, it is not guaranteed to be
    * unique.
    */
-  V8EXPORT int GetIdentityHash();
+  int GetIdentityHash();
 
   /**
    * Access hidden properties on JavaScript objects. These properties are
@@ -1706,9 +1699,9 @@
    * C++ API. Hidden properties introduced by V8 internally (for example the
    * identity hash) are prefixed with "v8::".
    */
-  V8EXPORT bool SetHiddenValue(Handle<String> key, Handle<Value> value);
-  V8EXPORT Local<Value> GetHiddenValue(Handle<String> key);
-  V8EXPORT bool DeleteHiddenValue(Handle<String> key);
+  bool SetHiddenValue(Handle<String> key, Handle<Value> value);
+  Local<Value> GetHiddenValue(Handle<String> key);
+  bool DeleteHiddenValue(Handle<String> key);
 
   /**
    * Returns true if this is an instance of an api function (one
@@ -1717,18 +1710,18 @@
    * conservative and may return true for objects that haven't actually
    * been modified.
    */
-  V8EXPORT bool IsDirty();
+  bool IsDirty();
 
   /**
    * Clone this object with a fast but shallow copy.  Values will point
    * to the same values as the original object.
    */
-  V8EXPORT Local<Object> Clone();
+  Local<Object> Clone();
 
   /**
    * Returns the context in which the object was created.
    */
-  V8EXPORT Local<Context> CreationContext();
+  Local<Context> CreationContext();
 
   /**
    * Set the backing store of the indexed properties to be managed by the
@@ -1737,10 +1730,10 @@
    * Note: The embedding program still owns the data and needs to ensure that
    *       the backing store is preserved while V8 has a reference.
    */
-  V8EXPORT void SetIndexedPropertiesToPixelData(uint8_t* data, int length);
-  V8EXPORT bool HasIndexedPropertiesInPixelData();
-  V8EXPORT uint8_t* GetIndexedPropertiesPixelData();
-  V8EXPORT int GetIndexedPropertiesPixelDataLength();
+  void SetIndexedPropertiesToPixelData(uint8_t* data, int length);
+  bool HasIndexedPropertiesInPixelData();
+  uint8_t* GetIndexedPropertiesPixelData();
+  int GetIndexedPropertiesPixelDataLength();
 
   /**
    * Set the backing store of the indexed properties to be managed by the
@@ -1749,87 +1742,83 @@
    * Note: The embedding program still owns the data and needs to ensure that
    *       the backing store is preserved while V8 has a reference.
    */
-  V8EXPORT void SetIndexedPropertiesToExternalArrayData(
-      void* data,
-      ExternalArrayType array_type,
-      int number_of_elements);
-  V8EXPORT bool HasIndexedPropertiesInExternalArrayData();
-  V8EXPORT void* GetIndexedPropertiesExternalArrayData();
-  V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
-  V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();
+  void SetIndexedPropertiesToExternalArrayData(void* data,
+                                               ExternalArrayType array_type,
+                                               int number_of_elements);
+  bool HasIndexedPropertiesInExternalArrayData();
+  void* GetIndexedPropertiesExternalArrayData();
+  ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
+  int GetIndexedPropertiesExternalArrayDataLength();
 
   /**
    * Checks whether a callback is set by the
    * ObjectTemplate::SetCallAsFunctionHandler method.
    * When an Object is callable this method returns true.
    */
-  V8EXPORT bool IsCallable();
+  bool IsCallable();
 
   /**
    * Call an Object as a function if a callback is set by the
    * ObjectTemplate::SetCallAsFunctionHandler method.
    */
-  V8EXPORT Local<Value> CallAsFunction(Handle<Object> recv,
-                                       int argc,
-                                       Handle<Value> argv[]);
+  Local<Value> CallAsFunction(Handle<Object> recv,
+                              int argc,
+                              Handle<Value> argv[]);
 
   /**
    * Call an Object as a constructor if a callback is set by the
    * ObjectTemplate::SetCallAsFunctionHandler method.
    * Note: This method behaves like the Function::NewInstance method.
    */
-  V8EXPORT Local<Value> CallAsConstructor(int argc,
-                                          Handle<Value> argv[]);
+  Local<Value> CallAsConstructor(int argc, Handle<Value> argv[]);
 
-  V8EXPORT static Local<Object> New();
+  static Local<Object> New();
   V8_INLINE(static Object* Cast(Value* obj));
 
  private:
-  V8EXPORT Object();
-  V8EXPORT static void CheckCast(Value* obj);
-  V8EXPORT Local<Value> SlowGetInternalField(int index);
-  V8EXPORT void* SlowGetAlignedPointerFromInternalField(int index);
+  Object();
+  static void CheckCast(Value* obj);
+  Local<Value> SlowGetInternalField(int index);
+  void* SlowGetAlignedPointerFromInternalField(int index);
 };
 
 
 /**
  * An instance of the built-in array constructor (ECMA-262, 15.4.2).
  */
-class Array : public Object {
+class V8EXPORT Array : public Object {
  public:
-  V8EXPORT uint32_t Length() const;
+  uint32_t Length() const;
 
   /**
    * Clones an element at index |index|.  Returns an empty
    * handle if cloning fails (for any reason).
    */
-  V8EXPORT Local<Object> CloneElementAt(uint32_t index);
+  Local<Object> CloneElementAt(uint32_t index);
 
   /**
    * Creates a JavaScript array with the given length. If the length
    * is negative the returned array will have length 0.
    */
-  V8EXPORT static Local<Array> New(int length = 0);
+  static Local<Array> New(int length = 0);
 
   V8_INLINE(static Array* Cast(Value* obj));
  private:
-  V8EXPORT Array();
-  V8EXPORT static void CheckCast(Value* obj);
+  Array();
+  static void CheckCast(Value* obj);
 };
 
 
 /**
  * A JavaScript function object (ECMA-262, 15.3).
  */
-class Function : public Object {
+class V8EXPORT Function : public Object {
  public:
-  V8EXPORT Local<Object> NewInstance() const;
-  V8EXPORT Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
-  V8EXPORT Local<Value> Call(Handle<Object> recv,
-                             int argc,
-                             Handle<Value> argv[]);
-  V8EXPORT void SetName(Handle<String> name);
-  V8EXPORT Handle<Value> GetName() const;
+  Local<Object> NewInstance() const;
+  Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
+  Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]);
+  void SetName(Handle<String> name);
+  Handle<Value> GetName() const;
 
   /**
    * Name inferred from variable or property assignment of this function.
@@ -1837,41 +1826,41 @@
    * in an OO style, where many functions are anonymous but are assigned
    * to object properties.
    */
-  V8EXPORT Handle<Value> GetInferredName() const;
+  Handle<Value> GetInferredName() const;
 
   /**
    * Returns zero based line number of function body and
    * kLineOffsetNotFound if no information available.
    */
-  V8EXPORT int GetScriptLineNumber() const;
+  int GetScriptLineNumber() const;
   /**
    * Returns zero based column number of function body and
    * kLineOffsetNotFound if no information available.
    */
-  V8EXPORT int GetScriptColumnNumber() const;
-  V8EXPORT Handle<Value> GetScriptId() const;
-  V8EXPORT ScriptOrigin GetScriptOrigin() const;
+  int GetScriptColumnNumber() const;
+  Handle<Value> GetScriptId() const;
+  ScriptOrigin GetScriptOrigin() const;
   V8_INLINE(static Function* Cast(Value* obj));
-  V8EXPORT static const int kLineOffsetNotFound;
+  static const int kLineOffsetNotFound;
 
  private:
-  V8EXPORT Function();
-  V8EXPORT static void CheckCast(Value* obj);
+  Function();
+  static void CheckCast(Value* obj);
 };
 
 
 /**
  * An instance of the built-in Date constructor (ECMA-262, 15.9).
  */
-class Date : public Object {
+class V8EXPORT Date : public Object {
  public:
-  V8EXPORT static Local<Value> New(double time);
+  static Local<Value> New(double time);
 
   /**
    * A specialization of Value::NumberValue that is more efficient
    * because we know the structure of this object.
    */
-  V8EXPORT double NumberValue() const;
+  double NumberValue() const;
 
   V8_INLINE(static Date* Cast(v8::Value* obj));
 
@@ -1887,74 +1876,74 @@
    * This API should not be called more than needed as it will
    * negatively impact the performance of date operations.
    */
-  V8EXPORT static void DateTimeConfigurationChangeNotification();
+  static void DateTimeConfigurationChangeNotification();
 
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A Number object (ECMA-262, 4.3.21).
  */
-class NumberObject : public Object {
+class V8EXPORT NumberObject : public Object {
  public:
-  V8EXPORT static Local<Value> New(double value);
+  static Local<Value> New(double value);
 
   /**
    * Returns the Number held by the object.
    */
-  V8EXPORT double NumberValue() const;
+  double NumberValue() const;
 
   V8_INLINE(static NumberObject* Cast(v8::Value* obj));
 
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A Boolean object (ECMA-262, 4.3.15).
  */
-class BooleanObject : public Object {
+class V8EXPORT BooleanObject : public Object {
  public:
-  V8EXPORT static Local<Value> New(bool value);
+  static Local<Value> New(bool value);
 
   /**
    * Returns the Boolean held by the object.
    */
-  V8EXPORT bool BooleanValue() const;
+  bool BooleanValue() const;
 
   V8_INLINE(static BooleanObject* Cast(v8::Value* obj));
 
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * A String object (ECMA-262, 4.3.18).
  */
-class StringObject : public Object {
+class V8EXPORT StringObject : public Object {
  public:
-  V8EXPORT static Local<Value> New(Handle<String> value);
+  static Local<Value> New(Handle<String> value);
 
   /**
    * Returns the String held by the object.
    */
-  V8EXPORT Local<String> StringValue() const;
+  Local<String> StringValue() const;
 
   V8_INLINE(static StringObject* Cast(v8::Value* obj));
 
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
 /**
  * An instance of the built-in RegExp constructor (ECMA-262, 15.10).
  */
-class RegExp : public Object {
+class V8EXPORT RegExp : public Object {
  public:
   /**
    * Regular expression flag bits. They can be or'ed to enable a set
@@ -1977,24 +1966,23 @@
    *               static_cast<RegExp::Flags>(kGlobal | kMultiline))
    * is equivalent to evaluating "/foo/gm".
    */
-  V8EXPORT static Local<RegExp> New(Handle<String> pattern,
-                                    Flags flags);
+  static Local<RegExp> New(Handle<String> pattern, Flags flags);
 
   /**
    * Returns the value of the source property: a string representing
    * the regular expression.
    */
-  V8EXPORT Local<String> GetSource() const;
+  Local<String> GetSource() const;
 
   /**
    * Returns the flags bit field.
    */
-  V8EXPORT Flags GetFlags() const;
+  Flags GetFlags() const;
 
   V8_INLINE(static RegExp* Cast(v8::Value* obj));
 
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
@@ -2002,19 +1990,13 @@
  * A JavaScript value that wraps a C++ void*. This type of value is mainly used
  * to associate C++ data structures with JavaScript objects.
  */
-class External : public Value {
+class V8EXPORT External : public Value {
  public:
-  /** Deprecated, use New instead. */
-  V8_DEPRECATED(V8_INLINE(static Local<Value> Wrap(void* value)));
-
-  /** Deprecated, use a combination of Cast and Value instead. */
-  V8_DEPRECATED(V8_INLINE(static void* Unwrap(Handle<Value> obj)));
-
-  V8EXPORT static Local<External> New(void* value);
+  static Local<External> New(void* value);
   V8_INLINE(static External* Cast(Value* obj));
-  V8EXPORT void* Value() const;
+  void* Value() const;
  private:
-  V8EXPORT static void CheckCast(v8::Value* obj);
+  static void CheckCast(v8::Value* obj);
 };
 
 
@@ -2044,7 +2026,7 @@
  * including the receiver, the number and values of arguments, and
  * the holder of the function.
  */
-class Arguments {
+class V8EXPORT Arguments {
  public:
   V8_INLINE(int Length() const);
   V8_INLINE(Local<Value> operator[](int i) const);
@@ -2944,7 +2926,7 @@
 };
 
 
-class StartupData {
+class V8EXPORT StartupData {
  public:
   enum CompressionAlgorithm {
     kUncompressed,
@@ -3562,9 +3544,6 @@
   static bool IsGlobalWeak(internal::Object** global_handle);
   static bool IsGlobalWeak(internal::Isolate* isolate,
                            internal::Object** global_handle);
-  static void SetWrapperClassId(internal::Object** global_handle,
-                                uint16_t class_id);
-  static uint16_t GetWrapperClassId(internal::Object** global_handle);
 
   template <class T> friend class Handle;
   template <class T> friend class Local;
@@ -3817,17 +3796,8 @@
   /** Returns true if V8 has a current context. */
   static bool InContext();
 
-  /**
-   * Gets embedder data with index 0. Deprecated, use GetEmbedderData with index
-   * 0 instead.
-   */
-  V8_DEPRECATED(V8_INLINE(Local<Value> GetData()));
-
-  /**
-   * Sets embedder data with index 0. Deprecated, use SetEmbedderData with index
-   * 0 instead.
-   */
-  V8_DEPRECATED(V8_INLINE(void SetData(Handle<Value> value)));
+  /** Returns an isolate associated with a current context. */
+  v8::Isolate* GetIsolate();
 
   /**
    * Gets the embedder data with the given index, which must have been set by a
@@ -3912,21 +3882,19 @@
 
 
 /**
- * Multiple threads in V8 are allowed, but only one thread at a time
- * is allowed to use any given V8 isolate. See Isolate class
- * comments. The definition of 'using V8 isolate' includes
- * accessing handles or holding onto object pointers obtained
- * from V8 handles while in the particular V8 isolate.  It is up
- * to the user of V8 to ensure (perhaps with locking) that this
- * constraint is not violated.  In addition to any other synchronization
- * mechanism that may be used, the v8::Locker and v8::Unlocker classes
- * must be used to signal thead switches to V8.
+ * Multiple threads in V8 are allowed, but only one thread at a time is allowed
+ * to use any given V8 isolate, see the comments in the Isolate class. The
+ * definition of 'using a V8 isolate' includes accessing handles or holding onto
+ * object pointers obtained from V8 handles while in the particular V8 isolate.
+ * It is up to the user of V8 to ensure, perhaps with locking, that this
+ * constraint is not violated. In addition to any other synchronization
+ * mechanism that may be used, the v8::Locker and v8::Unlocker classes must be
+ * used to signal thead switches to V8.
  *
- * v8::Locker is a scoped lock object. While it's
- * active (i.e. between its construction and destruction) the current thread is
- * allowed to use the locked isolate. V8 guarantees that an isolate can be
- * locked by at most one thread at any time. In other words, the scope of a
- * v8::Locker is a critical section.
+ * v8::Locker is a scoped lock object. While it's active, i.e. between its
+ * construction and destruction, the current thread is allowed to use the locked
+ * isolate. V8 guarantees that an isolate can be locked by at most one thread at
+ * any time. In other words, the scope of a v8::Locker is a critical section.
  *
  * Sample usage:
 * \code
@@ -3940,9 +3908,9 @@
  * } // Destructor called here
  * \endcode
  *
- * If you wish to stop using V8 in a thread A you can do this either
- * by destroying the v8::Locker object as above or by constructing a
- * v8::Unlocker object:
+ * If you wish to stop using V8 in a thread A you can do this either by
+ * destroying the v8::Locker object as above or by constructing a v8::Unlocker
+ * object:
  *
  * \code
  * {
@@ -3955,19 +3923,17 @@
  * isolate->Enter();
  * \endcode
  *
- * The Unlocker object is intended for use in a long-running callback
- * from V8, where you want to release the V8 lock for other threads to
- * use.
+ * The Unlocker object is intended for use in a long-running callback from V8,
+ * where you want to release the V8 lock for other threads to use.
  *
- * The v8::Locker is a recursive lock.  That is, you can lock more than
- * once in a given thread.  This can be useful if you have code that can
- * be called either from code that holds the lock or from code that does
- * not.  The Unlocker is not recursive so you can not have several
- * Unlockers on the stack at once, and you can not use an Unlocker in a
- * thread that is not inside a Locker's scope.
+ * The v8::Locker is a recursive lock, i.e. you can lock more than once in a
+ * given thread. This can be useful if you have code that can be called either
+ * from code that holds the lock or from code that does not. The Unlocker is
+ * not recursive so you can not have several Unlockers on the stack at once, and
+ * you can not use an Unlocker in a thread that is not inside a Locker's scope.
  *
- * An unlocker will unlock several lockers if it has to and reinstate
- * the correct depth of locking on its destruction. eg.:
+ * An unlocker will unlock several lockers if it has to and reinstate the
+ * correct depth of locking on its destruction, e.g.:
  *
  * \code
  * // V8 not locked.
@@ -3990,17 +3956,23 @@
  * }
  * // V8 Now no longer locked.
  * \endcode
- *
- *
  */
 class V8EXPORT Unlocker {
  public:
   /**
-   * Initialize Unlocker for a given Isolate. NULL means default isolate.
+   * Initialize Unlocker for a given Isolate.
    */
-  explicit Unlocker(Isolate* isolate = NULL);
+  V8_INLINE(explicit Unlocker(Isolate* isolate)) { Initialize(isolate); }
+
+  /**
+   * Deprecated. Use Isolate version instead.
+   */
+  V8_DEPRECATED(Unlocker());
+
   ~Unlocker();
  private:
+  void Initialize(Isolate* isolate);
+
   internal::Isolate* isolate_;
 };
 
@@ -4008,9 +3980,15 @@
 class V8EXPORT Locker {
  public:
   /**
-   * Initialize Locker for a given Isolate. NULL means default isolate.
+   * Initialize Locker for a given Isolate.
    */
-  explicit Locker(Isolate* isolate = NULL);
+  V8_INLINE(explicit Locker(Isolate* isolate)) { Initialize(isolate); }
+
+  /**
+   * Deprecated. Use Isolate version instead.
+   */
+  V8_DEPRECATED(Locker());
+
   ~Locker();
 
   /**
@@ -4028,10 +4006,10 @@
   static void StopPreemption();
 
   /**
-   * Returns whether or not the locker for a given isolate, or default isolate
-   * if NULL is given, is locked by the current thread.
+   * Returns whether or not the locker for a given isolate, is locked by the
+   * current thread.
    */
-  static bool IsLocked(Isolate* isolate = NULL);
+  static bool IsLocked(Isolate* isolate);
 
   /**
    * Returns whether v8::Locker is being used by this V8 instance.
@@ -4039,6 +4017,8 @@
   static bool IsActive();
 
  private:
+  void Initialize(Isolate* isolate);
+
   bool has_lock_;
   bool top_level_;
   internal::Isolate* isolate_;
@@ -4185,12 +4165,17 @@
   static const int kIsolateStateOffset = 0;
   static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
   static const int kIsolateRootsOffset = 3 * kApiPointerSize;
+  static const int kNodeClassIdOffset = 1 * kApiPointerSize;
+  static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
   static const int kUndefinedValueRootIndex = 5;
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
   static const int kEmptySymbolRootIndex = 119;
 
+  static const int kNodeIsIndependentShift = 4;
+  static const int kNodeIsPartiallyDependentShift = 5;
+
   static const int kJSObjectType = 0xab;
   static const int kFirstNonstringType = 0x80;
   static const int kOddballType = 0x82;
@@ -4229,6 +4214,18 @@
     return *reinterpret_cast<int*>(addr) == 1;
   }
 
+  V8_INLINE(static uint8_t GetNodeFlag(internal::Object** obj, int shift)) {
+      uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
+      return *addr & (1 << 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 = 1 << shift;
+      *addr = (*addr & ~mask) | (value << shift);
+  }
+
   V8_INLINE(static void SetEmbedderData(v8::Isolate* isolate, void* data)) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
         kIsolateEmbedderDataOffset;
@@ -4322,9 +4319,11 @@
 
 template <class T>
 bool Persistent<T>::IsIndependent(Isolate* isolate) const {
+  typedef internal::Internals I;
   if (this->IsEmpty()) return false;
-  return V8::IsGlobalIndependent(reinterpret_cast<internal::Isolate*>(isolate),
-                                 reinterpret_cast<internal::Object**>(**this));
+  if (!I::IsInitialized(isolate)) return false;
+  return I::GetNodeFlag(reinterpret_cast<internal::Object**>(**this),
+                        I::kNodeIsIndependentShift);
 }
 
 
@@ -4396,8 +4395,11 @@
 
 template <class T>
 void Persistent<T>::MarkIndependent(Isolate* isolate) {
-  V8::MarkIndependent(reinterpret_cast<internal::Isolate*>(isolate),
-                      reinterpret_cast<internal::Object**>(**this));
+  typedef internal::Internals I;
+  if (this->IsEmpty()) return;
+  if (!I::IsInitialized(isolate)) return;
+  I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
+                    true, I::kNodeIsIndependentShift);
 }
 
 template <class T>
@@ -4407,18 +4409,27 @@
 
 template <class T>
 void Persistent<T>::MarkPartiallyDependent(Isolate* isolate) {
-  V8::MarkPartiallyDependent(reinterpret_cast<internal::Isolate*>(isolate),
-                             reinterpret_cast<internal::Object**>(**this));
+  typedef internal::Internals I;
+  if (this->IsEmpty()) return;
+  if (!I::IsInitialized(isolate)) return;
+  I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
+                    true, I::kNodeIsPartiallyDependentShift);
 }
 
 template <class T>
 void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
-  V8::SetWrapperClassId(reinterpret_cast<internal::Object**>(**this), class_id);
+  typedef internal::Internals I;
+  internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
+  uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
+  *reinterpret_cast<uint16_t*>(addr) = class_id;
 }
 
 template <class T>
 uint16_t Persistent<T>::WrapperClassId() const {
-  return V8::GetWrapperClassId(reinterpret_cast<internal::Object**>(**this));
+  typedef internal::Internals I;
+  internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
+  uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
+  return *reinterpret_cast<uint16_t*>(addr);
 }
 
 Arguments::Arguments(internal::Object** implicit_args,
@@ -4523,11 +4534,6 @@
 }
 
 
-void Object::SetPointerInInternalField(int index, void* value) {
-  SetInternalField(index, External::New(value));
-}
-
-
 void* Object::GetAlignedPointerFromInternalField(int index) {
 #ifndef V8_ENABLE_CHECKS
   typedef internal::Object O;
@@ -4732,16 +4738,6 @@
 }
 
 
-Local<Value> External::Wrap(void* value) {
-  return External::New(value);
-}
-
-
-void* External::Unwrap(Handle<v8::Value> obj) {
-  return External::Cast(*obj)->Value();
-}
-
-
 External* External::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
@@ -4818,15 +4814,6 @@
 }
 
 
-Local<Value> Context::GetData() {
-  return GetEmbedderData(0);
-}
-
-void Context::SetData(Handle<Value> data) {
-  SetEmbedderData(0, data);
-}
-
-
 Local<Value> Context::GetEmbedderData(int index) {
 #ifndef V8_ENABLE_CHECKS
   typedef internal::Object O;
diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc
index 26e787f..4fc28b7 100644
--- a/samples/lineprocessor.cc
+++ b/samples/lineprocessor.cc
@@ -214,7 +214,7 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
   debug_message_context = v8::Persistent<v8::Context>::New(context);
 
-  v8::Locker locker;
+  v8::Locker locker(v8::Isolate::GetCurrent());
 
   if (support_callback) {
     v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
@@ -265,7 +265,7 @@
 bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
                  bool report_exceptions) {
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  v8::Locker lock;
+  v8::Locker lock(v8::Isolate::GetCurrent());
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
   v8::Handle<v8::String> fun_name = v8::String::New("ProcessLine");
@@ -420,7 +420,7 @@
   char* res;
   {
 #ifdef ENABLE_DEBUGGER_SUPPORT
-    v8::Unlocker unlocker;
+    v8::Unlocker unlocker(v8::Isolate::GetCurrent());
 #endif  // ENABLE_DEBUGGER_SUPPORT
     res = fgets(buffer, kBufferSize, stdin);
   }
diff --git a/src/SConscript b/src/SConscript
index 16bfb55..2fa8874 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -89,7 +89,6 @@
     hydrogen.cc
     ic.cc
     incremental-marking.cc
-    inspector.cc
     interface.cc
     interpreter-irregexp.cc
     isolate.cc
@@ -97,7 +96,6 @@
     lithium-allocator.cc
     lithium.cc
     liveedit.cc
-    liveobjectlist.cc
     log-utils.cc
     log.cc
     mark-compact.cc
diff --git a/src/api.cc b/src/api.cc
index 0563443..54b233c 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -668,13 +668,6 @@
 }
 
 
-void V8::MarkIndependent(i::Isolate* isolate, i::Object** object) {
-  ASSERT(isolate == i::Isolate::Current());
-  LOG_API(isolate, "MarkIndependent");
-  isolate->global_handles()->MarkIndependent(object);
-}
-
-
 void V8::MarkPartiallyDependent(i::Object** object) {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "MarkPartiallyDependent");
@@ -682,13 +675,6 @@
 }
 
 
-void V8::MarkPartiallyDependent(i::Isolate* isolate, i::Object** object) {
-  ASSERT(isolate == i::Isolate::Current());
-  LOG_API(isolate, "MarkPartiallyDependent");
-  isolate->global_handles()->MarkPartiallyDependent(object);
-}
-
-
 bool V8::IsGlobalIndependent(i::Object** obj) {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "IsGlobalIndependent");
@@ -697,14 +683,6 @@
 }
 
 
-bool V8::IsGlobalIndependent(i::Isolate* isolate, i::Object** obj) {
-  ASSERT(isolate == i::Isolate::Current());
-  LOG_API(isolate, "IsGlobalIndependent");
-  if (!isolate->IsInitialized()) return false;
-  return i::GlobalHandles::IsIndependent(obj);
-}
-
-
 bool V8::IsGlobalNearDeath(i::Object** obj) {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "IsGlobalNearDeath");
@@ -1862,8 +1840,7 @@
     if (!raw_obj->IsJSObject()) return v8::Local<Value>();
     i::HandleScope scope(isolate_);
     i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
-    i::Handle<i::String> name =
-        isolate_->factory()->LookupOneByteSymbol(STATIC_ASCII_VECTOR("stack"));
+    i::Handle<i::String> name = isolate_->factory()->stack_symbol();
     if (!obj->HasProperty(*name)) return v8::Local<Value>();
     i::Handle<i::Object> value = i::GetProperty(obj, name);
     if (value.is_null()) return v8::Local<Value>();
@@ -3893,6 +3870,15 @@
 }
 
 
+bool String::IsOneByte() const {
+  i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(), "v8::String::IsOneByte()")) {
+    return false;
+  }
+  return str->IsOneByteConvertible();
+}
+
+
 class Utf8LengthVisitor {
  public:
   explicit Utf8LengthVisitor()
@@ -4194,18 +4180,20 @@
 }
 
 
-int String::Write(uint16_t* buffer,
-                  int start,
-                  int length,
-                  int options) const {
-  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+template<typename CharType>
+static inline int WriteHelper(const String* string,
+                              CharType* buffer,
+                              int start,
+                              int length,
+                              int options) {
+  i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
   LOG_API(isolate, "String::Write");
   ENTER_V8(isolate);
   ASSERT(start >= 0 && length >= -1);
-  i::Handle<i::String> str = Utils::OpenHandle(this);
+  i::Handle<i::String> str = Utils::OpenHandle(string);
   isolate->string_tracker()->RecordWrite(str);
-  if (options & HINT_MANY_WRITES_EXPECTED) {
+  if (options & String::HINT_MANY_WRITES_EXPECTED) {
     // Flatten the string for efficiency.  This applies whether we are
     // using StringCharacterStream or Get(i) to access the characters.
     FlattenString(str);
@@ -4215,7 +4203,7 @@
     end = str->length();
   if (end < 0) return 0;
   i::String::WriteToFlat(*str, buffer, start, end);
-  if (!(options & NO_NULL_TERMINATION) &&
+  if (!(options & String::NO_NULL_TERMINATION) &&
       (length == -1 || end - start < length)) {
     buffer[end - start] = '\0';
   }
@@ -4223,6 +4211,22 @@
 }
 
 
+int String::WriteOneByte(uint8_t* buffer,
+                         int start,
+                         int length,
+                         int options) const {
+  return WriteHelper(this, buffer, start, length, options);
+}
+
+
+int String::Write(uint16_t* buffer,
+                  int start,
+                  int length,
+                  int options) const {
+  return WriteHelper(this, buffer, start, length, options);
+}
+
+
 bool v8::String::IsExternal() const {
   i::Handle<i::String> str = Utils::OpenHandle(this);
   if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
@@ -4407,14 +4411,6 @@
 }
 
 
-void* Object::GetPointerFromInternalField(int index) {
-  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-  const char* location = "v8::Object::GetPointerFromInternalField()";
-  if (!InternalFieldOK(obj, index, location)) return NULL;
-  return ExternalValue(obj->GetInternalField(index));
-}
-
-
 // --- E n v i r o n m e n t ---
 
 
@@ -4684,6 +4680,12 @@
 }
 
 
+v8::Isolate* Context::GetIsolate() {
+  i::Handle<i::Context> env = Utils::OpenHandle(this);
+  return reinterpret_cast<Isolate*>(env->GetIsolate());
+}
+
+
 v8::Local<v8::Context> Context::GetEntered() {
   i::Isolate* isolate = i::Isolate::Current();
   if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
@@ -4803,16 +4805,6 @@
 }
 
 
-void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
-  i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
-}
-
-
-uint16_t V8::GetWrapperClassId(internal::Object** global_handle) {
-  return i::GlobalHandles::GetWrapperClassId(global_handle);
-}
-
-
 Local<v8::Object> ObjectTemplate::NewInstance() {
   i::Isolate* isolate = i::Isolate::Current();
   ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index e5c1c3e..521231c 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -344,7 +344,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
-    AllocationSiteInfoMode allocation_site_info_mode,
+    AllocationSiteMode allocation_site_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -358,9 +358,10 @@
         ? FixedDoubleArray::SizeFor(length)
         : FixedArray::SizeFor(length);
   }
+
   int size = JSArray::kSize;
   int allocation_info_start = size;
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     size += AllocationSiteInfo::kSize;
   }
   size += elements_size;
@@ -373,7 +374,7 @@
   }
   __ AllocateInNewSpace(size, r0, r1, r2, fail, flags);
 
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ mov(r2, Operand(Handle<Map>(masm->isolate()->heap()->
                                    allocation_site_info_map())));
     __ str(r2, FieldMemOperand(r0, allocation_info_start));
@@ -392,7 +393,7 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
-    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
       __ add(r2, r0, Operand(JSArray::kSize + AllocationSiteInfo::kSize));
     } else {
       __ add(r2, r0, Operand(JSArray::kSize));
@@ -423,22 +424,14 @@
   __ b(eq, &slow_case);
 
   FastCloneShallowArrayStub::Mode mode = mode_;
-  AllocationSiteInfoMode allocation_site_info_mode =
-      DONT_TRACK_ALLOCATION_SITE_INFO;
-  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
-    mode = CLONE_ANY_ELEMENTS;
-    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
-  }
-
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ ldr(r0, FieldMemOperand(r3, JSArray::kElementsOffset));
     __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
     __ CompareRoot(r0, Heap::kFixedCOWArrayMapRootIndex);
     __ b(ne, &check_fast_elements);
-    GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, 0, COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     // Return and remove the on-stack parameters.
     __ add(sp, sp, Operand(3 * kPointerSize));
@@ -447,9 +440,8 @@
     __ bind(&check_fast_elements);
     __ CompareRoot(r0, Heap::kFixedArrayMapRootIndex);
     __ b(ne, &double_elements);
-    GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, length_, CLONE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     // Return and remove the on-stack parameters.
     __ add(sp, sp, Operand(3 * kPointerSize));
@@ -483,7 +475,8 @@
   }
 
   GenerateFastCloneShallowArrayCommon(masm, length_, mode,
-                                      allocation_site_info_mode, &slow_case);
+                                      allocation_site_mode_,
+                                      &slow_case);
 
   // Return and remove the on-stack parameters.
   __ add(sp, sp, Operand(3 * kPointerSize));
@@ -6607,6 +6600,11 @@
   __ tst(r4, Operand(kAsciiDataHintMask));
   __ tst(r5, Operand(kAsciiDataHintMask), ne);
   __ b(ne, &ascii_data);
+  __ eor(r4, r4, Operand(r5));
+  STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
+  __ and_(r4, r4, Operand(kOneByteStringTag | kAsciiDataHintTag));
+  __ cmp(r4, Operand(kOneByteStringTag | kAsciiDataHintTag));
+  __ b(eq, &ascii_data);
 
   // Allocate a two byte cons string.
   __ AllocateTwoByteConsString(r7, r6, r4, r5, &call_runtime);
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 9d00823..2146a0e 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -144,7 +144,8 @@
 #define __ ACCESS_MASM(masm)
 
 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
-    MacroAssembler* masm) {
+    MacroAssembler* masm, AllocationSiteMode mode,
+    Label* allocation_site_info_found) {
   // ----------- S t a t e -------------
   //  -- r0    : value
   //  -- r1    : key
@@ -153,6 +154,12 @@
   //  -- r3    : target map, scratch for subsequent call
   //  -- r4    : scratch (elements)
   // -----------------------------------
+  if (mode == TRACK_ALLOCATION_SITE) {
+    ASSERT(allocation_site_info_found != NULL);
+    masm->TestJSArrayForAllocationSiteInfo(r2, r4,
+                                           allocation_site_info_found);
+  }
+
   // Set transitioned map.
   __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
   __ RecordWriteField(r2,
@@ -167,7 +174,7 @@
 
 
 void ElementsTransitionGenerator::GenerateSmiToDouble(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- r0    : value
   //  -- r1    : key
@@ -179,7 +186,7 @@
   Label loop, entry, convert_hole, gc_required, only_change_map, done;
   bool vfp2_supported = CpuFeatures::IsSupported(VFP2);
 
-  if (FLAG_track_allocation_sites) {
+  if (mode == TRACK_ALLOCATION_SITE) {
     masm->TestJSArrayForAllocationSiteInfo(r2, r4, fail);
   }
 
@@ -308,7 +315,7 @@
 
 
 void ElementsTransitionGenerator::GenerateDoubleToObject(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- r0    : value
   //  -- r1    : key
@@ -319,6 +326,10 @@
   // -----------------------------------
   Label entry, loop, convert_hole, gc_required, only_change_map;
 
+  if (mode == TRACK_ALLOCATION_SITE) {
+    masm->TestJSArrayForAllocationSiteInfo(r2, r4, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 6a97201..cb83860 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1719,7 +1719,9 @@
   if (has_fast_elements && constant_elements_values->map() ==
       isolate()->heap()->fixed_cow_array_map()) {
     FastCloneShallowArrayStub stub(
-        FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
+        FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
+        DONT_TRACK_ALLOCATION_SITE,
+        length);
     __ CallStub(&stub);
     __ IncrementCounter(
         isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
@@ -1730,19 +1732,17 @@
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
-    FastCloneShallowArrayStub::Mode mode = has_fast_elements
-      ? FastCloneShallowArrayStub::CLONE_ELEMENTS
-      : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+    FastCloneShallowArrayStub::Mode mode =
+        FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+    AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
+        ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
 
-    // Tracking allocation info allows us to pre-transition later if it makes
-    // sense.
-    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
-        FLAG_track_allocation_sites) {
-      mode = FastCloneShallowArrayStub::
-          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    if (has_fast_elements) {
+      mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
+      allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
     }
 
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     __ CallStub(&stub);
   }
 
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 5e17694..0db63e7 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -1249,7 +1249,9 @@
   // Must return the modified receiver in r0.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                          FAST_DOUBLE_ELEMENTS);
+    ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
     __ mov(r0, r2);
     __ Ret();
     __ bind(&fail);
@@ -1270,7 +1272,9 @@
   // Must return the modified receiver in r0.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS,
+                                                          FAST_ELEMENTS);
+    ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
     __ mov(r0, r2);
     __ Ret();
     __ bind(&fail);
@@ -1406,7 +1410,9 @@
                                          r4,
                                          slow);
   ASSERT(receiver_map.is(r3));  // Transition code expects map in r3
-  ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                        FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
   __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
@@ -1418,7 +1424,9 @@
                                          r4,
                                          slow);
   ASSERT(receiver_map.is(r3));  // Transition code expects map in r3
-  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+  mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
+                                                                   slow);
   __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 
@@ -1432,7 +1440,8 @@
                                          r4,
                                          slow);
   ASSERT(receiver_map.is(r3));  // Transition code expects map in r3
-  ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+  mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
   __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 }
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index f194720..2400bf0 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -682,6 +682,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
+  return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 1b589ce..41639e7 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -93,6 +93,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(DummyUse)                                   \
   V(ElementsKind)                               \
   V(FastLiteral)                                \
   V(FixedArrayBaseLength)                       \
@@ -403,6 +404,15 @@
 };
 
 
+class LDummyUse: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDummyUse(LOperand* value) {
+    inputs_[0] = value;
+  }
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
+};
+
+
 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index c7fe06c..3c8e568 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -5431,6 +5431,8 @@
   Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();
+  AllocationSiteMode allocation_site_mode =
+      instr->hydrogen()->allocation_site_mode();
 
   // Deopt if the array literal boilerplate ElementsKind is of a type different
   // than the expected one. The check isn't necessary if the boilerplate has
@@ -5462,7 +5464,7 @@
     ASSERT(instr->hydrogen()->depth() == 1);
     FastCloneShallowArrayStub::Mode mode =
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   } else if (instr->hydrogen()->depth() > 1) {
     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
@@ -5471,9 +5473,9 @@
   } else {
     FastCloneShallowArrayStub::Mode mode =
         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS
-            ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
-            : FastCloneShallowArrayStub::CLONE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+        ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
+        : FastCloneShallowArrayStub::CLONE_ELEMENTS;
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   }
 }
@@ -5482,10 +5484,14 @@
 void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
                             Register result,
                             Register source,
-                            int* offset) {
+                            int* offset,
+                            AllocationSiteMode mode) {
   ASSERT(!source.is(r2));
   ASSERT(!result.is(r2));
 
+  bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
+      object->map()->CanTrackAllocationSite();
+
   // Only elements backing stores for non-COW arrays need to be copied.
   Handle<FixedArrayBase> elements(object->elements());
   bool has_elements = elements->length() > 0 &&
@@ -5495,8 +5501,13 @@
   // this object and its backing store.
   int object_offset = *offset;
   int object_size = object->map()->instance_size();
-  int elements_offset = *offset + object_size;
   int elements_size = has_elements ? elements->Size() : 0;
+  int elements_offset = *offset + object_size;
+  if (create_allocation_site_info) {
+    elements_offset += AllocationSiteInfo::kSize;
+    *offset += AllocationSiteInfo::kSize;
+  }
+
   *offset += object_size + elements_size;
 
   // Copy object header.
@@ -5521,7 +5532,8 @@
       __ add(r2, result, Operand(*offset));
       __ str(r2, FieldMemOperand(result, total_offset));
       __ LoadHeapObject(source, value_object);
-      EmitDeepCopy(value_object, result, source, offset);
+      EmitDeepCopy(value_object, result, source, offset,
+                   DONT_TRACK_ALLOCATION_SITE);
     } else if (value->IsHeapObject()) {
       __ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
       __ str(r2, FieldMemOperand(result, total_offset));
@@ -5531,6 +5543,14 @@
     }
   }
 
+  // Build Allocation Site Info if desired
+  if (create_allocation_site_info) {
+    __ mov(r2, Operand(Handle<Map>(isolate()->heap()->
+                                   allocation_site_info_map())));
+    __ str(r2, FieldMemOperand(result, object_size));
+    __ str(source, FieldMemOperand(result, object_size + kPointerSize));
+  }
+
   if (has_elements) {
     // Copy elements backing store header.
     __ LoadHeapObject(source, elements);
@@ -5566,7 +5586,8 @@
           __ add(r2, result, Operand(*offset));
           __ str(r2, FieldMemOperand(result, total_offset));
           __ LoadHeapObject(source, value_object);
-          EmitDeepCopy(value_object, result, source, offset);
+          EmitDeepCopy(value_object, result, source, offset,
+                       DONT_TRACK_ALLOCATION_SITE);
         } else if (value->IsHeapObject()) {
           __ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
           __ str(r2, FieldMemOperand(result, total_offset));
@@ -5617,7 +5638,8 @@
   __ bind(&allocated);
   int offset = 0;
   __ LoadHeapObject(r1, instr->hydrogen()->boilerplate());
-  EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset);
+  EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset,
+               instr->hydrogen()->allocation_site_mode());
   ASSERT_EQ(size, offset);
 }
 
@@ -5892,6 +5914,11 @@
 }
 
 
+void LCodeGen::DoDummyUse(LDummyUse* instr) {
+  // Nothing to see here, move on!
+}
+
+
 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   Register object = ToRegister(instr->object());
   Register key = ToRegister(instr->key());
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index f4d8269..8e83547 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -365,7 +365,8 @@
   void EmitDeepCopy(Handle<JSObject> object,
                     Register result,
                     Register source,
-                    int* offset);
+                    int* offset,
+                    AllocationSiteMode mode);
 
   // Emit optimized code for integer division.
   // Inputs are signed.
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index d7ea107..ffa25eb 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -3399,10 +3399,8 @@
     Register scratch2,
     Label* failure) {
   int kFlatAsciiStringMask =
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask;
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
   int kFlatAsciiStringTag = ASCII_STRING_TYPE;
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
   and_(scratch1, first, Operand(kFlatAsciiStringMask));
   and_(scratch2, second, Operand(kFlatAsciiStringMask));
   cmp(scratch1, Operand(kFlatAsciiStringTag));
@@ -3416,10 +3414,8 @@
                                                             Register scratch,
                                                             Label* failure) {
   int kFlatAsciiStringMask =
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask;
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
   int kFlatAsciiStringTag = ASCII_STRING_TYPE;
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
   and_(scratch, type, Operand(kFlatAsciiStringMask));
   cmp(scratch, Operand(kFlatAsciiStringTag));
   b(ne, failure);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index dcc88f7..d1b51e4 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1694,7 +1694,9 @@
                                                &try_holey_map);
         __ mov(r2, receiver);
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         __ jmp(&fast_object);
 
         __ bind(&try_holey_map);
@@ -1705,7 +1707,9 @@
                                                &call_builtin);
         __ mov(r2, receiver);
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         __ bind(&fast_object);
       } else {
         __ CheckFastObjectElements(r3, r3, &call_builtin);
diff --git a/src/builtins.h b/src/builtins.h
index 3ca397e..9a02ad0 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -151,13 +151,13 @@
                                     Code::kNoExtraICState)              \
   V(KeyedLoadIC_PreMonomorphic,     KEYED_LOAD_IC, PREMONOMORPHIC,      \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_Generic,            KEYED_LOAD_IC, MEGAMORPHIC,         \
+  V(KeyedLoadIC_Generic,            KEYED_LOAD_IC, GENERIC,             \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_String,             KEYED_LOAD_IC, MEGAMORPHIC,         \
+  V(KeyedLoadIC_String,             KEYED_LOAD_IC, GENERIC,             \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MEGAMORPHIC,         \
+  V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, GENERIC,             \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MEGAMORPHIC,         \
+  V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, GENERIC,             \
                                     Code::kNoExtraICState)              \
                                                                         \
   V(StoreIC_Initialize,             STORE_IC, UNINITIALIZED,            \
@@ -168,7 +168,7 @@
                                     Code::kNoExtraICState)              \
   V(StoreIC_Megamorphic,            STORE_IC, MEGAMORPHIC,              \
                                     Code::kNoExtraICState)              \
-  V(StoreIC_GlobalProxy,            STORE_IC, MEGAMORPHIC,              \
+  V(StoreIC_GlobalProxy,            STORE_IC, GENERIC,                  \
                                     Code::kNoExtraICState)              \
   V(StoreIC_Initialize_Strict,      STORE_IC, UNINITIALIZED,            \
                                     kStrictMode)                        \
@@ -178,21 +178,21 @@
                                     kStrictMode)                        \
   V(StoreIC_Megamorphic_Strict,     STORE_IC, MEGAMORPHIC,              \
                                     kStrictMode)                        \
-  V(StoreIC_GlobalProxy_Strict,     STORE_IC, MEGAMORPHIC,              \
+  V(StoreIC_GlobalProxy_Strict,     STORE_IC, GENERIC,                  \
                                     kStrictMode)                        \
   V(StoreIC_Setter_ForDeopt,        STORE_IC, MONOMORPHIC,              \
                                     kStrictMode)                        \
                                                                         \
   V(KeyedStoreIC_Initialize,        KEYED_STORE_IC, UNINITIALIZED,      \
                                     Code::kNoExtraICState)              \
-  V(KeyedStoreIC_Generic,           KEYED_STORE_IC, MEGAMORPHIC,        \
+  V(KeyedStoreIC_Generic,           KEYED_STORE_IC, GENERIC,            \
                                     Code::kNoExtraICState)              \
                                                                         \
   V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED,      \
                                     kStrictMode)                        \
-  V(KeyedStoreIC_Generic_Strict,    KEYED_STORE_IC, MEGAMORPHIC,        \
+  V(KeyedStoreIC_Generic_Strict,    KEYED_STORE_IC, GENERIC,            \
                                     kStrictMode)                        \
-  V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MEGAMORPHIC,       \
+  V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, GENERIC,           \
                                      Code::kNoExtraICState)             \
   V(TransitionElementsSmiToDouble,  BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index c7d4c80..7b1d1b4 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -570,15 +570,16 @@
 
 void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
   Label fail;
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(from_, to_);
   ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_));
   if (!FLAG_trace_elements_transitions) {
     if (IsFastSmiOrObjectElementsKind(to_)) {
       if (IsFastSmiOrObjectElementsKind(from_)) {
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm);
+            GenerateMapChangeElementsTransition(masm, mode, &fail);
       } else if (IsFastDoubleElementsKind(from_)) {
         ASSERT(!IsFastSmiElementsKind(to_));
-        ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+        ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
       } else {
         UNREACHABLE();
       }
@@ -588,14 +589,14 @@
                                                        grow_mode_);
     } else if (IsFastSmiElementsKind(from_) &&
                IsFastDoubleElementsKind(to_)) {
-      ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+      ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
       KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
                                                              is_jsarray_,
                                                              grow_mode_);
     } else if (IsFastDoubleElementsKind(from_)) {
       ASSERT(to_ == FAST_HOLEY_DOUBLE_ELEMENTS);
       ElementsTransitionGenerator::
-          GenerateMapChangeElementsTransition(masm);
+          GenerateMapChangeElementsTransition(masm, mode, &fail);
     } else {
       UNREACHABLE();
     }
diff --git a/src/code-stubs.h b/src/code-stubs.h
index a02a959..8cba966 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -427,14 +427,16 @@
     CLONE_DOUBLE_ELEMENTS,
     COPY_ON_WRITE_ELEMENTS,
     CLONE_ANY_ELEMENTS,
-    CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO,
-    LAST_CLONE_MODE = CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO
+    LAST_CLONE_MODE = CLONE_ANY_ELEMENTS
   };
 
   static const int kFastCloneModeCount = LAST_CLONE_MODE + 1;
 
-  FastCloneShallowArrayStub(Mode mode, int length)
+  FastCloneShallowArrayStub(Mode mode,
+                            AllocationSiteMode allocation_site_mode,
+                            int length)
       : mode_(mode),
+        allocation_site_mode_(allocation_site_mode),
         length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
     ASSERT_GE(length_, 0);
     ASSERT_LE(length_, kMaximumClonedLength);
@@ -444,12 +446,21 @@
 
  private:
   Mode mode_;
+  AllocationSiteMode allocation_site_mode_;
   int length_;
 
+  class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
+  class ModeBits: public BitField<Mode, 1, 4> {};
+  class LengthBits: public BitField<int, 5, 4> {};
+  // Ensure data fits within available bits.
+  STATIC_ASSERT(LAST_ALLOCATION_SITE_MODE == 1);
+  STATIC_ASSERT(kFastCloneModeCount < 16);
+  STATIC_ASSERT(kMaximumClonedLength < 16);
   Major MajorKey() { return FastCloneShallowArray; }
   int MinorKey() {
-    ASSERT(mode_ >= 0 && mode_ <= LAST_CLONE_MODE);
-    return length_ * kFastCloneModeCount + mode_;
+    return AllocationSiteModeBits::encode(allocation_site_mode_)
+        | ModeBits::encode(mode_)
+        | LengthBits::encode(length_);
   }
 };
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 2eebef6..b42645c 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -86,12 +86,12 @@
     PrintF(" ***\n");
   }
 
-  if (print_source) {
+  if (!info->IsStub() && print_source) {
     PrintF("--- Source from AST ---\n%s\n",
            PrettyPrinter().PrintProgram(info->function()));
   }
 
-  if (print_ast) {
+  if (!info->IsStub() && print_ast) {
     PrintF("--- AST ---\n%s\n",
            AstPrinter().PrintProgram(info->function()));
   }
diff --git a/src/codegen.h b/src/codegen.h
index 0ac68c2..09907c4 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -96,9 +96,17 @@
 
 class ElementsTransitionGenerator : public AllStatic {
  public:
-  static void GenerateMapChangeElementsTransition(MacroAssembler* masm);
-  static void GenerateSmiToDouble(MacroAssembler* masm, Label* fail);
-  static void GenerateDoubleToObject(MacroAssembler* masm, Label* fail);
+  // If |mode| is set to DONT_TRACK_ALLOCATION_SITE,
+  // |allocation_site_info_found| may be NULL.
+  static void GenerateMapChangeElementsTransition(MacroAssembler* masm,
+      AllocationSiteMode mode,
+      Label* allocation_site_info_found);
+  static void GenerateSmiToDouble(MacroAssembler* masm,
+                                  AllocationSiteMode mode,
+                                  Label* fail);
+  static void GenerateDoubleToObject(MacroAssembler* masm,
+                                     AllocationSiteMode mode,
+                                     Label* fail);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ElementsTransitionGenerator);
diff --git a/src/compiler.cc b/src/compiler.cc
index daeca1e..84ea9c6 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -474,6 +474,13 @@
 #endif
 
 
+static bool DebuggerWantsEagerCompilation(CompilationInfo* info,
+                                          bool allow_lazy_without_ctx = false) {
+  return LiveEditFunctionTracker::IsActive(info->isolate()) ||
+         (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
+}
+
+
 static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
   Isolate* isolate = info->isolate();
   ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
@@ -511,8 +518,9 @@
   // Only allow non-global compiles for eval.
   ASSERT(info->is_eval() || info->is_global());
   ParsingFlags flags = kNoParsingFlags;
-  if (info->pre_parse_data() != NULL ||
-      String::cast(script->source())->length() > FLAG_min_preparse_length) {
+  if ((info->pre_parse_data() != NULL ||
+       String::cast(script->source())->length() > FLAG_min_preparse_length) &&
+      !DebuggerWantsEagerCompilation(info)) {
     flags = kAllowLazy;
   }
   if (!ParserApi::Parse(info, flags)) {
@@ -1006,8 +1014,7 @@
   // Debug::FindSharedFunctionInfoInScript.
   bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
   bool allow_lazy = literal->AllowsLazyCompilation() &&
-      !LiveEditFunctionTracker::IsActive(info.isolate()) &&
-      (!info.isolate()->DebuggerHasBreakPoints() || allow_lazy_without_ctx);
+      !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
 
   Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
 
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index de0faa8..f044328 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -273,7 +273,7 @@
 
 
 void RemoteDebugger::HandleMessageReceived(char* message) {
-  Locker lock;
+  Locker lock(v8::Isolate::GetCurrent());
   HandleScope scope;
 
   // Print the event details.
@@ -302,7 +302,7 @@
 
 
 void RemoteDebugger::HandleKeyboardCommand(char* command) {
-  Locker lock;
+  Locker lock(v8::Isolate::GetCurrent());
   HandleScope scope;
 
   // Convert the debugger command to a JSON debugger request.
diff --git a/src/d8.cc b/src/d8.cc
index b098628..407488f 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -886,7 +886,7 @@
 
 
 Handle<Value> Shell::Yield(const Arguments& args) {
-  v8::Unlocker unlocker;
+  v8::Unlocker unlocker(args.GetIsolate());
   return Undefined();
 }
 
@@ -1093,8 +1093,8 @@
 }
 
 
-void Shell::InstallUtilityScript() {
-  Locker lock;
+void Shell::InstallUtilityScript(Isolate* isolate) {
+  Locker lock(isolate);
   HandleScope scope;
   // If we use the utility context, we have to set the security tokens so that
   // utility, evaluation and debug context can all access each other.
@@ -1235,12 +1235,6 @@
   global_template->Set(String::New("Uint8ClampedArray"),
                        CreateArrayTemplate(Uint8ClampedArray), attr);
 
-#ifdef LIVE_OBJECT_LIST
-  global_template->Set(String::New("lol_is_enabled"), True());
-#else
-  global_template->Set(String::New("lol_is_enabled"), False());
-#endif
-
 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
   Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
   AddOSMethods(os_templ);
@@ -1278,7 +1272,7 @@
 void Shell::InitializeDebugger(Isolate* isolate) {
   if (options.test_shell) return;
 #ifndef V8_SHARED
-  Locker lock;
+  Locker lock(isolate);
   HandleScope scope;
   Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
   utility_context_ = Context::New(NULL, global_template);
@@ -1496,7 +1490,7 @@
 
 
 void Shell::RunShell(Isolate* isolate) {
-  Locker locker;
+  Locker locker(isolate);
   Context::Scope context_scope(evaluation_context_);
   HandleScope outer_scope;
   Handle<String> name = String::New("(d8)");
@@ -1546,7 +1540,7 @@
     }
 
     // Prepare the context for this thread.
-    Locker locker;
+    Locker locker(isolate_);
     HandleScope outer_scope;
     Persistent<Context> thread_context =
         Shell::CreateEvaluationContext(isolate_);
@@ -1845,7 +1839,7 @@
   }
 #endif  // V8_SHARED
   {  // NOLINT
-    Locker lock;
+    Locker lock(isolate);
     HandleScope scope;
     Persistent<Context> context = CreateEvaluationContext(isolate);
     if (options.last_run) {
@@ -1855,7 +1849,7 @@
       // If the interactive debugger is enabled make sure to activate
       // it before running the files passed on the command line.
       if (i::FLAG_debugger) {
-        InstallUtilityScript();
+        InstallUtilityScript(isolate);
       }
 #endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
     }
@@ -1893,7 +1887,7 @@
   }
 
   if (threads.length() > 0 && options.use_preemption) {
-    Locker lock;
+    Locker lock(isolate);
     Locker::StopPreemption();
   }
 #endif  // V8_SHARED
@@ -1940,7 +1934,7 @@
 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
     // Run remote debugger if requested, but never on --test
     if (i::FLAG_remote_debugger && !options.test_shell) {
-      InstallUtilityScript();
+      InstallUtilityScript(isolate);
       RunRemoteDebugger(i::FLAG_debugger_port);
       return 0;
     }
@@ -1953,7 +1947,7 @@
         && !options.test_shell ) {
 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
       if (!i::FLAG_debugger) {
-        InstallUtilityScript();
+        InstallUtilityScript(isolate);
       }
 #endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
       RunShell(isolate);
diff --git a/src/d8.h b/src/d8.h
index 07699e8..63efd66 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -381,7 +381,7 @@
   static i::Mutex* context_mutex_;
 
   static Counter* GetCounter(const char* name, bool is_histogram);
-  static void InstallUtilityScript();
+  static void InstallUtilityScript(Isolate* isolate);
 #endif  // V8_SHARED
   static void Initialize(Isolate* isolate);
   static void InitializeDebugger(Isolate* isolate);
diff --git a/src/d8.js b/src/d8.js
index 819135a..3cb1819 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -123,10 +123,6 @@
 var trace_compile = false;  // Tracing all compile events?
 var trace_debug_json = false; // Tracing all debug json packets?
 var last_cmd = '';
-//var lol_is_enabled;  // Set to true in d8.cc if LIVE_OBJECT_LIST is defined.
-var lol_next_dump_index = 0;
-var kDefaultLolLinesToPrintAtATime = 10;
-var kMaxLolLinesToPrintAtATime = 1000;
 var repeat_cmd_line = '';
 var is_running = true;
 // Global variable used to store whether a handle was requested.
@@ -507,13 +503,6 @@
       this.request_ = void 0;
       break;
 
-    case 'liveobjectlist':
-    case 'lol':
-      if (lol_is_enabled) {
-        this.request_ = this.lolToJSONRequest_(args, is_repeating);
-        break;
-      }
-
     default:
       throw new Error('Unknown command "' + cmd + '"');
   }
@@ -558,53 +547,10 @@
 };
 
 
-// Note: we use detected command repetition as a signal for continuation here.
-DebugRequest.prototype.createLOLRequest = function(command,
-                                                   start_index,
-                                                   lines_to_dump,
-                                                   is_continuation) {
-  if (is_continuation) {
-    start_index = lol_next_dump_index;
-  }
-
-  if (lines_to_dump) {
-    lines_to_dump = parseInt(lines_to_dump);
-  } else {
-    lines_to_dump = kDefaultLolLinesToPrintAtATime;
-  }
-  if (lines_to_dump > kMaxLolLinesToPrintAtATime) {
-    lines_to_dump = kMaxLolLinesToPrintAtATime;
-  }
-
-  // Save the next start_index to dump from:
-  lol_next_dump_index = start_index + lines_to_dump;
-
-  var request = this.createRequest(command);
-  request.arguments = {};
-  request.arguments.start = start_index;
-  request.arguments.count = lines_to_dump;
-
-  return request;
-};
-
-
 // Create a JSON request for the evaluation command.
 DebugRequest.prototype.makeEvaluateJSONRequest_ = function(expression) {
   lookup_handle = null;
 
-  if (lol_is_enabled) {
-    // Check if the expression is a obj id in the form @<obj id>.
-    var obj_id_match = expression.match(/^@([0-9]+)$/);
-    if (obj_id_match) {
-      var obj_id = parseInt(obj_id_match[1]);
-      // Build a dump request.
-      var request = this.createRequest('getobj');
-      request.arguments = {};
-      request.arguments.obj_id = obj_id;
-      return request.toJSONProtocol();
-    }
-  }
-
   // Check if the expression is a handle id in the form #<handle>#.
   var handle_match = expression.match(/^#([0-9]*)#$/);
   if (handle_match) {
@@ -1170,10 +1116,6 @@
     // Build a evaluate request from the text command.
     request = this.createRequest('frame');
     last_cmd = 'info args';
-  } else if (lol_is_enabled &&
-             args && (args == 'liveobjectlist' || args == 'lol')) {
-    // Build a evaluate request from the text command.
-    return this.liveObjectListToJSONRequest_(null);
   } else {
     throw new Error('Invalid info arguments.');
   }
@@ -1224,262 +1166,6 @@
 };
 
 
-// Args: [v[erbose]] [<N>] [i[ndex] <i>] [t[ype] <type>] [sp[ace] <space>]
-DebugRequest.prototype.lolMakeListRequest =
-    function(cmd, args, first_arg_index, is_repeating) {
-
-  var request;
-  var start_index = 0;
-  var dump_limit = void 0;
-  var type_filter = void 0;
-  var space_filter = void 0;
-  var prop_filter = void 0;
-  var is_verbose = false;
-  var i;
-
-  for (i = first_arg_index; i < args.length; i++) {
-    var arg = args[i];
-    // Check for [v[erbose]]:
-    if (arg === 'verbose' || arg === 'v') {
-      // Nothing to do.  This is already implied by args.length > 3.
-      is_verbose = true;
-
-    // Check for [<N>]:
-    } else if (arg.match(/^[0-9]+$/)) {
-      dump_limit = arg;
-      is_verbose = true;
-
-    // Check for i[ndex] <i>:
-    } else if (arg === 'index' || arg === 'i') {
-      i++;
-      if (args.length < i) {
-        throw new Error('Missing index after ' + arg + '.');
-      }
-      start_index = parseInt(args[i]);
-      // The user input start index starts at 1:
-      if (start_index <= 0) {
-        throw new Error('Invalid index ' + args[i] + '.');
-      }
-      start_index -= 1;
-      is_verbose = true;
-
-    // Check for t[ype] <type>:
-    } else if (arg === 'type' || arg === 't') {
-      i++;
-      if (args.length < i) {
-        throw new Error('Missing type after ' + arg + '.');
-      }
-      type_filter = args[i];
-
-    // Check for space <heap space name>:
-    } else if (arg === 'space' || arg === 'sp') {
-      i++;
-      if (args.length < i) {
-        throw new Error('Missing space name after ' + arg + '.');
-      }
-      space_filter = args[i];
-
-    // Check for property <prop name>:
-    } else if (arg === 'property' || arg === 'prop') {
-      i++;
-      if (args.length < i) {
-        throw new Error('Missing property name after ' + arg + '.');
-      }
-      prop_filter = args[i];
-
-    } else {
-      throw new Error('Unknown args at ' + arg + '.');
-    }
-  }
-
-  // Build the verbose request:
-  if (is_verbose) {
-    request = this.createLOLRequest('lol-'+cmd,
-                                    start_index,
-                                    dump_limit,
-                                    is_repeating);
-    request.arguments.verbose = true;
-  } else {
-    request = this.createRequest('lol-'+cmd);
-    request.arguments = {};
-  }
-
-  request.arguments.filter = {};
-  if (type_filter) {
-    request.arguments.filter.type = type_filter;
-  }
-  if (space_filter) {
-    request.arguments.filter.space = space_filter;
-  }
-  if (prop_filter) {
-    request.arguments.filter.prop = prop_filter;
-  }
-
-  return request;
-};
-
-
-function extractObjId(args) {
-  var id = args;
-  id = id.match(/^@([0-9]+)$/);
-  if (id) {
-    id = id[1];
-  } else {
-    throw new Error('Invalid obj id ' + args + '.');
-  }
-  return parseInt(id);
-}
-
-
-DebugRequest.prototype.lolToJSONRequest_ = function(args, is_repeating) {
-  var request;
-  // Use default command if one is not specified:
-  if (!args) {
-    args = 'info';
-  }
-
-  var orig_args = args;
-  var first_arg_index;
-
-  var arg, i;
-  var args = args.split(/\s+/g);
-  var cmd = args[0];
-  var id;
-
-  // Command: <id> [v[erbose]] ...
-  if (cmd.match(/^[0-9]+$/)) {
-    // Convert to the padded list command:
-    // Command: l[ist] <dummy> <id> [v[erbose]] ...
-
-    // Insert the implicit 'list' in front and process as normal:
-    cmd = 'list';
-    args.unshift(cmd);
-  }
-
-  switch(cmd) {
-    // Command: c[apture]
-    case 'capture':
-    case 'c':
-      request = this.createRequest('lol-capture');
-      break;
-
-    // Command: clear|d[elete] <id>|all
-    case 'clear':
-    case 'delete':
-    case 'del': {
-      if (args.length < 2) {
-        throw new Error('Missing argument after ' + cmd + '.');
-      } else if (args.length > 2) {
-        throw new Error('Too many arguments after ' + cmd + '.');
-      }
-      id = args[1];
-      if (id.match(/^[0-9]+$/)) {
-        // Delete a specific lol record:
-        request = this.createRequest('lol-delete');
-        request.arguments = {};
-        request.arguments.id = parseInt(id);
-      } else if (id === 'all') {
-        // Delete all:
-        request = this.createRequest('lol-reset');
-      } else {
-        throw new Error('Invalid argument after ' + cmd + '.');
-      }
-      break;
-    }
-
-    // Command: diff <id1> <id2> [<dump options>]
-    case 'diff':
-      first_arg_index = 3;
-
-    // Command: list <dummy> <id> [<dump options>]
-    case 'list':
-
-    // Command: ret[ainers] <obj id> [<dump options>]
-    case 'retainers':
-    case 'ret':
-    case 'retaining-paths':
-    case 'rp': {
-      if (cmd === 'ret') cmd = 'retainers';
-      else if (cmd === 'rp') cmd = 'retaining-paths';
-
-      if (!first_arg_index) first_arg_index = 2;
-
-      if (args.length < first_arg_index) {
-        throw new Error('Too few arguments after ' + cmd + '.');
-      }
-
-      var request_cmd = (cmd === 'list') ? 'diff':cmd;
-      request = this.lolMakeListRequest(request_cmd,
-                                        args,
-                                        first_arg_index,
-                                        is_repeating);
-
-      if (cmd === 'diff') {
-        request.arguments.id1 = parseInt(args[1]);
-        request.arguments.id2 = parseInt(args[2]);
-      } else if (cmd == 'list') {
-        request.arguments.id1 = 0;
-        request.arguments.id2 = parseInt(args[1]);
-      } else {
-        request.arguments.id = extractObjId(args[1]);
-      }
-      break;
-    }
-
-    // Command: getid
-    case 'getid': {
-      request = this.createRequest('lol-getid');
-      request.arguments = {};
-      request.arguments.address = args[1];
-      break;
-    }
-
-    // Command: inf[o] [<N>]
-    case 'info':
-    case 'inf': {
-      if (args.length > 2) {
-        throw new Error('Too many arguments after ' + cmd + '.');
-      }
-      // Built the info request:
-      request = this.createLOLRequest('lol-info', 0, args[1], is_repeating);
-      break;
-    }
-
-    // Command: path <obj id 1> <obj id 2>
-    case 'path': {
-      request = this.createRequest('lol-path');
-      request.arguments = {};
-      if (args.length > 2) {
-        request.arguments.id1 = extractObjId(args[1]);
-        request.arguments.id2 = extractObjId(args[2]);
-      } else {
-        request.arguments.id1 = 0;
-        request.arguments.id2 = extractObjId(args[1]);
-      }
-      break;
-    }
-
-    // Command: print
-    case 'print': {
-      request = this.createRequest('lol-print');
-      request.arguments = {};
-      request.arguments.id = extractObjId(args[1]);
-      break;
-    }
-
-    // Command: reset
-    case 'reset': {
-      request = this.createRequest('lol-reset');
-      break;
-    }
-
-    default:
-      throw new Error('Invalid arguments.');
-  }
-  return request.toJSONProtocol();
-};
-
-
 // Create a JSON request for the threads command.
 DebugRequest.prototype.threadsCommandToJSONRequest_ = function(args) {
   // Build a threads request from the text command.
@@ -1545,7 +1231,6 @@
   print('inf[o] br[eak]             - prints info about breakpoints in use');
   print('inf[o] ar[gs]              - prints info about arguments of the current function');
   print('inf[o] lo[cals]            - prints info about locals in the current function');
-  print('inf[o] liveobjectlist|lol  - same as \'lol info\'');
   print('');
   print('step [in | next | out| min [step count]]');
   print('c[ontinue]                 - continue executing after a breakpoint');
@@ -1566,49 +1251,6 @@
   print('');
   print('gc                         - runs the garbage collector');
   print('');
-
-  if (lol_is_enabled) {
-    print('liveobjectlist|lol <command> - live object list tracking.');
-    print('  where <command> can be:');
-    print('  c[apture]               - captures a LOL list.');
-    print('  clear|del[ete] <id>|all - clears LOL of id <id>.');
-    print('                            If \'all\' is unspecified instead, will clear all.');
-    print('  diff <id1> <id2> [<dump options>]');
-    print('                          - prints the diff between LOLs id1 and id2.');
-    print('                          - also see <dump options> below.');
-    print('  getid <address>         - gets the obj id for the specified address if available.');
-    print('                            The address must be in hex form prefixed with 0x.');
-    print('  inf[o] [<N>]            - lists summary info of all LOL lists.');
-    print('                            If N is specified, will print N items at a time.');
-    print('  [l[ist]] <id> [<dump options>]');
-    print('                          - prints the listing of objects in LOL id.');
-    print('                          - also see <dump options> below.');
-    print('  reset                   - clears all LOL lists.');
-    print('  ret[ainers] <id> [<dump options>]');
-    print('                          - prints the list of retainers of obj id.');
-    print('                          - also see <dump options> below.');
-    print('  path <id1> <id2>        - prints the retaining path from obj id1 to id2.');
-    print('                            If only one id is specified, will print the path from');
-    print('                            roots to the specified object if available.');
-    print('  print <id>              - prints the obj for the specified obj id if available.');
-    print('');
-    print('  <dump options> includes:');
-    print('     [v[erbose]]            - do verbose dump.');
-    print('     [<N>]                  - dump N items at a time.  Implies verbose dump.');
-    print('                             If unspecified, N will default to '+
-          kDefaultLolLinesToPrintAtATime+'.  Max N is '+
-          kMaxLolLinesToPrintAtATime+'.');
-    print('     [i[ndex] <i>]          - start dump from index i.  Implies verbose dump.');
-    print('     [t[ype] <type>]        - filter by type.');
-    print('     [sp[ace] <space name>] - filter by heap space where <space name> is one of');
-    print('                              { cell, code, lo, map, new, old-data, old-pointer }.');
-    print('');
-    print('     If the verbose option, or an option that implies a verbose dump');
-    print('     is specified, then a verbose dump will requested.  Else, a summary dump');
-    print('     will be requested.');
-    print('');
-  }
-
   print('trace compile');
   // hidden command: trace debug json - toggles tracing of debug json packets
   print('');
@@ -1709,237 +1351,6 @@
 }
 
 
-function decodeLolCaptureResponse(body) {
-  var result;
-  result = 'Captured live object list '+ body.id +
-           ': count '+ body.count + ' size ' + body.size;
-  return result;
-}
-
-
-function decodeLolDeleteResponse(body) {
-  var result;
-  result = 'Deleted live object list '+ body.id;
-  return result;
-}
-
-
-function digitsIn(value) {
-  var digits = 0;
-  if (value === 0) value = 1;
-  while (value >= 1) {
-    digits++;
-    value /= 10;
-  }
-  return digits;
-}
-
-
-function padding(value, max_digits) {
-  var padding_digits = max_digits - digitsIn(value);
-  var padding = '';
-  while (padding_digits > 0) {
-    padding += ' ';
-    padding_digits--;
-  }
-  return padding;
-}
-
-
-function decodeLolInfoResponse(body) {
-  var result;
-  var lists = body.lists;
-  var length = lists.length;
-  var first_index = body.first_index + 1;
-  var has_more = ((first_index + length) <= body.count);
-  result = 'captured live object lists';
-  if (has_more || (first_index != 1)) {
-    result += ' ['+ length +' of '+ body.count +
-              ': starting from '+ first_index +']';
-  }
-  result += ':\n';
-  var max_digits = digitsIn(body.count);
-  var last_count = 0;
-  var last_size = 0;
-  for (var i = 0; i < length; i++) {
-    var entry = lists[i];
-    var count = entry.count;
-    var size = entry.size;
-    var index = first_index + i;
-    result += '  [' + padding(index, max_digits) + index + '] id '+ entry.id +
-              ': count '+ count;
-    if (last_count > 0) {
-      result += '(+' + (count - last_count) + ')';
-    }
-    result += ' size '+ size;
-    if (last_size > 0) {
-      result += '(+' + (size - last_size) + ')';
-    }
-    result += '\n';
-    last_count = count;
-    last_size = size;
-  }
-  result += '  total: '+length+' lists\n';
-  if (has_more) {
-    result += '  -- press <enter> for more --\n';
-  } else {
-    repeat_cmd_line = '';
-  }
-  if (length === 0) result += '  none\n';
-
-  return result;
-}
-
-
-function decodeLolListResponse(body, title) {
-
-  var result;
-  var total_count = body.count;
-  var total_size = body.size;
-  var length;
-  var max_digits;
-  var i;
-  var entry;
-  var index;
-
-  var max_count_digits = digitsIn(total_count);
-  var max_size_digits;
-
-  var summary = body.summary;
-  if (summary) {
-
-    var roots_count = 0;
-    var found_root = body.found_root || 0;
-    var found_weak_root = body.found_weak_root || 0;
-
-    // Print the summary result:
-    result = 'summary of objects:\n';
-    length = summary.length;
-    if (found_root !== 0) {
-      roots_count++;
-    }
-    if (found_weak_root !== 0) {
-      roots_count++;
-    }
-    max_digits = digitsIn(length + roots_count);
-    max_size_digits = digitsIn(total_size);
-
-    index = 1;
-    if (found_root !== 0) {
-      result += '  [' + padding(index, max_digits) + index + '] ' +
-                ' count '+ 1 + padding(0, max_count_digits) +
-                '      '+ padding(0, max_size_digits+1) +
-                ' : <root>\n';
-      index++;
-    }
-    if (found_weak_root !== 0) {
-      result += '  [' + padding(index, max_digits) + index + '] ' +
-                ' count '+ 1 + padding(0, max_count_digits) +
-                '      '+ padding(0, max_size_digits+1) +
-                ' : <weak root>\n';
-      index++;
-    }
-
-    for (i = 0; i < length; i++) {
-      entry = summary[i];
-      var count = entry.count;
-      var size = entry.size;
-      result += '  [' + padding(index, max_digits) + index + '] ' +
-                ' count '+ count + padding(count, max_count_digits) +
-                ' size '+ size + padding(size, max_size_digits) +
-                ' : <' + entry.desc + '>\n';
-      index++;
-    }
-    result += '\n  total count: '+(total_count+roots_count)+'\n';
-    if (body.size) {
-      result += '  total size:  '+body.size+'\n';
-    }
-
-  } else {
-    // Print the full dump result:
-    var first_index = body.first_index + 1;
-    var elements = body.elements;
-    length = elements.length;
-    var has_more = ((first_index + length) <= total_count);
-    result = title;
-    if (has_more || (first_index != 1)) {
-      result += ' ['+ length +' of '+ total_count +
-                ': starting from '+ first_index +']';
-    }
-    result += ':\n';
-    if (length === 0) result += '  none\n';
-    max_digits = digitsIn(length);
-
-    var max_id = 0;
-    var max_size = 0;
-    for (i = 0; i < length; i++) {
-      entry = elements[i];
-      if (entry.id > max_id) max_id = entry.id;
-      if (entry.size > max_size) max_size = entry.size;
-    }
-    var max_id_digits = digitsIn(max_id);
-    max_size_digits = digitsIn(max_size);
-
-    for (i = 0; i < length; i++) {
-      entry = elements[i];
-      index = first_index + i;
-      result += '  ['+ padding(index, max_digits) + index +']';
-      if (entry.id !== 0) {
-        result += ' @' + entry.id + padding(entry.id, max_id_digits) +
-                  ': size ' + entry.size + ', ' +
-                  padding(entry.size, max_size_digits) +  entry.desc + '\n';
-      } else {
-        // Must be a root or weak root:
-        result += ' ' + entry.desc + '\n';
-      }
-    }
-    if (has_more) {
-      result += '  -- press <enter> for more --\n';
-    } else {
-      repeat_cmd_line = '';
-    }
-    if (length === 0) result += '  none\n';
-  }
-
-  return result;
-}
-
-
-function decodeLolDiffResponse(body) {
-  var title = 'objects';
-  return decodeLolListResponse(body, title);
-}
-
-
-function decodeLolRetainersResponse(body) {
-  var title = 'retainers for @' + body.id;
-  return decodeLolListResponse(body, title);
-}
-
-
-function decodeLolPathResponse(body) {
-  return body.path;
-}
-
-
-function decodeLolResetResponse(body) {
-  return 'Reset all live object lists.';
-}
-
-
-function decodeLolGetIdResponse(body) {
-  if (body.id == 0) {
-    return 'Address is invalid, or object has been moved or collected';
-  }
-  return 'obj id is @' + body.id;
-}
-
-
-function decodeLolPrintResponse(body) {
-  return body.dump;
-}
-
-
 // Rounds number 'num' to 'length' decimal places.
 function roundNumber(num, length) {
   var factor = Math.pow(10, length);
@@ -2276,34 +1687,6 @@
         }
         break;
 
-      case 'lol-capture':
-        details.text = decodeLolCaptureResponse(body);
-        break;
-      case 'lol-delete':
-        details.text = decodeLolDeleteResponse(body);
-        break;
-      case 'lol-diff':
-        details.text = decodeLolDiffResponse(body);
-        break;
-      case 'lol-getid':
-        details.text = decodeLolGetIdResponse(body);
-        break;
-      case 'lol-info':
-        details.text = decodeLolInfoResponse(body);
-        break;
-      case 'lol-print':
-        details.text = decodeLolPrintResponse(body);
-        break;
-      case 'lol-reset':
-        details.text = decodeLolResetResponse(body);
-        break;
-      case 'lol-retainers':
-        details.text = decodeLolRetainersResponse(body);
-        break;
-      case 'lol-path':
-        details.text = decodeLolPathResponse(body);
-        break;
-
       default:
         details.text =
             'Response for unknown command \'' + response.command() + '\'' +
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index eef12a9..7787312 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -110,7 +110,6 @@
     }
   },
 };
-var lol_is_enabled = %HasLOLEnabled();
 
 
 // Create a new break point object and add it to the list of break points.
@@ -1437,8 +1436,6 @@
         this.setVariableValueRequest_(request, response);
       } else if (request.command == 'evaluate') {
         this.evaluateRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'getobj') {
-        this.getobjRequest_(request, response);
       } else if (request.command == 'lookup') {
         this.lookupRequest_(request, response);
       } else if (request.command == 'references') {
@@ -1468,28 +1465,6 @@
       } else if (request.command == 'gc') {
         this.gcRequest_(request, response);
 
-      // LiveObjectList tools:
-      } else if (lol_is_enabled && request.command == 'lol-capture') {
-        this.lolCaptureRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-delete') {
-        this.lolDeleteRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-diff') {
-        this.lolDiffRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-getid') {
-        this.lolGetIdRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-info') {
-        this.lolInfoRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-reset') {
-        this.lolResetRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-retainers') {
-        this.lolRetainersRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-path') {
-        this.lolPathRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-print') {
-        this.lolPrintRequest_(request, response);
-      } else if (lol_is_enabled && request.command == 'lol-stats') {
-        this.lolStatsRequest_(request, response);
-
       } else {
         throw new Error('Unknown command "' + request.command + '" in request');
       }
@@ -2191,24 +2166,6 @@
 };
 
 
-DebugCommandProcessor.prototype.getobjRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var obj_id = request.arguments.obj_id;
-
-  // Check for legal arguments.
-  if (IS_UNDEFINED(obj_id)) {
-    return response.failed('Argument "obj_id" missing');
-  }
-
-  // Dump the object.
-  response.body = MakeMirror(%GetLOLObj(obj_id));
-};
-
-
 DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
   if (!request.arguments) {
     return response.failed('Missing arguments');
@@ -2567,86 +2524,6 @@
 };
 
 
-DebugCommandProcessor.prototype.lolCaptureRequest_ =
-    function(request, response) {
-  response.body = %CaptureLOL();
-};
-
-
-DebugCommandProcessor.prototype.lolDeleteRequest_ =
-    function(request, response) {
-  var id = request.arguments.id;
-  var result = %DeleteLOL(id);
-  if (result) {
-    response.body = { id: id };
-  } else {
-    response.failed('Failed to delete: live object list ' + id + ' not found.');
-  }
-};
-
-
-DebugCommandProcessor.prototype.lolDiffRequest_ = function(request, response) {
-  var id1 = request.arguments.id1;
-  var id2 = request.arguments.id2;
-  var verbose = request.arguments.verbose;
-  var filter = request.arguments.filter;
-  if (verbose === true) {
-    var start = request.arguments.start;
-    var count = request.arguments.count;
-    response.body = %DumpLOL(id1, id2, start, count, filter);
-  } else {
-    response.body = %SummarizeLOL(id1, id2, filter);
-  }
-};
-
-
-DebugCommandProcessor.prototype.lolGetIdRequest_ = function(request, response) {
-  var address = request.arguments.address;
-  response.body = {};
-  response.body.id = %GetLOLObjId(address);
-};
-
-
-DebugCommandProcessor.prototype.lolInfoRequest_ = function(request, response) {
-  var start = request.arguments.start;
-  var count = request.arguments.count;
-  response.body = %InfoLOL(start, count);
-};
-
-
-DebugCommandProcessor.prototype.lolResetRequest_ = function(request, response) {
-  %ResetLOL();
-};
-
-
-DebugCommandProcessor.prototype.lolRetainersRequest_ =
-    function(request, response) {
-  var id = request.arguments.id;
-  var verbose = request.arguments.verbose;
-  var start = request.arguments.start;
-  var count = request.arguments.count;
-  var filter = request.arguments.filter;
-
-  response.body = %GetLOLObjRetainers(id, Mirror.prototype, verbose,
-                                      start, count, filter);
-};
-
-
-DebugCommandProcessor.prototype.lolPathRequest_ = function(request, response) {
-  var id1 = request.arguments.id1;
-  var id2 = request.arguments.id2;
-  response.body = {};
-  response.body.path = %GetLOLPath(id1, id2, Mirror.prototype);
-};
-
-
-DebugCommandProcessor.prototype.lolPrintRequest_ = function(request, response) {
-  var id = request.arguments.id;
-  response.body = {};
-  response.body.dump = %PrintLOLObj(id);
-};
-
-
 // Check whether the previously processed command caused the VM to become
 // running.
 DebugCommandProcessor.prototype.isRunning = function() {
diff --git a/src/debug.cc b/src/debug.cc
index 1524349..7baed88 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3767,6 +3767,7 @@
 
 
 void MessageDispatchHelperThread::Run() {
+  Isolate* isolate = Isolate::Current();
   while (true) {
     sem_->Wait();
     {
@@ -3774,8 +3775,8 @@
       already_signalled_ = false;
     }
     {
-      Locker locker;
-      Isolate::Current()->debugger()->CallMessageDispatchHandler();
+      Locker locker(reinterpret_cast<v8::Isolate*>(isolate));
+      isolate->debugger()->CallMessageDispatchHandler();
     }
   }
 }
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index a7a2573..5bf7df3 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -194,6 +194,8 @@
 DEFINE_bool(trace_range, false, "trace range analysis")
 DEFINE_bool(trace_gvn, false, "trace global value numbering")
 DEFINE_bool(trace_representation, false, "trace representation types")
+DEFINE_bool(trace_track_allocation_sites, false,
+            "trace the tracking of allocation sites")
 DEFINE_bool(stress_pointer_maps, false, "pointer map for every instruction")
 DEFINE_bool(stress_environments, false, "environment for every instruction")
 DEFINE_int(deopt_every_n_times,
@@ -419,12 +421,6 @@
 // ic.cc
 DEFINE_bool(use_ic, true, "use inline caching")
 
-#ifdef LIVE_OBJECT_LIST
-// liveobjectlist.cc
-DEFINE_string(lol_workdir, NULL, "path for lol temp files")
-DEFINE_bool(verify_lol, false, "perform debugging verification for lol")
-#endif
-
 // macro-assembler-ia32.cc
 DEFINE_bool(native_code_counters, false,
             "generate extra code for manipulating stats counters")
diff --git a/src/global-handles.cc b/src/global-handles.cc
index 392a181..94ccc28 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -46,7 +46,7 @@
   // State transition diagram:
   // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
   enum State {
-    FREE,
+    FREE = 0,
     NORMAL,     // Normal global handle.
     WEAK,       // Flagged as weak but not yet finalized.
     PENDING,    // Has been recognized as only reachable by weak handles.
@@ -59,7 +59,14 @@
     return reinterpret_cast<Node*>(location);
   }
 
-  Node() {}
+  Node() {
+    ASSERT(OFFSET_OF(Node, flags_) == Internals::kNodeFlagsOffset);
+    ASSERT(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset);
+    ASSERT(static_cast<int>(IsIndependent::kShift) ==
+           Internals::kNodeIsIndependentShift);
+    ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
+           Internals::kNodeIsPartiallyDependentShift);
+  }
 
 #ifdef DEBUG
   ~Node() {
@@ -68,9 +75,9 @@
     object_ = NULL;
     class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
     index_ = 0;
-    independent_ = false;
-    partially_dependent_ = false;
-    in_new_space_list_ = false;
+    set_independent(false);
+    set_partially_dependent(false);
+    set_in_new_space_list(false);
     parameter_or_next_free_.next_free = NULL;
     callback_ = NULL;
   }
@@ -79,33 +86,33 @@
   void Initialize(int index, Node** first_free) {
     index_ = static_cast<uint8_t>(index);
     ASSERT(static_cast<int>(index_) == index);
-    state_ = FREE;
-    in_new_space_list_ = false;
+    set_state(FREE);
+    set_in_new_space_list(false);
     parameter_or_next_free_.next_free = *first_free;
     *first_free = this;
   }
 
   void Acquire(Object* object, GlobalHandles* global_handles) {
-    ASSERT(state_ == FREE);
+    ASSERT(state() == FREE);
     object_ = object;
     class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
-    independent_ = false;
-    partially_dependent_ = false;
-    state_  = NORMAL;
+    set_independent(false);
+    set_partially_dependent(false);
+    set_state(NORMAL);
     parameter_or_next_free_.parameter = NULL;
     callback_ = NULL;
     IncreaseBlockUses(global_handles);
   }
 
   void Release(GlobalHandles* global_handles) {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     if (IsWeakRetainer()) {
       global_handles->number_of_weak_handles_--;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_--;
       }
     }
-    state_ = FREE;
+    set_state(FREE);
     parameter_or_next_free_.next_free = global_handles->first_free_;
     global_handles->first_free_ = this;
     DecreaseBlockUses(global_handles);
@@ -120,115 +127,133 @@
   bool has_wrapper_class_id() const {
     return class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId;
   }
+
   uint16_t wrapper_class_id() const { return class_id_; }
-  void set_wrapper_class_id(uint16_t class_id) {
-    class_id_ = class_id;
+
+  // State and flag accessors.
+
+  State state() const {
+    return NodeState::decode(flags_);
+  }
+  void set_state(State state) {
+    flags_ = NodeState::update(flags_, state);
   }
 
-  // State accessors.
+  bool is_independent() {
+    return IsIndependent::decode(flags_);
+  }
+  void set_independent(bool v) {
+    flags_ = IsIndependent::update(flags_, v);
+  }
 
-  State state() const { return state_; }
+  bool is_partially_dependent() {
+    return IsPartiallyDependent::decode(flags_);
+  }
+  void set_partially_dependent(bool v) {
+    flags_ = IsPartiallyDependent::update(flags_, v);
+  }
+
+  bool is_in_new_space_list() {
+    return IsInNewSpaceList::decode(flags_);
+  }
+  void set_in_new_space_list(bool v) {
+    flags_ = IsInNewSpaceList::update(flags_, v);
+  }
 
   bool IsNearDeath() const {
     // Check for PENDING to ensure correct answer when processing callbacks.
-    return state_ == PENDING || state_ == NEAR_DEATH;
+    return state() == PENDING || state() == NEAR_DEATH;
   }
 
-  bool IsWeak() const { return state_ == WEAK; }
+  bool IsWeak() const { return state() == WEAK; }
 
-  bool IsRetainer() const { return state_ != FREE; }
+  bool IsRetainer() const { return state() != FREE; }
 
-  bool IsStrongRetainer() const { return state_ == NORMAL; }
+  bool IsStrongRetainer() const { return state() == NORMAL; }
 
   bool IsWeakRetainer() const {
-    return state_ == WEAK || state_ == PENDING || state_ == NEAR_DEATH;
+    return state() == WEAK || state() == PENDING || state() == NEAR_DEATH;
   }
 
   void MarkPending() {
-    ASSERT(state_ == WEAK);
-    state_ = PENDING;
+    ASSERT(state() == WEAK);
+    set_state(PENDING);
   }
 
   // Independent flag accessors.
   void MarkIndependent() {
-    ASSERT(state_ != FREE);
-    independent_ = true;
+    ASSERT(state() != FREE);
+    set_independent(true);
   }
-  bool is_independent() const { return independent_; }
 
   void MarkPartiallyDependent(GlobalHandles* global_handles) {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     if (global_handles->isolate()->heap()->InNewSpace(object_)) {
-      partially_dependent_ = true;
+      set_partially_dependent(true);
     }
   }
-  bool is_partially_dependent() const { return partially_dependent_; }
-  void clear_partially_dependent() { partially_dependent_ = false; }
-
-  // In-new-space-list flag accessors.
-  void set_in_new_space_list(bool v) { in_new_space_list_ = v; }
-  bool is_in_new_space_list() const { return in_new_space_list_; }
+  void clear_partially_dependent() { set_partially_dependent(false); }
 
   // Callback accessor.
   WeakReferenceCallback callback() { return callback_; }
 
   // Callback parameter accessors.
   void set_parameter(void* parameter) {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     parameter_or_next_free_.parameter = parameter;
   }
   void* parameter() const {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     return parameter_or_next_free_.parameter;
   }
 
   // Accessors for next free node in the free list.
   Node* next_free() {
-    ASSERT(state_ == FREE);
+    ASSERT(state() == FREE);
     return parameter_or_next_free_.next_free;
   }
   void set_next_free(Node* value) {
-    ASSERT(state_ == FREE);
+    ASSERT(state() == FREE);
     parameter_or_next_free_.next_free = value;
   }
 
   void MakeWeak(GlobalHandles* global_handles,
                 void* parameter,
                 WeakReferenceCallback callback) {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     if (!IsWeakRetainer()) {
       global_handles->number_of_weak_handles_++;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_++;
       }
     }
-    state_ = WEAK;
+    set_state(WEAK);
     set_parameter(parameter);
     callback_ = callback;
   }
 
   void ClearWeakness(GlobalHandles* global_handles) {
-    ASSERT(state_ != FREE);
+    ASSERT(state() != FREE);
     if (IsWeakRetainer()) {
       global_handles->number_of_weak_handles_--;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_--;
       }
     }
-    state_ = NORMAL;
+    set_state(NORMAL);
     set_parameter(NULL);
   }
 
   bool PostGarbageCollectionProcessing(Isolate* isolate,
                                        GlobalHandles* global_handles) {
-    if (state_ != Node::PENDING) return false;
+    if (state() != Node::PENDING) return false;
     WeakReferenceCallback func = callback();
     if (func == NULL) {
       Release(global_handles);
       return false;
     }
     void* par = parameter();
-    state_ = NEAR_DEATH;
+    set_state(NEAR_DEATH);
     set_parameter(NULL);
 
     v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle());
@@ -245,7 +270,7 @@
     }
     // Absence of explicit cleanup or revival of weak handle
     // in most of the cases would lead to memory leak.
-    ASSERT(state_ != NEAR_DEATH);
+    ASSERT(state() != NEAR_DEATH);
     return true;
   }
 
@@ -267,12 +292,14 @@
   // Index in the containing handle block.
   uint8_t index_;
 
-  // Need one more bit for MSVC as it treats enums as signed.
-  State state_ : 4;
+  // This stores three flags (independent, partially_dependent and
+  // in_new_space_list) and a State.
+  class NodeState:            public BitField<State, 0, 4> {};
+  class IsIndependent:        public BitField<bool,  4, 1> {};
+  class IsPartiallyDependent: public BitField<bool,  5, 1> {};
+  class IsInNewSpaceList:     public BitField<bool,  6, 1> {};
 
-  bool independent_ : 1;
-  bool partially_dependent_ : 1;
-  bool in_new_space_list_ : 1;
+  uint8_t flags_;
 
   // Handle specific callback.
   WeakReferenceCallback callback_;
@@ -480,14 +507,6 @@
 }
 
 
-void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) {
-  Node::FromLocation(location)->set_wrapper_class_id(class_id);
-}
-
-uint16_t GlobalHandles::GetWrapperClassId(Object** location) {
-  return Node::FromLocation(location)->wrapper_class_id();
-}
-
 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
   for (NodeIterator it(this); !it.done(); it.Advance()) {
     if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
diff --git a/src/global-handles.h b/src/global-handles.h
index 7808d16..a28a96f 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -130,9 +130,6 @@
                 void* parameter,
                 WeakReferenceCallback callback);
 
-  static void SetWrapperClassId(Object** location, uint16_t class_id);
-  static uint16_t GetWrapperClassId(Object** location);
-
   // Returns the current number of weak handles.
   int NumberOfWeakHandles() { return number_of_weak_handles_; }
 
diff --git a/src/handles.cc b/src/handles.cc
index ed92c41..c0dea20 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -375,6 +375,15 @@
   Handle<JSFunction> constructor = isolate->script_function();
   Handle<JSValue> result =
       Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
+
+  // The allocation might have triggered a GC, which could have called this
+  // function recursively, and a wrapper has already been created and cached.
+  // In that case, simply return the cached wrapper.
+  if (script->wrapper()->foreign_address() != NULL) {
+    return Handle<JSValue>(
+        reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
+  }
+
   result->set_value(*script);
 
   // Create a new weak global handle and use it to cache the wrapper
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 6f4b69c..b8fb1e8 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -633,20 +633,24 @@
     // TODO(yangguo): check that the object is indeed an external string.
     ASSERT(heap_->InNewSpace(obj));
     ASSERT(obj != HEAP->the_hole_value());
+#ifndef ENABLE_LATIN_1
     if (obj->IsExternalAsciiString()) {
       ExternalAsciiString* string = ExternalAsciiString::cast(obj);
       ASSERT(String::IsAscii(string->GetChars(), string->length()));
     }
+#endif
   }
   for (int i = 0; i < old_space_strings_.length(); ++i) {
     Object* obj = Object::cast(old_space_strings_[i]);
     // TODO(yangguo): check that the object is indeed an external string.
     ASSERT(!heap_->InNewSpace(obj));
     ASSERT(obj != HEAP->the_hole_value());
+#ifndef ENABLE_LATIN_1
     if (obj->IsExternalAsciiString()) {
       ExternalAsciiString* string = ExternalAsciiString::cast(obj);
       ASSERT(String::IsAscii(string->GetChars(), string->length()));
     }
+#endif
   }
 #endif
 }
@@ -669,6 +673,19 @@
 }
 
 
+void ErrorObjectList::Add(JSObject* object) {
+  list_.Add(object);
+}
+
+
+void ErrorObjectList::Iterate(ObjectVisitor* v) {
+  if (!list_.is_empty()) {
+    Object** start = &list_[0];
+    v->VisitPointers(start, start + list_.length());
+  }
+}
+
+
 void Heap::ClearInstanceofCache() {
   set_instanceof_cache_function(the_hole_value());
 }
diff --git a/src/heap.cc b/src/heap.cc
index 013a18c..5edaa35 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -37,7 +37,6 @@
 #include "global-handles.h"
 #include "heap-profiler.h"
 #include "incremental-marking.h"
-#include "liveobjectlist-inl.h"
 #include "mark-compact.h"
 #include "natives.h"
 #include "objects-visiting.h"
@@ -439,7 +438,6 @@
   ReportStatisticsBeforeGC();
 #endif  // DEBUG
 
-  LiveObjectList::GCPrologue();
   store_buffer()->GCPrologue();
 }
 
@@ -466,7 +464,6 @@
 
 void Heap::GarbageCollectionEpilogue() {
   store_buffer()->GCEpilogue();
-  LiveObjectList::GCEpilogue();
 
   // In release mode, we only zap the from space under heap verification.
   if (Heap::ShouldZapGarbage()) {
@@ -550,6 +547,8 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
   isolate_->debug()->AfterGarbageCollection();
 #endif  // ENABLE_DEBUGGER_SUPPORT
+
+  error_object_list_.DeferredFormatStackTrace(isolate());
 }
 
 
@@ -886,15 +885,20 @@
   if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) {
     ASSERT(!allocation_allowed_);
     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+    VMState state(isolate_, EXTERNAL);
     global_gc_prologue_callback_();
   }
 
   GCType gc_type =
       collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
 
-  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
-    if (gc_type & gc_prologue_callbacks_[i].gc_type) {
-      gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
+  {
+    GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+    VMState state(isolate_, EXTERNAL);
+    for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
+      if (gc_type & gc_prologue_callbacks_[i].gc_type) {
+        gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
+      }
     }
   }
 
@@ -1002,16 +1006,21 @@
         amount_of_external_allocated_memory_;
   }
 
-  GCCallbackFlags callback_flags = kNoGCCallbackFlags;
-  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
-    if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
-      gc_epilogue_callbacks_[i].callback(gc_type, callback_flags);
+  {
+    GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+    VMState state(isolate_, EXTERNAL);
+    GCCallbackFlags callback_flags = kNoGCCallbackFlags;
+    for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
+      if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
+        gc_epilogue_callbacks_[i].callback(gc_type, callback_flags);
+      }
     }
   }
 
   if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) {
     ASSERT(!allocation_allowed_);
     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+    VMState state(isolate_, EXTERNAL);
     global_gc_epilogue_callback_();
   }
 
@@ -1377,9 +1386,10 @@
   UpdateNewSpaceReferencesInExternalStringTable(
       &UpdateNewSpaceReferenceInExternalStringTableEntry);
 
+  error_object_list_.UpdateReferencesInNewSpace(this);
+
   promotion_queue_.Destroy();
 
-  LiveObjectList::UpdateReferencesForScavengeGC();
   if (!FLAG_watch_ic_patching) {
     isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
   }
@@ -4384,7 +4394,8 @@
 }
 
 
-MaybeObject* Heap::CopyJSObject(JSObject* source) {
+MaybeObject* Heap::CopyJSObject(JSObject* source,
+                                AllocationSiteMode mode) {
   // Never used to copy functions.  If functions need to be copied we
   // have to be careful to clear the literals array.
   SLOW_ASSERT(!source->IsJSFunction());
@@ -4394,13 +4405,25 @@
   int object_size = map->instance_size();
   Object* clone;
 
+  bool track_origin = mode == TRACK_ALLOCATION_SITE &&
+      map->CanTrackAllocationSite();
+
   WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
 
   // If we're forced to always allocate, we use the general allocation
   // functions which may leave us with an object in old space.
+  int adjusted_object_size = object_size;
   if (always_allocate()) {
+    // We'll only track origin if we are certain to allocate in new space
+    if (track_origin) {
+      const int kMinFreeNewSpaceAfterGC = InitialSemiSpaceSize() * 3/4;
+      if ((object_size + AllocationSiteInfo::kSize) < kMinFreeNewSpaceAfterGC) {
+        adjusted_object_size += AllocationSiteInfo::kSize;
+      }
+    }
+
     { MaybeObject* maybe_clone =
-          AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
+          AllocateRaw(adjusted_object_size, NEW_SPACE, OLD_POINTER_SPACE);
       if (!maybe_clone->ToObject(&clone)) return maybe_clone;
     }
     Address clone_address = HeapObject::cast(clone)->address();
@@ -4413,7 +4436,11 @@
                  (object_size - JSObject::kHeaderSize) / kPointerSize);
   } else {
     wb_mode = SKIP_WRITE_BARRIER;
-    { MaybeObject* maybe_clone = new_space_.AllocateRaw(object_size);
+    if (track_origin) {
+      adjusted_object_size += AllocationSiteInfo::kSize;
+    }
+
+    { MaybeObject* maybe_clone = new_space_.AllocateRaw(adjusted_object_size);
       if (!maybe_clone->ToObject(&clone)) return maybe_clone;
     }
     SLOW_ASSERT(InNewSpace(clone));
@@ -4424,6 +4451,13 @@
               object_size);
   }
 
+  if (adjusted_object_size > object_size) {
+    AllocationSiteInfo* alloc_info = reinterpret_cast<AllocationSiteInfo*>(
+        reinterpret_cast<Address>(clone) + object_size);
+    alloc_info->set_map(allocation_site_info_map());
+    alloc_info->set_payload(source);
+  }
+
   SLOW_ASSERT(
       JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind());
   FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
@@ -4640,82 +4674,57 @@
 }
 
 
-template<typename T>
-class AllocateInternalSymbolHelper {
- public:
-  static void WriteOneByteData(T t, char* chars, int len);
-  static void WriteTwoByteData(T t, uint16_t* chars, int len);
- private:
-  DISALLOW_COPY_AND_ASSIGN(AllocateInternalSymbolHelper);
-};
+static inline void WriteOneByteData(Vector<const char> vector,
+                                    uint8_t* chars,
+                                    int len) {
+  // Only works for ascii.
+  ASSERT(vector.length() == len);
+  memcpy(chars, vector.start(), len);
+}
 
-
-template<>
-class AllocateInternalSymbolHelper< Vector<const char> > {
- public:
-  static inline void WriteOneByteData(Vector<const char> vector,
-                                      uint8_t* chars,
-                                      int len) {
-    // Only works for ascii.
-    ASSERT(vector.length() == len);
-    memcpy(chars, vector.start(), len);
-  }
-
-  static inline void WriteTwoByteData(Vector<const char> vector,
-                                      uint16_t* chars,
-                                      int len) {
-    const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
-    unsigned stream_length = vector.length();
-    while (stream_length != 0) {
-      unsigned consumed = 0;
-      uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
-      ASSERT(c != unibrow::Utf8::kBadChar);
-      ASSERT(consumed <= stream_length);
-      stream_length -= consumed;
-      stream += consumed;
-      if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
-        len -= 2;
-        if (len < 0) break;
-        *chars++ = unibrow::Utf16::LeadSurrogate(c);
-        *chars++ = unibrow::Utf16::TrailSurrogate(c);
-      } else {
-        len -= 1;
-        if (len < 0) break;
-        *chars++ = c;
-      }
+static inline void WriteTwoByteData(Vector<const char> vector,
+                                    uint16_t* chars,
+                                    int len) {
+  const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
+  unsigned stream_length = vector.length();
+  while (stream_length != 0) {
+    unsigned consumed = 0;
+    uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
+    ASSERT(c != unibrow::Utf8::kBadChar);
+    ASSERT(consumed <= stream_length);
+    stream_length -= consumed;
+    stream += consumed;
+    if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
+      len -= 2;
+      if (len < 0) break;
+      *chars++ = unibrow::Utf16::LeadSurrogate(c);
+      *chars++ = unibrow::Utf16::TrailSurrogate(c);
+    } else {
+      len -= 1;
+      if (len < 0) break;
+      *chars++ = c;
     }
-    ASSERT(stream_length == 0);
-    ASSERT(len == 0);
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AllocateInternalSymbolHelper);
-};
+  ASSERT(stream_length == 0);
+  ASSERT(len == 0);
+}
 
 
-template<>
-class AllocateInternalSymbolHelper<String*> {
- public:
-  static inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
-    ASSERT(s->length() == len);
-    String::WriteToFlat(s, chars, 0, len);
-  }
+static inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
+  ASSERT(s->length() == len);
+  String::WriteToFlat(s, chars, 0, len);
+}
 
-  static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
-    ASSERT(s->length() == len);
-    String::WriteToFlat(s, chars, 0, len);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AllocateInternalSymbolHelper<String*>);
-};
+static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
+  ASSERT(s->length() == len);
+  String::WriteToFlat(s, chars, 0, len);
+}
 
 
 template<bool is_one_byte, typename T>
 MaybeObject* Heap::AllocateInternalSymbol(T t,
                                           int chars,
                                           uint32_t hash_field) {
-  typedef AllocateInternalSymbolHelper<T> H;
   ASSERT(chars >= 0);
   // Compute map and object size.
   int size;
@@ -4752,9 +4761,9 @@
   ASSERT_EQ(size, answer->Size());
 
   if (is_one_byte) {
-    H::WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
+    WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
   } else {
-    H::WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
+    WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
   }
   return answer;
 }
@@ -5959,6 +5968,7 @@
       mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
     // Scavenge collections have special processing for this.
     external_string_table_.Iterate(v);
+    error_object_list_.Iterate(v);
   }
   v->Synchronize(VisitorSynchronization::kExternalStringsTable);
 }
@@ -6332,6 +6342,8 @@
 
   external_string_table_.TearDown();
 
+  error_object_list_.TearDown();
+
   new_space_.TearDown();
 
   if (old_pointer_space_ != NULL) {
@@ -6731,7 +6743,7 @@
 }
 
 
-#if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
+#ifdef DEBUG
 
 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL);
 
@@ -6898,10 +6910,8 @@
     PrintF("=====================================\n");
   }
 }
-#endif  // DEBUG || LIVE_OBJECT_LIST
 
 
-#ifdef DEBUG
 // Triggers a depth-first traversal of reachable objects from one
 // given root object and finds a path to a specific heap object and
 // prints it.
@@ -7238,6 +7248,8 @@
     }
   }
   new_space_strings_.Rewind(last);
+  new_space_strings_.Trim();
+
   last = 0;
   for (int i = 0; i < old_space_strings_.length(); ++i) {
     if (old_space_strings_[i] == heap_->the_hole_value()) {
@@ -7247,6 +7259,7 @@
     old_space_strings_[last++] = old_space_strings_[i];
   }
   old_space_strings_.Rewind(last);
+  old_space_strings_.Trim();
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap) {
     Verify();
@@ -7261,6 +7274,119 @@
 }
 
 
+// Update all references.
+void ErrorObjectList::UpdateReferences() {
+  for (int i = 0; i < list_.length(); i++) {
+    HeapObject* object = HeapObject::cast(list_[i]);
+    MapWord first_word = object->map_word();
+    if (first_word.IsForwardingAddress()) {
+      list_[i] = first_word.ToForwardingAddress();
+    }
+  }
+}
+
+
+// Unforwarded objects in new space are dead and removed from the list.
+void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) {
+  if (list_.is_empty()) return;
+  if (!nested_) {
+    int write_index = 0;
+    for (int i = 0; i < list_.length(); i++) {
+      MapWord first_word = HeapObject::cast(list_[i])->map_word();
+      if (first_word.IsForwardingAddress()) {
+        list_[write_index++] = first_word.ToForwardingAddress();
+      }
+    }
+    list_.Rewind(write_index);
+  } else {
+    // If a GC is triggered during DeferredFormatStackTrace, we do not move
+    // objects in the list, just remove dead ones, as to not confuse the
+    // loop in DeferredFormatStackTrace.
+    for (int i = 0; i < list_.length(); i++) {
+      MapWord first_word = HeapObject::cast(list_[i])->map_word();
+      list_[i] = first_word.IsForwardingAddress()
+                     ? first_word.ToForwardingAddress()
+                     : heap->the_hole_value();
+    }
+  }
+}
+
+
+void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) {
+  // If formatting the stack trace causes a GC, this method will be
+  // recursively called.  In that case, skip the recursive call, since
+  // the loop modifies the list while iterating over it.
+  if (nested_ || list_.is_empty() || isolate->has_pending_exception()) return;
+  nested_ = true;
+  HandleScope scope(isolate);
+  Handle<String> stack_key = isolate->factory()->stack_symbol();
+  int write_index = 0;
+  int budget = kBudgetPerGC;
+  for (int i = 0; i < list_.length(); i++) {
+    Object* object = list_[i];
+    JSFunction* getter_fun;
+
+    { AssertNoAllocation assert;
+      // Skip possible holes in the list.
+      if (object->IsTheHole()) continue;
+      if (isolate->heap()->InNewSpace(object) || budget == 0) {
+        list_[write_index++] = object;
+        continue;
+      }
+
+      // Check whether the stack property is backed by the original getter.
+      LookupResult lookup(isolate);
+      JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup);
+      if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue;
+      Object* callback = lookup.GetCallbackObject();
+      if (!callback->IsAccessorPair()) continue;
+      Object* getter_obj = AccessorPair::cast(callback)->getter();
+      if (!getter_obj->IsJSFunction()) continue;
+      getter_fun = JSFunction::cast(getter_obj);
+      String* key = isolate->heap()->hidden_stack_trace_symbol();
+      if (key != getter_fun->GetHiddenProperty(key)) continue;
+    }
+
+    budget--;
+    HandleScope scope(isolate);
+    bool has_exception = false;
+#ifdef DEBUG
+    Handle<Map> map(HeapObject::cast(object)->map(), isolate);
+#endif
+    Handle<Object> object_handle(object, isolate);
+    Handle<Object> getter_handle(getter_fun, isolate);
+    Execution::Call(getter_handle, object_handle, 0, NULL, &has_exception);
+    ASSERT(*map == HeapObject::cast(*object_handle)->map());
+    if (has_exception) {
+      // Hit an exception (most likely a stack overflow).
+      // Wrap up this pass and retry after another GC.
+      isolate->clear_pending_exception();
+      // We use the handle since calling the getter might have caused a GC.
+      list_[write_index++] = *object_handle;
+      budget = 0;
+    }
+  }
+  list_.Rewind(write_index);
+  list_.Trim();
+  nested_ = false;
+}
+
+
+void ErrorObjectList::RemoveUnmarked(Heap* heap) {
+  for (int i = 0; i < list_.length(); i++) {
+    HeapObject* object = HeapObject::cast(list_[i]);
+    if (!Marking::MarkBitFrom(object).Get()) {
+      list_[i] = heap->the_hole_value();
+    }
+  }
+}
+
+
+void ErrorObjectList::TearDown() {
+  list_.Free();
+}
+
+
 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
   chunk->set_next_chunk(chunks_queued_for_free_);
   chunks_queued_for_free_ = chunk;
diff --git a/src/heap.h b/src/heap.h
index a2564a5..b7ef1f7 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -209,6 +209,7 @@
   V(char_at_symbol, "CharAt")                                            \
   V(undefined_symbol, "undefined")                                       \
   V(value_of_symbol, "valueOf")                                          \
+  V(stack_symbol, "stack")                                               \
   V(InitializeVarGlobal_symbol, "InitializeVarGlobal")                   \
   V(InitializeConstGlobal_symbol, "InitializeConstGlobal")               \
   V(KeyedLoadElementMonomorphic_symbol,                                  \
@@ -427,6 +428,41 @@
 };
 
 
+// The stack property of an error object is implemented as a getter that
+// formats the attached raw stack trace into a string.  This raw stack trace
+// keeps code and function objects alive until the getter is called the first
+// time.  To release those objects, we call the getter after each GC for
+// newly tenured error objects that are kept in a list.
+class ErrorObjectList {
+ public:
+  inline void Add(JSObject* object);
+
+  inline void Iterate(ObjectVisitor* v);
+
+  void TearDown();
+
+  void RemoveUnmarked(Heap* heap);
+
+  void DeferredFormatStackTrace(Isolate* isolate);
+
+  void UpdateReferences();
+
+  void UpdateReferencesInNewSpace(Heap* heap);
+
+ private:
+  static const int kBudgetPerGC = 16;
+
+  ErrorObjectList() : nested_(false) { }
+
+  friend class Heap;
+
+  List<Object*> list_;
+  bool nested_;
+
+  DISALLOW_COPY_AND_ASSIGN(ErrorObjectList);
+};
+
+
 enum ArrayStorageAllocationMode {
   DONT_INITIALIZE_ARRAY_ELEMENTS,
   INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
@@ -588,7 +624,9 @@
   // Returns a deep copy of the JavaScript object.
   // Properties and elements are copied too.
   // Returns failure if allocation failed.
-  MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source);
+  MUST_USE_RESULT MaybeObject* CopyJSObject(
+      JSObject* source,
+      AllocationSiteMode mode = DONT_TRACK_ALLOCATION_SITE);
 
   // Allocates the function prototype.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -1589,6 +1627,10 @@
     return &external_string_table_;
   }
 
+  ErrorObjectList* error_object_list() {
+    return &error_object_list_;
+  }
+
   // Returns the current sweep generation.
   int sweep_generation() {
     return sweep_generation_;
@@ -2165,6 +2207,8 @@
 
   ExternalStringTable external_string_table_;
 
+  ErrorObjectList error_object_list_;
+
   VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
 
   MemoryChunk* chunks_queued_for_free_;
@@ -2798,7 +2842,7 @@
 };
 
 
-#if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
+#ifdef DEBUG
 // Helper class for tracing paths to a search target Object from all roots.
 // The TracePathFrom() method can be used to trace paths from a specific
 // object to the search target object.
@@ -2855,7 +2899,7 @@
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
 };
-#endif  // DEBUG || LIVE_OBJECT_LIST
+#endif  // DEBUG
 
 } }  // namespace v8::internal
 
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 67a679f..4bcb498 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -737,6 +737,11 @@
 #endif
 
 
+void HDummyUse::PrintDataTo(StringStream* stream) {
+  value()->PrintNameTo(stream);
+}
+
+
 void HUnaryCall::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   stream->Add(" ");
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 30919f5..88d217a 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -104,6 +104,7 @@
   V(DeleteProperty)                            \
   V(Deoptimize)                                \
   V(Div)                                       \
+  V(DummyUse)                                  \
   V(ElementsKind)                              \
   V(EnterInlined)                              \
   V(FastLiteral)                               \
@@ -1024,6 +1025,28 @@
 };
 
 
+class HDummyUse: public HTemplateInstruction<1> {
+ public:
+  explicit HDummyUse(HValue* value) {
+    SetOperandAt(0, value);
+    // Pretend to be a Smi so that the HChange instructions inserted
+    // before any use generate as little code as possible.
+    set_representation(Representation::Tagged());
+    set_type(HType::Smi());
+  }
+
+  HValue* value() { return OperandAt(0); }
+
+  virtual Representation RequiredInputRepresentation(int index) {
+    return Representation::None();
+  }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse);
+};
+
+
 // We insert soft-deoptimize when we hit code with unknown typefeedback,
 // so that we get a chance of re-optimizing with useful typefeedback.
 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
@@ -4968,19 +4991,29 @@
 template <int V>
 class HMaterializedLiteral: public HTemplateInstruction<V> {
  public:
+  HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
+      : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
+    this->set_representation(Representation::Tagged());
+  }
+
   HMaterializedLiteral<V>(int index, int depth)
-      : literal_index_(index), depth_(depth) {
+      : literal_index_(index), depth_(depth),
+        allocation_site_mode_(DONT_TRACK_ALLOCATION_SITE) {
     this->set_representation(Representation::Tagged());
   }
 
   int literal_index() const { return literal_index_; }
   int depth() const { return depth_; }
+  AllocationSiteMode allocation_site_mode() const {
+    return allocation_site_mode_;
+  }
 
  private:
   virtual bool IsDeletable() const { return true; }
 
   int literal_index_;
   int depth_;
+  AllocationSiteMode allocation_site_mode_;
 };
 
 
@@ -4990,8 +5023,9 @@
                Handle<JSObject> boilerplate,
                int total_size,
                int literal_index,
-               int depth)
-      : HMaterializedLiteral<1>(literal_index, depth),
+               int depth,
+               AllocationSiteMode mode)
+      : HMaterializedLiteral<1>(literal_index, depth, mode),
         boilerplate_(boilerplate),
         total_size_(total_size) {
     SetOperandAt(0, context);
@@ -5006,7 +5040,6 @@
   HValue* context() { return OperandAt(0); }
   Handle<JSObject> boilerplate() const { return boilerplate_; }
   int total_size() const { return total_size_; }
-
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
@@ -5026,8 +5059,9 @@
                 Handle<HeapObject> boilerplate_object,
                 int length,
                 int literal_index,
-                int depth)
-      : HMaterializedLiteral<1>(literal_index, depth),
+                int depth,
+                AllocationSiteMode mode)
+      : HMaterializedLiteral<1>(literal_index, depth, mode),
         length_(length),
         boilerplate_object_(boilerplate_object) {
     SetOperandAt(0, context);
@@ -5043,7 +5077,6 @@
   }
   Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
   int length() const { return length_; }
-
   bool IsCopyOnWrite() const;
 
   virtual Representation RequiredInputRepresentation(int index) {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e5b1da8..a4578ee 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -877,6 +877,7 @@
       zone_(info->zone()),
       is_recursive_(false),
       use_optimistic_licm_(false),
+      has_soft_deoptimize_(false),
       type_change_checksum_(0) {
   if (info->IsStub()) {
     start_environment_ =
@@ -1244,13 +1245,18 @@
   }
 }
 
+
 // Mark all blocks that are dominated by an unconditional soft deoptimize to
 // prevent code motion across those blocks.
 void HGraph::PropagateDeoptimizingMark() {
   HPhase phase("H_Propagate deoptimizing mark", this);
+  // Skip this phase if there is nothing to be done anyway.
+  if (!has_soft_deoptimize()) return;
   MarkAsDeoptimizingRecursively(entry_block());
+  NullifyUnreachableInstructions();
 }
 
+
 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) {
   for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
     HBasicBlock* dominated = block->dominated_blocks()->at(i);
@@ -1259,6 +1265,67 @@
   }
 }
 
+
+void HGraph::NullifyUnreachableInstructions() {
+  int block_count = blocks_.length();
+  for (int i = 0; i < block_count; ++i) {
+    HBasicBlock* block = blocks_.at(i);
+    bool nullify = false;
+    const ZoneList<HBasicBlock*>* predecessors = block->predecessors();
+    int predecessors_length = predecessors->length();
+    bool all_predecessors_deoptimizing = (predecessors_length > 0);
+    for (int j = 0; j < predecessors_length; ++j) {
+      if (!predecessors->at(j)->IsDeoptimizing()) {
+        all_predecessors_deoptimizing = false;
+        break;
+      }
+    }
+    if (all_predecessors_deoptimizing) nullify = true;
+    for (HInstruction* instr = block->first(); instr != NULL;
+         instr = instr->next()) {
+      // Leave the basic structure of the graph intact.
+      if (instr->IsBlockEntry()) continue;
+      if (instr->IsControlInstruction()) continue;
+      if (instr->IsSimulate()) continue;
+      if (instr->IsEnterInlined()) continue;
+      if (instr->IsLeaveInlined()) continue;
+      if (nullify) {
+        HInstruction* last_dummy = NULL;
+        for (int j = 0; j < instr->OperandCount(); ++j) {
+          HValue* operand = instr->OperandAt(j);
+          // Insert an HDummyUse for each operand, unless the operand
+          // is an HDummyUse itself. If it's even from the same block,
+          // remember it as a potential replacement for the instruction.
+          if (operand->IsDummyUse()) {
+            if (operand->block() == instr->block() &&
+                last_dummy == NULL) {
+              last_dummy = HInstruction::cast(operand);
+            }
+            continue;
+          }
+          if (operand->IsControlInstruction()) {
+            // Inserting a dummy use for a value that's not defined anywhere
+            // will fail. Some instructions define fake inputs on such
+            // values as control flow dependencies.
+            continue;
+          }
+          HDummyUse* dummy = new(zone()) HDummyUse(operand);
+          dummy->InsertBefore(instr);
+          last_dummy = dummy;
+        }
+        if (last_dummy == NULL) last_dummy = GetConstant1();
+        instr->DeleteAndReplaceWith(last_dummy);
+        continue;
+      }
+      if (instr->IsSoftDeoptimize()) {
+        ASSERT(block->IsDeoptimizing());
+        nullify = true;
+      }
+    }
+  }
+}
+
+
 void HGraph::EliminateRedundantPhis() {
   HPhase phase("H_Redundant phi elimination", this);
 
@@ -3985,6 +4052,15 @@
 }
 
 
+void HOptimizedGraphBuilder::AddSoftDeoptimize() {
+  if (FLAG_always_opt) return;
+  if (current_block()->IsDeoptimizing()) return;
+  AddInstruction(new(zone()) HSoftDeoptimize());
+  current_block()->MarkAsDeoptimizing();
+  graph()->set_has_soft_deoptimize(true);
+}
+
+
 template <class Instruction>
 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
   int count = call->argument_count();
@@ -5213,7 +5289,8 @@
                                        boilerplate_object,
                                        total_size,
                                        expr->literal_index(),
-                                       expr->depth());
+                                       expr->depth(),
+                                       DONT_TRACK_ALLOCATION_SITE);
   } else {
     literal = new(zone()) HObjectLiteral(context,
                                          expr->constant_properties(),
@@ -5323,7 +5400,13 @@
 
   Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate);
   ElementsKind boilerplate_elements_kind =
-        Handle<JSObject>::cast(boilerplate)->GetElementsKind();
+      Handle<JSObject>::cast(boilerplate)->GetElementsKind();
+
+  // TODO(mvstanton): This heuristic is only a temporary solution.  In the
+  // end, we want to quit creating allocation site info after a certain number
+  // of GCs for a call site.
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(
+      boilerplate_elements_kind);
 
   // Check whether to use fast or slow deep-copying for boilerplate.
   int total_size = 0;
@@ -5332,17 +5415,22 @@
                     HFastLiteral::kMaxLiteralDepth,
                     &max_properties,
                     &total_size)) {
+    if (mode == TRACK_ALLOCATION_SITE) {
+      total_size += AllocationSiteInfo::kSize;
+    }
     literal = new(zone()) HFastLiteral(context,
                                        boilerplate,
                                        total_size,
                                        expr->literal_index(),
-                                       expr->depth());
+                                       expr->depth(),
+                                       mode);
   } else {
     literal = new(zone()) HArrayLiteral(context,
                                         boilerplate,
                                         length,
                                         expr->literal_index(),
-                                        expr->depth());
+                                        expr->depth(),
+                                        mode);
   }
 
   // The array is expected in the bailout environment during computation
@@ -6160,9 +6248,8 @@
     HValue* object,
     Handle<String> name,
     Property* expr) {
-  if (expr->IsUninitialized() && !FLAG_always_opt) {
-    AddInstruction(new(zone()) HSoftDeoptimize);
-    current_block()->MarkAsDeoptimizing();
+  if (expr->IsUninitialized()) {
+    AddSoftDeoptimize();
   }
   HValue* context = environment()->LookupContext();
   return new(zone()) HLoadNamedGeneric(context, object, name);
@@ -8057,8 +8144,7 @@
   TypeInfo info = oracle()->UnaryType(expr);
   Representation rep = ToRepresentation(info);
   if (info.IsUninitialized()) {
-    AddInstruction(new(zone()) HSoftDeoptimize);
-    current_block()->MarkAsDeoptimizing();
+    AddSoftDeoptimize();
     info = TypeInfo::Unknown();
   }
   HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep);
@@ -8071,8 +8157,7 @@
   HValue* value = Pop();
   TypeInfo info = oracle()->UnaryType(expr);
   if (info.IsUninitialized()) {
-    AddInstruction(new(zone()) HSoftDeoptimize);
-    current_block()->MarkAsDeoptimizing();
+    AddSoftDeoptimize();
   }
   HInstruction* instr = new(zone()) HBitNot(value);
   return ast_context()->ReturnInstruction(instr, expr->id());
@@ -8428,8 +8513,7 @@
   if (left_info.IsUninitialized()) {
     // Can't have initialized one but not the other.
     ASSERT(right_info.IsUninitialized());
-    AddInstruction(new(zone()) HSoftDeoptimize);
-    current_block()->MarkAsDeoptimizing();
+    AddSoftDeoptimize();
     left_info = right_info = TypeInfo::Unknown();
   }
   HInstruction* instr = NULL;
@@ -8745,8 +8829,7 @@
   // Check if this expression was ever executed according to type feedback.
   // Note that for the special typeof/null/undefined cases we get unknown here.
   if (overall_type_info.IsUninitialized()) {
-    AddInstruction(new(zone()) HSoftDeoptimize);
-    current_block()->MarkAsDeoptimizing();
+    AddSoftDeoptimize();
     overall_type_info = left_type = right_type = TypeInfo::Unknown();
   }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index eb5ec52..faaffc3 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -355,6 +355,14 @@
     use_optimistic_licm_ = value;
   }
 
+  bool has_soft_deoptimize() {
+    return has_soft_deoptimize_;
+  }
+
+  void set_has_soft_deoptimize(bool value) {
+    has_soft_deoptimize_ = value;
+  }
+
   void MarkRecursive() {
     is_recursive_ = true;
   }
@@ -377,6 +385,7 @@
                               int32_t integer_value);
 
   void MarkAsDeoptimizingRecursively(HBasicBlock* block);
+  void NullifyUnreachableInstructions();
   void InsertTypeConversions(HInstruction* instr);
   void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
   void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
@@ -414,6 +423,7 @@
 
   bool is_recursive_;
   bool use_optimistic_licm_;
+  bool has_soft_deoptimize_;
   int type_change_checksum_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraph);
@@ -956,6 +966,8 @@
 
   bool inline_bailout() { return inline_bailout_; }
 
+  void AddSoftDeoptimize();
+
   // Bailout environment manipulation.
   void Push(HValue* value) { environment()->Push(value); }
   HValue* Pop() { return environment()->Pop(); }
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 28663ab..4b71af6 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -323,7 +323,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
-    AllocationSiteInfoMode allocation_site_info_mode,
+    AllocationSiteMode allocation_site_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -339,7 +339,7 @@
   }
   int size = JSArray::kSize;
   int allocation_info_start = size;
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     size += AllocationSiteInfo::kSize;
   }
   size += elements_size;
@@ -352,7 +352,7 @@
   }
   __ AllocateInNewSpace(size, eax, ebx, edx, fail, flags);
 
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ mov(FieldOperand(eax, allocation_info_start),
            Immediate(Handle<Map>(masm->isolate()->heap()->
                                  allocation_site_info_map())));
@@ -371,7 +371,7 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset));
-    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
       __ lea(edx, Operand(eax, JSArray::kSize + AllocationSiteInfo::kSize));
     } else {
       __ lea(edx, Operand(eax, JSArray::kSize));
@@ -425,30 +425,21 @@
 
   FastCloneShallowArrayStub::Mode mode = mode_;
   // ecx is boilerplate object.
-  AllocationSiteInfoMode allocation_site_info_mode =
-      DONT_TRACK_ALLOCATION_SITE_INFO;
-  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
-    mode = CLONE_ANY_ELEMENTS;
-    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
-  }
-
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ mov(ebx, FieldOperand(ecx, JSArray::kElementsOffset));
     __ CheckMap(ebx, factory->fixed_cow_array_map(),
                 &check_fast_elements, DONT_DO_SMI_CHECK);
-    GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, 0, COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     __ ret(3 * kPointerSize);
 
     __ bind(&check_fast_elements);
     __ CheckMap(ebx, factory->fixed_array_map(),
                 &double_elements, DONT_DO_SMI_CHECK);
-    GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, length_, CLONE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     __ ret(3 * kPointerSize);
 
@@ -479,7 +470,9 @@
   }
 
   GenerateFastCloneShallowArrayCommon(masm, length_, mode,
-                                      allocation_site_info_mode, &slow_case);
+                                      allocation_site_mode_,
+                                      &slow_case);
+
   // Return and remove the on-stack parameters.
   __ ret(3 * kPointerSize);
 
@@ -5720,6 +5713,13 @@
   // edi: second instance type.
   __ test(ecx, Immediate(kAsciiDataHintMask));
   __ j(not_zero, &ascii_data);
+  __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
+  __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+  __ xor_(edi, ecx);
+  STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
+  __ and_(edi, kOneByteStringTag | kAsciiDataHintTag);
+  __ cmp(edi, kOneByteStringTag | kAsciiDataHintTag);
+  __ j(equal, &ascii_data);
   // Allocate a two byte cons string.
   __ AllocateTwoByteConsString(ecx, edi, no_reg, &call_runtime);
   __ jmp(&allocated);
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index cb2fa26..7dc3768 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -390,7 +390,8 @@
 
 
 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
-    MacroAssembler* masm) {
+    MacroAssembler* masm, AllocationSiteMode mode,
+    Label* allocation_site_info_found) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ebx    : target map
@@ -398,6 +399,12 @@
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
+  if (mode == TRACK_ALLOCATION_SITE) {
+    ASSERT(allocation_site_info_found != NULL);
+    masm->TestJSArrayForAllocationSiteInfo(edx, edi,
+                                           allocation_site_info_found);
+  }
+
   // Set transitioned map.
   __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx);
   __ RecordWriteField(edx,
@@ -411,7 +418,7 @@
 
 
 void ElementsTransitionGenerator::GenerateSmiToDouble(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ebx    : target map
@@ -421,7 +428,7 @@
   // -----------------------------------
   Label loop, entry, convert_hole, gc_required, only_change_map;
 
-  if (FLAG_track_allocation_sites) {
+  if (mode == TRACK_ALLOCATION_SITE) {
     masm->TestJSArrayForAllocationSiteInfo(edx, edi, fail);
   }
 
@@ -550,7 +557,7 @@
 
 
 void ElementsTransitionGenerator::GenerateDoubleToObject(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ebx    : target map
@@ -560,6 +567,10 @@
   // -----------------------------------
   Label loop, entry, convert_hole, gc_required, only_change_map, success;
 
+  if (mode == TRACK_ALLOCATION_SITE) {
+    masm->TestJSArrayForAllocationSiteInfo(edx, edi, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 72a8592..029dbfb 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -1148,7 +1148,16 @@
       __ movdbl(Operand(ebx, dst_offset), xmm0);
     }
   }
-  __ fninit();
+
+  // Check that the TOP register is zero and clear all exceptions.
+  const int kTopMask = 0x3800;
+  __ push(eax);
+  __ fwait();
+  __ fnstsw_ax();
+  __ test(eax, Immediate(kTopMask));
+  __ Check(zero, "FPU TOP is not zero in deoptimizer.");
+  __ fnclex();
+  __ pop(eax);
 
   // Remove the bailout id and the double registers from the stack.
   if (type() == EAGER) {
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 7cb6558..23b8c66 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1664,6 +1664,7 @@
     __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
     FastCloneShallowArrayStub stub(
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
+        DONT_TRACK_ALLOCATION_SITE,
         length);
     __ CallStub(&stub);
   } else if (expr->depth() > 1) {
@@ -1673,21 +1674,19 @@
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
+    FastCloneShallowArrayStub::Mode mode =
+        FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+    AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
+        ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
+
     // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot
     // change, so it's possible to specialize the stub in advance.
-    FastCloneShallowArrayStub::Mode mode = has_constant_fast_elements
-        ? FastCloneShallowArrayStub::CLONE_ELEMENTS
-        : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
-
-    // Tracking allocation info allows us to pre-transition later if it makes
-    // sense.
-    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
-        FLAG_track_allocation_sites) {
-      mode = FastCloneShallowArrayStub::
-          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    if (has_constant_fast_elements) {
+      mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
+      allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
     }
 
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     __ CallStub(&stub);
   }
 
@@ -3639,8 +3638,7 @@
   __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
   __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
   __ and_(scratch, Immediate(
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask));
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
   __ cmp(scratch, ASCII_STRING_TYPE);
   __ j(not_equal, &bailout);
 
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index eb69658..3b5ef00 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -835,7 +835,9 @@
                                          ebx,
                                          edi,
                                          slow);
-  ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                        FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
   __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
@@ -846,7 +848,9 @@
                                          ebx,
                                          edi,
                                          slow);
-  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+  mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
+                                                                   slow);
   __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 
@@ -860,7 +864,8 @@
                                          ebx,
                                          edi,
                                          slow);
-  ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+  mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
   __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 }
@@ -1650,7 +1655,9 @@
   // Must return the modified receiver in eax.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                          FAST_DOUBLE_ELEMENTS);
+    ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
     __ mov(eax, edx);
     __ Ret();
     __ bind(&fail);
@@ -1676,7 +1683,9 @@
   // Must return the modified receiver in eax.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS,
+                                                          FAST_ELEMENTS);
+    ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
     __ mov(eax, edx);
     __ Ret();
     __ bind(&fail);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index e9d7509..c8fae64 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4159,11 +4159,6 @@
     }
     DeoptimizeIf(below_equal, instr->environment());
   } else {
-    if (instr->hydrogen()->index()->representation().IsTagged() &&
-        !instr->hydrogen()->index()->type().IsSmi()) {
-      __ test(ToRegister(instr->index()), Immediate(kSmiTagMask));
-      DeoptimizeIf(not_zero, instr->environment());
-    }
     __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
     DeoptimizeIf(above_equal, instr->environment());
   }
@@ -5300,6 +5295,8 @@
   Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();
+  AllocationSiteMode allocation_site_mode =
+      instr->hydrogen()->allocation_site_mode();
 
   // Deopt if the array literal boilerplate ElementsKind is of a type different
   // than the expected one. The check isn't necessary if the boilerplate has
@@ -5330,7 +5327,7 @@
     ASSERT(instr->hydrogen()->depth() == 1);
     FastCloneShallowArrayStub::Mode mode =
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   } else if (instr->hydrogen()->depth() > 1) {
     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
@@ -5339,9 +5336,9 @@
   } else {
     FastCloneShallowArrayStub::Mode mode =
         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS
-            ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
-            : FastCloneShallowArrayStub::CLONE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+        ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
+        : FastCloneShallowArrayStub::CLONE_ELEMENTS;
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   }
 }
@@ -5350,10 +5347,14 @@
 void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
                             Register result,
                             Register source,
-                            int* offset) {
+                            int* offset,
+                            AllocationSiteMode mode) {
   ASSERT(!source.is(ecx));
   ASSERT(!result.is(ecx));
 
+  bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
+      object->map()->CanTrackAllocationSite();
+
   if (FLAG_debug_code) {
     __ LoadHeapObject(ecx, object);
     __ cmp(source, ecx);
@@ -5376,8 +5377,13 @@
   // this object and its backing store.
   int object_offset = *offset;
   int object_size = object->map()->instance_size();
-  int elements_offset = *offset + object_size;
   int elements_size = has_elements ? elements->Size() : 0;
+  int elements_offset = *offset + object_size;
+  if (create_allocation_site_info) {
+    elements_offset += AllocationSiteInfo::kSize;
+    *offset += AllocationSiteInfo::kSize;
+  }
+
   *offset += object_size + elements_size;
 
   // Copy object header.
@@ -5402,7 +5408,8 @@
       __ lea(ecx, Operand(result, *offset));
       __ mov(FieldOperand(result, total_offset), ecx);
       __ LoadHeapObject(source, value_object);
-      EmitDeepCopy(value_object, result, source, offset);
+      EmitDeepCopy(value_object, result, source, offset,
+                   DONT_TRACK_ALLOCATION_SITE);
     } else if (value->IsHeapObject()) {
       __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
       __ mov(FieldOperand(result, total_offset), ecx);
@@ -5411,6 +5418,14 @@
     }
   }
 
+  // Build Allocation Site Info if desired
+  if (create_allocation_site_info) {
+    __ mov(FieldOperand(result, object_size),
+           Immediate(Handle<Map>(isolate()->heap()->
+                                 allocation_site_info_map())));
+    __ mov(FieldOperand(result, object_size + kPointerSize), source);
+  }
+
   if (has_elements) {
     // Copy elements backing store header.
     __ LoadHeapObject(source, elements);
@@ -5443,7 +5458,8 @@
           __ lea(ecx, Operand(result, *offset));
           __ mov(FieldOperand(result, total_offset), ecx);
           __ LoadHeapObject(source, value_object);
-          EmitDeepCopy(value_object, result, source, offset);
+          EmitDeepCopy(value_object, result, source, offset,
+                       DONT_TRACK_ALLOCATION_SITE);
         } else if (value->IsHeapObject()) {
           __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
           __ mov(FieldOperand(result, total_offset), ecx);
@@ -5493,7 +5509,8 @@
   __ bind(&allocated);
   int offset = 0;
   __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate());
-  EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset);
+  EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset,
+               instr->hydrogen()->allocation_site_mode());
   ASSERT_EQ(size, offset);
 }
 
@@ -5758,6 +5775,11 @@
 }
 
 
+void LCodeGen::DoDummyUse(LDummyUse* instr) {
+  // Nothing to see here, move on!
+}
+
+
 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   LOperand* obj = instr->object();
   LOperand* key = instr->key();
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index 63d15f4..5c3d045 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -350,7 +350,8 @@
   void EmitDeepCopy(Handle<JSObject> object,
                     Register result,
                     Register source,
-                    int* offset);
+                    int* offset,
+                    AllocationSiteMode mode);
 
   void EnsureSpaceForLazyDeopt();
   void DoLoadKeyedExternalArray(LLoadKeyed* instr);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index da1a466..8bb5740 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -726,6 +726,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
+  return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 02eb6d3..1daf847 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -87,6 +87,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(DummyUse)                                   \
   V(ElementsKind)                               \
   V(FastLiteral)                                \
   V(FixedArrayBaseLength)                       \
@@ -387,6 +388,15 @@
 };
 
 
+class LDummyUse: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDummyUse(LOperand* value) {
+    inputs_[0] = value;
+  }
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
+};
+
+
 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index d5013d7..cebfb13 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -2706,17 +2706,15 @@
   movzx_b(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));
 
   // Check that both are flat ASCII strings.
-  const int kFlatAsciiStringMask = kIsNotStringMask | kStringRepresentationMask
-          | kStringEncodingMask | kAsciiDataHintTag;
+  const int kFlatAsciiStringMask =
+      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
   const int kFlatAsciiStringTag = ASCII_STRING_TYPE;
   // Interleave bits from both instance types and compare them in one check.
-  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
+  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
   and_(scratch1, kFlatAsciiStringMask);
   and_(scratch2, kFlatAsciiStringMask);
-  shl(scratch1, 8);
-  or_(scratch1, scratch2);
-  cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 8));
+  lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
+  cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 3));
   j(not_equal, failure);
 }
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 2129be3..9e694d2 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1616,7 +1616,9 @@
                                                &try_holey_map);
 
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         // Restore edi.
         __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
         __ jmp(&fast_object);
@@ -1628,7 +1630,9 @@
                                                edi,
                                                &call_builtin);
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         // Restore edi.
         __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
         __ bind(&fast_object);
diff --git a/src/ic.cc b/src/ic.cc
index 5c4150b..0a99772 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -47,7 +47,8 @@
     case MONOMORPHIC: return '1';
     case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
     case POLYMORPHIC: return 'P';
-    case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N';
+    case MEGAMORPHIC: return 'N';
+    case GENERIC: return 'G';
 
     // We never see the debugger states here, because the state is
     // computed from the original code - not the patched code. Let
@@ -772,6 +773,7 @@
     case DEBUG_STUB:
       break;
     case POLYMORPHIC:
+    case GENERIC:
       UNREACHABLE();
       break;
   }
@@ -796,6 +798,7 @@
   }
 
   if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
+    ASSERT(state != GENERIC);
     int argc = target()->arguments_count();
     Handle<Map> map =
         isolate()->factory()->non_strict_arguments_elements_map();
@@ -855,6 +858,7 @@
       } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
         stub = isolate()->builtins()->LoadIC_StringWrapperLength();
       } else if (state != MEGAMORPHIC) {
+        ASSERT(state != GENERIC);
         stub = megamorphic_stub();
       }
       if (!stub.is_null()) {
@@ -879,6 +883,7 @@
       } else if (state == PREMONOMORPHIC) {
         stub = isolate()->builtins()->LoadIC_ArrayLength();
       } else if (state != MEGAMORPHIC) {
+        ASSERT(state != GENERIC);
         stub = megamorphic_stub();
       }
       if (!stub.is_null()) {
@@ -900,6 +905,7 @@
       } else if (state == PREMONOMORPHIC) {
         stub = isolate()->builtins()->LoadIC_FunctionPrototype();
       } else if (state != MEGAMORPHIC) {
+        ASSERT(state != GENERIC);
         stub = megamorphic_stub();
       }
       if (!stub.is_null()) {
@@ -1067,6 +1073,7 @@
     case DEBUG_STUB:
       break;
     case POLYMORPHIC:
+    case GENERIC:
       UNREACHABLE();
       break;
   }
@@ -1336,6 +1343,7 @@
       }
       break;
     case MEGAMORPHIC:
+    case GENERIC:
     case DEBUG_STUB:
       break;
     case MONOMORPHIC_PROTOTYPE_FAILURE:
@@ -1614,6 +1622,7 @@
     case DEBUG_STUB:
       break;
     case POLYMORPHIC:
+    case GENERIC:
       UNREACHABLE();
       break;
   }
@@ -1658,6 +1667,7 @@
         break;
       }
       case MEGAMORPHIC:
+      case GENERIC:
         break;
       case UNINITIALIZED:
       case PREMONOMORPHIC:
@@ -1852,6 +1862,12 @@
     Handle<Code> cached_stub;
     Handle<Map> transitioned_map =
         receiver_map->FindTransitionedMap(receiver_maps);
+
+    // TODO(mvstanton): The code below is doing pessimistic elements
+    // transitions. I would like to stop doing that and rely on Allocation Site
+    // Tracking to do a better job of ensuring the data types are what they need
+    // to be. Not all the elements are in place yet, pessimistic elements
+    // transitions are still important for performance.
     if (!transitioned_map.is_null()) {
       cached_stub = ElementsTransitionAndStoreStub(
           receiver_map->elements_kind(),  // original elements_kind
@@ -2108,6 +2124,7 @@
       }
       break;
     case MEGAMORPHIC:
+    case GENERIC:
     case DEBUG_STUB:
       break;
     case MONOMORPHIC_PROTOTYPE_FAILURE:
@@ -2354,7 +2371,7 @@
     case HEAP_NUMBER:
       return MONOMORPHIC;
     case GENERIC:
-      return MEGAMORPHIC;
+      return ::v8::internal::GENERIC;
   }
   UNREACHABLE();
   return ::v8::internal::UNINITIALIZED;
@@ -2425,7 +2442,7 @@
     case STRING:
       return MONOMORPHIC;
     case GENERIC:
-      return MEGAMORPHIC;
+      return ::v8::internal::GENERIC;
   }
   UNREACHABLE();
   return ::v8::internal::UNINITIALIZED;
diff --git a/src/ic.h b/src/ic.h
index dd81ab4..0cc6aa4 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -97,8 +97,6 @@
   Code* target() const { return GetTargetAtAddress(address()); }
   inline Address address() const;
 
-  virtual bool IsGeneric() const { return false; }
-
   // Compute the current IC state based on the target stub, receiver and name.
   static State StateFrom(Code* target, Object* receiver, Object* name);
 
@@ -519,10 +517,6 @@
       ElementsKind elements_kind,
       KeyedAccessGrowMode grow_mode);
 
-  virtual bool IsGeneric() const {
-    return target() == *generic_stub();
-  }
-
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
 
@@ -680,11 +674,6 @@
       ElementsKind elements_kind,
       KeyedAccessGrowMode grow_mode);
 
-  virtual bool IsGeneric() const {
-    return target() == *generic_stub() ||
-        target() == *generic_stub_strict();
-  }
-
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
 
diff --git a/src/inspector.cc b/src/inspector.cc
deleted file mode 100644
index 833d338..0000000
--- a/src/inspector.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-#include "v8.h"
-#include "inspector.h"
-
-
-namespace v8 {
-namespace internal {
-
-#ifdef INSPECTOR
-
-//============================================================================
-// The Inspector.
-
-void Inspector::DumpObjectType(FILE* out, Object* obj, bool print_more) {
-  // Dump the object pointer.
-  OS::FPrint(out, "%p:", reinterpret_cast<void*>(obj));
-  if (obj->IsHeapObject()) {
-    HeapObject* hobj = HeapObject::cast(obj);
-    OS::FPrint(out, " size %d :", hobj->Size());
-  }
-
-  // Dump each object classification that matches this object.
-#define FOR_EACH_TYPE(type)   \
-  if (obj->Is##type()) {      \
-    OS::FPrint(out, " %s", #type);    \
-  }
-  OBJECT_TYPE_LIST(FOR_EACH_TYPE)
-  HEAP_OBJECT_TYPE_LIST(FOR_EACH_TYPE)
-#undef FOR_EACH_TYPE
-}
-
-
-#endif  // INSPECTOR
-
-} }  // namespace v8::internal
-
diff --git a/src/isolate.cc b/src/isolate.cc
index 2044805..8bcceab 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -408,9 +408,9 @@
 }
 
 
-Isolate* Isolate::GetDefaultIsolateForLocking() {
+v8::Isolate* Isolate::GetDefaultIsolateForLocking() {
   EnsureDefaultIsolate();
-  return default_isolate_;
+  return reinterpret_cast<v8::Isolate*>(default_isolate_);
 }
 
 
@@ -923,7 +923,11 @@
   if (decision != UNKNOWN) return decision == YES;
 
   // Get named access check callback
-  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
+  // TODO(dcarney): revert
+  Map* map = receiver->map();
+  CHECK(map->IsMap());
+  CHECK(map->constructor()->IsJSFunction());
+  JSFunction* constructor = JSFunction::cast(map->constructor());
   if (!constructor->shared()->IsApiFunction()) return false;
 
   Object* data_obj =
@@ -1738,7 +1742,7 @@
     delete deoptimizer_data_;
     deoptimizer_data_ = NULL;
     if (FLAG_preemption) {
-      v8::Locker locker;
+      v8::Locker locker(reinterpret_cast<v8::Isolate*>(this));
       v8::Locker::StopPreemption();
     }
     builtins_.TearDown();
@@ -2029,7 +2033,7 @@
   }
 
   if (FLAG_preemption) {
-    v8::Locker locker;
+    v8::Locker locker(reinterpret_cast<v8::Isolate*>(this));
     v8::Locker::StartPreemption(100);
   }
 
diff --git a/src/isolate.h b/src/isolate.h
index 8d0575c..d43c451 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1070,6 +1070,11 @@
     return &optimizing_compiler_thread_;
   }
 
+  // PreInits and returns a default isolate. Needed when a new thread tries
+  // to create a Locker for the first time (the lock itself is in the isolate).
+  // TODO(svenpanne) This method is on death row...
+  static v8::Isolate* GetDefaultIsolateForLocking();
+
  private:
   Isolate();
 
@@ -1153,10 +1158,6 @@
   // If one does not yet exist, allocate a new one.
   PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
 
-  // PreInits and returns a default isolate. Needed when a new thread tries
-  // to create a Locker for the first time (the lock itself is in the isolate).
-  static Isolate* GetDefaultIsolateForLocking();
-
   // Initializes the current thread to run this Isolate.
   // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
   // at the same time, this should be prevented using external locking.
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index a3efb85..f6e2e7f 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -2875,23 +2875,9 @@
         if (!ignore_case) return set_replacement(NULL);
         // Here, we need to check for characters whose upper and lower cases
         // are outside the Latin-1 range.
-        // TODO(dcarney): Replace this code with a simple
-        // table lookup in unibrow::Latin-1.
-        // TODO(dcarney): Test cases!.
-        unibrow::uchar result;
-        int chars;
-        chars = unibrow::ToLowercase::Convert(quarks[j], 0, &result, NULL);
-        if (chars > 1 ||
-            (chars == 1 && result <= String::kMaxOneByteCharCodeU)) {
-          continue;
+        if (!unibrow::Latin1::NonLatin1CanBeConvertedToLatin1(quarks[j])) {
+          return set_replacement(NULL);
         }
-        chars = unibrow::ToUppercase::Convert(quarks[j], 0, &result, NULL);
-        if (chars > 1 ||
-            (chars == 1 && result <= String::kMaxOneByteCharCodeU)) {
-          continue;
-        }
-        // This character is definitely not in the Latin-1 range.
-        return set_replacement(NULL);
 #endif
       }
     } else {
diff --git a/src/list-inl.h b/src/list-inl.h
index 60a033d..7a84313 100644
--- a/src/list-inl.h
+++ b/src/list-inl.h
@@ -85,8 +85,9 @@
 
 template<typename T, class P>
 void List<T, P>::Resize(int new_capacity, P alloc) {
+  ASSERT_LE(length_, new_capacity);
   T* new_data = NewData(new_capacity, alloc);
-  memcpy(new_data, data_, capacity_ * sizeof(T));
+  memcpy(new_data, data_, length_ * sizeof(T));
   List<T, P>::DeleteData(data_);
   data_ = new_data;
   capacity_ = new_capacity;
@@ -162,6 +163,14 @@
 
 
 template<typename T, class P>
+void List<T, P>::Trim(P alloc) {
+  if (length_ < capacity_ / 4) {
+    Resize(capacity_ / 2, alloc);
+  }
+}
+
+
+template<typename T, class P>
 void List<T, P>::Iterate(void (*callback)(T* x)) {
   for (int i = 0; i < length_; i++) callback(&data_[i]);
 }
diff --git a/src/list.h b/src/list.h
index 7fd4f5c..43d982f 100644
--- a/src/list.h
+++ b/src/list.h
@@ -149,6 +149,9 @@
   // Drop the last 'count' elements from the list.
   INLINE(void RewindBy(int count)) { Rewind(length_ - count); }
 
+  // Halve the capacity if fill level is less than a quarter.
+  INLINE(void Trim(AllocationPolicy allocator = AllocationPolicy()));
+
   bool Contains(const T& elm) const;
   int CountOccurrences(const T& elm, int start, int end) const;
 
diff --git a/src/liveobjectlist-inl.h b/src/liveobjectlist-inl.h
deleted file mode 100644
index 2bc2296..0000000
--- a/src/liveobjectlist-inl.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2011 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_LIVEOBJECTLIST_INL_H_
-#define V8_LIVEOBJECTLIST_INL_H_
-
-#include "v8.h"
-
-#include "liveobjectlist.h"
-
-namespace v8 {
-namespace internal {
-
-#ifdef LIVE_OBJECT_LIST
-
-void LiveObjectList::GCEpilogue() {
-  if (!NeedLOLProcessing()) return;
-  GCEpiloguePrivate();
-}
-
-
-void LiveObjectList::GCPrologue() {
-  if (!NeedLOLProcessing()) return;
-#ifdef VERIFY_LOL
-  if (FLAG_verify_lol) {
-    Verify();
-  }
-#endif
-}
-
-
-void LiveObjectList::IterateElements(ObjectVisitor* v) {
-  if (!NeedLOLProcessing()) return;
-  IterateElementsPrivate(v);
-}
-
-
-void LiveObjectList::ProcessNonLive(HeapObject* obj) {
-  // Only do work if we have at least one list to process.
-  if (last()) DoProcessNonLive(obj);
-}
-
-
-void LiveObjectList::UpdateReferencesForScavengeGC() {
-  if (LiveObjectList::NeedLOLProcessing()) {
-    UpdateLiveObjectListVisitor update_visitor;
-    LiveObjectList::IterateElements(&update_visitor);
-  }
-}
-
-
-LiveObjectList* LiveObjectList::FindLolForId(int id,
-                                             LiveObjectList* start_lol) {
-  if (id != 0) {
-    LiveObjectList* lol = start_lol;
-    while (lol != NULL) {
-      if (lol->id() == id) {
-        return lol;
-      }
-      lol = lol->prev_;
-    }
-  }
-  return NULL;
-}
-
-
-// Iterates the elements in every lol and returns the one that matches the
-// specified key.  If no matching element is found, then it returns NULL.
-template <typename T>
-inline LiveObjectList::Element*
-LiveObjectList::FindElementFor(T (*GetValue)(LiveObjectList::Element*), T key) {
-  LiveObjectList* lol = last();
-  while (lol != NULL) {
-    Element* elements = lol->elements_;
-    for (int i = 0; i < lol->obj_count_; i++) {
-      Element* element = &elements[i];
-      if (GetValue(element) == key) {
-        return element;
-      }
-    }
-    lol = lol->prev_;
-  }
-  return NULL;
-}
-
-
-inline int LiveObjectList::GetElementId(LiveObjectList::Element* element) {
-  return element->id_;
-}
-
-
-inline HeapObject*
-LiveObjectList::GetElementObj(LiveObjectList::Element* element) {
-  return element->obj_;
-}
-
-#endif  // LIVE_OBJECT_LIST
-
-} }  // namespace v8::internal
-
-#endif  // V8_LIVEOBJECTLIST_INL_H_
-
diff --git a/src/liveobjectlist.cc b/src/liveobjectlist.cc
deleted file mode 100644
index 6dbe0a8..0000000
--- a/src/liveobjectlist.cc
+++ /dev/null
@@ -1,2631 +0,0 @@
-// Copyright 2011 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.
-
-#ifdef LIVE_OBJECT_LIST
-
-#include <ctype.h>
-#include <stdlib.h>
-
-#include "v8.h"
-
-#include "checks.h"
-#include "global-handles.h"
-#include "heap.h"
-#include "inspector.h"
-#include "isolate.h"
-#include "list-inl.h"
-#include "liveobjectlist-inl.h"
-#include "string-stream.h"
-#include "v8utils.h"
-#include "v8conversions.h"
-
-namespace v8 {
-namespace internal {
-
-
-typedef int (*RawComparer)(const void*, const void*);
-
-
-#ifdef CHECK_ALL_OBJECT_TYPES
-
-#define DEBUG_LIVE_OBJECT_TYPES(v) \
-  v(Smi, "unexpected: Smi") \
-  \
-  v(CodeCache, "unexpected: CodeCache") \
-  v(BreakPointInfo, "unexpected: BreakPointInfo") \
-  v(DebugInfo, "unexpected: DebugInfo") \
-  v(TypeSwitchInfo, "unexpected: TypeSwitchInfo") \
-  v(SignatureInfo, "unexpected: SignatureInfo") \
-  v(Script, "unexpected: Script") \
-  v(ObjectTemplateInfo, "unexpected: ObjectTemplateInfo") \
-  v(FunctionTemplateInfo, "unexpected: FunctionTemplateInfo") \
-  v(CallHandlerInfo, "unexpected: CallHandlerInfo") \
-  v(InterceptorInfo, "unexpected: InterceptorInfo") \
-  v(AccessCheckInfo, "unexpected: AccessCheckInfo") \
-  v(AccessorInfo, "unexpected: AccessorInfo") \
-  v(ExternalTwoByteString, "unexpected: ExternalTwoByteString") \
-  v(ExternalAsciiString, "unexpected: ExternalAsciiString") \
-  v(ExternalString, "unexpected: ExternalString") \
-  v(SeqTwoByteString, "unexpected: SeqTwoByteString") \
-  v(SeqOneByteString, "unexpected: SeqOneByteString") \
-  v(SeqString, "unexpected: SeqString") \
-  v(JSFunctionResultCache, "unexpected: JSFunctionResultCache") \
-  v(NativeContext, "unexpected: NativeContext") \
-  v(MapCache, "unexpected: MapCache") \
-  v(CodeCacheHashTable, "unexpected: CodeCacheHashTable") \
-  v(CompilationCacheTable, "unexpected: CompilationCacheTable") \
-  v(SymbolTable, "unexpected: SymbolTable") \
-  v(Dictionary, "unexpected: Dictionary") \
-  v(HashTable, "unexpected: HashTable") \
-  v(DescriptorArray, "unexpected: DescriptorArray") \
-  v(ExternalFloatArray, "unexpected: ExternalFloatArray") \
-  v(ExternalUnsignedIntArray, "unexpected: ExternalUnsignedIntArray") \
-  v(ExternalIntArray, "unexpected: ExternalIntArray") \
-  v(ExternalUnsignedShortArray, "unexpected: ExternalUnsignedShortArray") \
-  v(ExternalShortArray, "unexpected: ExternalShortArray") \
-  v(ExternalUnsignedByteArray, "unexpected: ExternalUnsignedByteArray") \
-  v(ExternalByteArray, "unexpected: ExternalByteArray") \
-  v(JSValue, "unexpected: JSValue")
-
-#else
-#define DEBUG_LIVE_OBJECT_TYPES(v)
-#endif
-
-
-#define FOR_EACH_LIVE_OBJECT_TYPE(v) \
-  DEBUG_LIVE_OBJECT_TYPES(v) \
-  \
-  v(JSArray, "JSArray") \
-  v(JSRegExp, "JSRegExp") \
-  v(JSFunction, "JSFunction") \
-  v(JSGlobalObject, "JSGlobal") \
-  v(JSBuiltinsObject, "JSBuiltins") \
-  v(GlobalObject, "Global") \
-  v(JSGlobalProxy, "JSGlobalProxy") \
-  v(JSObject, "JSObject") \
-  \
-  v(Context, "meta: Context") \
-  v(ByteArray, "meta: ByteArray") \
-  v(ExternalPixelArray, "meta: PixelArray") \
-  v(ExternalArray, "meta: ExternalArray") \
-  v(FixedArray, "meta: FixedArray") \
-  v(String, "String") \
-  v(HeapNumber, "HeapNumber") \
-  \
-  v(Code, "meta: Code") \
-  v(Map, "meta: Map") \
-  v(Oddball, "Oddball") \
-  v(Foreign, "meta: Foreign") \
-  v(SharedFunctionInfo, "meta: SharedFunctionInfo") \
-  v(Struct, "meta: Struct") \
-  \
-  v(HeapObject, "HeapObject")
-
-
-enum /* LiveObjectType */ {
-#define DECLARE_OBJECT_TYPE_ENUM(type, name) kType##type,
-  FOR_EACH_LIVE_OBJECT_TYPE(DECLARE_OBJECT_TYPE_ENUM)
-  kInvalidLiveObjType,
-  kNumberOfTypes
-#undef DECLARE_OBJECT_TYPE_ENUM
-};
-
-
-LiveObjectType GetObjectType(HeapObject* heap_obj) {
-  // TODO(mlam): investigate usint Map::instance_type() instead.
-#define CHECK_FOR_OBJECT_TYPE(type, name) \
-  if (heap_obj->Is##type()) return kType##type;
-  FOR_EACH_LIVE_OBJECT_TYPE(CHECK_FOR_OBJECT_TYPE)
-#undef CHECK_FOR_OBJECT_TYPE
-
-  UNREACHABLE();
-  return kInvalidLiveObjType;
-}
-
-
-inline const char* GetObjectTypeDesc(LiveObjectType type) {
-  static const char* const name[kNumberOfTypes] = {
-  #define DEFINE_OBJECT_TYPE_NAME(type, name) name,
-    FOR_EACH_LIVE_OBJECT_TYPE(DEFINE_OBJECT_TYPE_NAME)
-    "invalid"
-  #undef DEFINE_OBJECT_TYPE_NAME
-  };
-  ASSERT(type < kNumberOfTypes);
-  return name[type];
-}
-
-
-const char* GetObjectTypeDesc(HeapObject* heap_obj) {
-  LiveObjectType type = GetObjectType(heap_obj);
-  return GetObjectTypeDesc(type);
-}
-
-
-bool IsOfType(LiveObjectType type, HeapObject* obj) {
-  // Note: there are types that are more general (e.g. JSObject) that would
-  // have passed the Is##type_() test for more specialized types (e.g.
-  // JSFunction).  If we find a more specialized match but we're looking for
-  // the general type, then we should reject the ones that matches the
-  // specialized type.
-#define CHECK_OBJECT_TYPE(type_, name) \
-  if (obj->Is##type_()) return (type == kType##type_);
-
-  FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
-#undef CHECK_OBJECT_TYPE
-
-  return false;
-}
-
-
-const AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1);
-
-static AllocationSpace FindSpaceFor(String* space_str) {
-  SmartArrayPointer<char> s =
-      space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-
-  const char* key_str = *s;
-  switch (key_str[0]) {
-    case 'c':
-      if (strcmp(key_str, "cell") == 0) return CELL_SPACE;
-      if (strcmp(key_str, "code") == 0) return CODE_SPACE;
-      break;
-    case 'l':
-      if (strcmp(key_str, "lo") == 0) return LO_SPACE;
-      break;
-    case 'm':
-      if (strcmp(key_str, "map") == 0) return MAP_SPACE;
-      break;
-    case 'n':
-      if (strcmp(key_str, "new") == 0) return NEW_SPACE;
-      break;
-    case 'o':
-      if (strcmp(key_str, "old-pointer") == 0) return OLD_POINTER_SPACE;
-      if (strcmp(key_str, "old-data") == 0) return OLD_DATA_SPACE;
-      break;
-  }
-  return kInvalidSpace;
-}
-
-
-static bool InSpace(AllocationSpace space, HeapObject* heap_obj) {
-  Heap* heap = ISOLATE->heap();
-  if (space != LO_SPACE) {
-    return heap->InSpace(heap_obj, space);
-  }
-
-  // This is an optimization to speed up the check for an object in the LO
-  // space by exclusion because we know that all object pointers passed in
-  // here are guaranteed to be in the heap.  Hence, it is safe to infer
-  // using an exclusion test.
-  // Note: calling Heap::InSpace(heap_obj, LO_SPACE) is too slow for our
-  // filters.
-  int first_space = static_cast<int>(FIRST_SPACE);
-  int last_space = static_cast<int>(LO_SPACE);
-  for (int sp = first_space; sp < last_space; sp++) {
-    if (heap->InSpace(heap_obj, static_cast<AllocationSpace>(sp))) {
-      return false;
-    }
-  }
-  SLOW_ASSERT(heap->InSpace(heap_obj, LO_SPACE));
-  return true;
-}
-
-
-static LiveObjectType FindTypeFor(String* type_str) {
-  SmartArrayPointer<char> s =
-      type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-
-#define CHECK_OBJECT_TYPE(type_, name) { \
-    const char* type_desc = GetObjectTypeDesc(kType##type_); \
-    const char* key_str = *s; \
-    if (strstr(type_desc, key_str) != NULL) return kType##type_; \
-  }
-  FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
-#undef CHECK_OBJECT_TYPE
-
-  return kInvalidLiveObjType;
-}
-
-
-class LolFilter {
- public:
-  explicit LolFilter(Handle<JSObject> filter_obj);
-
-  inline bool is_active() const { return is_active_; }
-  inline bool Matches(HeapObject* obj) {
-    return !is_active() || MatchesSlow(obj);
-  }
-
- private:
-  void InitTypeFilter(Handle<JSObject> filter_obj);
-  void InitSpaceFilter(Handle<JSObject> filter_obj);
-  void InitPropertyFilter(Handle<JSObject> filter_obj);
-  bool MatchesSlow(HeapObject* obj);
-
-  bool is_active_;
-  LiveObjectType type_;
-  AllocationSpace space_;
-  Handle<String> prop_;
-};
-
-
-LolFilter::LolFilter(Handle<JSObject> filter_obj)
-    : is_active_(false),
-      type_(kInvalidLiveObjType),
-      space_(kInvalidSpace),
-      prop_() {
-  if (filter_obj.is_null()) return;
-
-  InitTypeFilter(filter_obj);
-  InitSpaceFilter(filter_obj);
-  InitPropertyFilter(filter_obj);
-}
-
-
-void LolFilter::InitTypeFilter(Handle<JSObject> filter_obj) {
-  Handle<String> type_sym = FACTORY->LookupAsciiSymbol("type");
-  MaybeObject* maybe_result = filter_obj->GetProperty(*type_sym);
-  Object* type_obj;
-  if (maybe_result->ToObject(&type_obj)) {
-    if (type_obj->IsString()) {
-      String* type_str = String::cast(type_obj);
-      type_ = FindTypeFor(type_str);
-      if (type_ != kInvalidLiveObjType) {
-        is_active_ = true;
-      }
-    }
-  }
-}
-
-
-void LolFilter::InitSpaceFilter(Handle<JSObject> filter_obj) {
-  Handle<String> space_sym = FACTORY->LookupAsciiSymbol("space");
-  MaybeObject* maybe_result = filter_obj->GetProperty(*space_sym);
-  Object* space_obj;
-  if (maybe_result->ToObject(&space_obj)) {
-    if (space_obj->IsString()) {
-      String* space_str = String::cast(space_obj);
-      space_ = FindSpaceFor(space_str);
-      if (space_ != kInvalidSpace) {
-        is_active_ = true;
-      }
-    }
-  }
-}
-
-
-void LolFilter::InitPropertyFilter(Handle<JSObject> filter_obj) {
-  Handle<String> prop_sym = FACTORY->LookupAsciiSymbol("prop");
-  MaybeObject* maybe_result = filter_obj->GetProperty(*prop_sym);
-  Object* prop_obj;
-  if (maybe_result->ToObject(&prop_obj)) {
-    if (prop_obj->IsString()) {
-      prop_ = Handle<String>(String::cast(prop_obj));
-      is_active_ = true;
-    }
-  }
-}
-
-
-bool LolFilter::MatchesSlow(HeapObject* obj) {
-  if ((type_ != kInvalidLiveObjType) && !IsOfType(type_, obj)) {
-    return false;  // Fail because obj is not of the type of interest.
-  }
-  if ((space_ != kInvalidSpace) && !InSpace(space_, obj)) {
-    return false;  // Fail because obj is not in the space of interest.
-  }
-  if (!prop_.is_null() && obj->IsJSObject()) {
-    LookupResult result;
-    obj->Lookup(*prop_, &result);
-    if (!result.IsProperty()) {
-      return false;  // Fail because obj does not have the property of interest.
-    }
-  }
-  return true;
-}
-
-
-class LolIterator {
- public:
-  LolIterator(LiveObjectList* older, LiveObjectList* newer)
-      : older_(older),
-        newer_(newer),
-        curr_(0),
-        elements_(0),
-        count_(0),
-        index_(0) { }
-
-  inline void Init() {
-    SetCurrent(newer_);
-    // If the elements_ list is empty, then move on to the next list as long
-    // as we're not at the last list (indicated by done()).
-    while ((elements_ == NULL) && !Done()) {
-      SetCurrent(curr_->prev_);
-    }
-  }
-
-  inline bool Done() const {
-    return (curr_ == older_);
-  }
-
-  // Object level iteration.
-  inline void Next() {
-    index_++;
-    if (index_ >= count_) {
-      // Iterate backwards until we get to the oldest list.
-      while (!Done()) {
-        SetCurrent(curr_->prev_);
-        // If we have elements to process, we're good to go.
-        if (elements_ != NULL) break;
-
-        // Else, we should advance to the next older list.
-      }
-    }
-  }
-
-  inline int Id() const {
-    return elements_[index_].id_;
-  }
-  inline HeapObject* Obj() const {
-    return elements_[index_].obj_;
-  }
-
-  inline int LolObjCount() const {
-    if (curr_ != NULL) return curr_->obj_count_;
-    return 0;
-  }
-
- protected:
-  inline void SetCurrent(LiveObjectList* new_curr) {
-    curr_ = new_curr;
-    if (curr_ != NULL) {
-      elements_ = curr_->elements_;
-      count_ = curr_->obj_count_;
-      index_ = 0;
-    }
-  }
-
-  LiveObjectList* older_;
-  LiveObjectList* newer_;
-  LiveObjectList* curr_;
-  LiveObjectList::Element* elements_;
-  int count_;
-  int index_;
-};
-
-
-class LolForwardIterator : public LolIterator {
- public:
-  LolForwardIterator(LiveObjectList* first, LiveObjectList* last)
-      : LolIterator(first, last) {
-  }
-
-  inline void Init() {
-    SetCurrent(older_);
-    // If the elements_ list is empty, then move on to the next list as long
-    // as we're not at the last list (indicated by Done()).
-    while ((elements_ == NULL) && !Done()) {
-      SetCurrent(curr_->next_);
-    }
-  }
-
-  inline bool Done() const {
-    return (curr_ == newer_);
-  }
-
-  // Object level iteration.
-  inline void Next() {
-    index_++;
-    if (index_ >= count_) {
-      // Done with current list.  Move on to the next.
-      while (!Done()) {  // If not at the last list already, ...
-        SetCurrent(curr_->next_);
-        // If we have elements to process, we're good to go.
-        if (elements_ != NULL) break;
-
-        // Else, we should advance to the next list.
-      }
-    }
-  }
-};
-
-
-// Minimizes the white space in a string.  Tabs and newlines are replaced
-// with a space where appropriate.
-static int CompactString(char* str) {
-  char* src = str;
-  char* dst = str;
-  char prev_ch = 0;
-  while (*dst != '\0') {
-    char ch = *src++;
-    // We will treat non-ASCII chars as '?'.
-    if ((ch & 0x80) != 0) {
-      ch = '?';
-    }
-    // Compact contiguous whitespace chars into a single ' '.
-    if (isspace(ch)) {
-      if (prev_ch != ' ') *dst++ = ' ';
-      prev_ch = ' ';
-      continue;
-    }
-    *dst++ = ch;
-    prev_ch = ch;
-  }
-  return (dst - str);
-}
-
-
-// Generates a custom description based on the specific type of
-// object we're looking at.  We only generate specialized
-// descriptions where we can.  In all other cases, we emit the
-// generic info.
-static void GenerateObjectDesc(HeapObject* obj,
-                               char* buffer,
-                               int buffer_size) {
-  Vector<char> buffer_v(buffer, buffer_size);
-  ASSERT(obj != NULL);
-  if (obj->IsJSArray()) {
-    JSArray* jsarray = JSArray::cast(obj);
-    double length = jsarray->length()->Number();
-    OS::SNPrintF(buffer_v,
-                 "%p <%s> len %g",
-                 reinterpret_cast<void*>(obj),
-                 GetObjectTypeDesc(obj),
-                 length);
-
-  } else if (obj->IsString()) {
-    String* str = String::cast(obj);
-    // Only grab up to 160 chars in case they are double byte.
-    // We'll only dump 80 of them after we compact them.
-    const int kMaxCharToDump = 80;
-    const int kMaxBufferSize = kMaxCharToDump * 2;
-    SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS,
-                                                    ROBUST_STRING_TRAVERSAL,
-                                                    0,
-                                                    kMaxBufferSize);
-    char* str_cstr = *str_sp;
-    int length = CompactString(str_cstr);
-    OS::SNPrintF(buffer_v,
-                 "%p <%s> '%.80s%s'",
-                 reinterpret_cast<void*>(obj),
-                 GetObjectTypeDesc(obj),
-                 str_cstr,
-                 (length > kMaxCharToDump) ? "..." : "");
-
-  } else if (obj->IsJSFunction() || obj->IsSharedFunctionInfo()) {
-    SharedFunctionInfo* sinfo;
-    if (obj->IsJSFunction()) {
-      JSFunction* func = JSFunction::cast(obj);
-      sinfo = func->shared();
-    } else {
-      sinfo = SharedFunctionInfo::cast(obj);
-    }
-
-    String* name = sinfo->DebugName();
-    SmartArrayPointer<char> name_sp =
-        name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-    char* name_cstr = *name_sp;
-
-    HeapStringAllocator string_allocator;
-    StringStream stream(&string_allocator);
-    sinfo->SourceCodePrint(&stream, 50);
-    SmartArrayPointer<const char> source_sp = stream.ToCString();
-    const char* source_cstr = *source_sp;
-
-    OS::SNPrintF(buffer_v,
-                 "%p <%s> '%s' %s",
-                 reinterpret_cast<void*>(obj),
-                 GetObjectTypeDesc(obj),
-                 name_cstr,
-                 source_cstr);
-
-  } else if (obj->IsFixedArray()) {
-    FixedArray* fixed = FixedArray::cast(obj);
-
-    OS::SNPrintF(buffer_v,
-                 "%p <%s> len %d",
-                 reinterpret_cast<void*>(obj),
-                 GetObjectTypeDesc(obj),
-                 fixed->length());
-
-  } else {
-    OS::SNPrintF(buffer_v,
-                 "%p <%s>",
-                 reinterpret_cast<void*>(obj),
-                 GetObjectTypeDesc(obj));
-  }
-}
-
-
-// Utility function for filling in a line of detail in a verbose dump.
-static bool AddObjDetail(Handle<FixedArray> arr,
-                         int index,
-                         int obj_id,
-                         Handle<HeapObject> target,
-                         const char* desc_str,
-                         Handle<String> id_sym,
-                         Handle<String> desc_sym,
-                         Handle<String> size_sym,
-                         Handle<JSObject> detail,
-                         Handle<String> desc,
-                         Handle<Object> error) {
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  detail = factory->NewJSObject(isolate->object_function());
-  if (detail->IsFailure()) {
-    error = detail;
-    return false;
-  }
-
-  int size = 0;
-  char buffer[512];
-  if (desc_str == NULL) {
-    ASSERT(!target.is_null());
-    HeapObject* obj = *target;
-    GenerateObjectDesc(obj, buffer, sizeof(buffer));
-    desc_str = buffer;
-    size = obj->Size();
-  }
-  desc = factory->NewStringFromAscii(CStrVector(desc_str));
-  if (desc->IsFailure()) {
-    error = desc;
-    return false;
-  }
-
-  { MaybeObject* maybe_result = detail->SetProperty(*id_sym,
-                                                    Smi::FromInt(obj_id),
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return false;
-  }
-  { MaybeObject* maybe_result = detail->SetProperty(*desc_sym,
-                                                    *desc,
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return false;
-  }
-  { MaybeObject* maybe_result = detail->SetProperty(*size_sym,
-                                                    Smi::FromInt(size),
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return false;
-  }
-
-  arr->set(index, *detail);
-  return true;
-}
-
-
-class DumpWriter {
- public:
-  virtual ~DumpWriter() {}
-
-  virtual void ComputeTotalCountAndSize(LolFilter* filter,
-                                        int* count,
-                                        int* size) = 0;
-  virtual bool Write(Handle<FixedArray> elements_arr,
-                     int start,
-                     int dump_limit,
-                     LolFilter* filter,
-                     Handle<Object> error) = 0;
-};
-
-
-class LolDumpWriter: public DumpWriter {
- public:
-  LolDumpWriter(LiveObjectList* older, LiveObjectList* newer)
-      : older_(older), newer_(newer) {
-  }
-
-  void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) {
-    *count = 0;
-    *size = 0;
-
-    LolIterator it(older_, newer_);
-    for (it.Init(); !it.Done(); it.Next()) {
-      HeapObject* heap_obj = it.Obj();
-      if (!filter->Matches(heap_obj)) {
-        continue;
-      }
-
-      *size += heap_obj->Size();
-      (*count)++;
-    }
-  }
-
-  bool Write(Handle<FixedArray> elements_arr,
-             int start,
-             int dump_limit,
-             LolFilter* filter,
-             Handle<Object> error) {
-    // The lols are listed in latest to earliest.  We want to dump from
-    // earliest to latest.  So, compute the last element to start with.
-    int index = 0;
-    int count = 0;
-
-    Isolate* isolate = Isolate::Current();
-    Factory* factory = isolate->factory();
-
-    // Prefetch some needed symbols.
-    Handle<String> id_sym = factory->LookupAsciiSymbol("id");
-    Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
-    Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-
-    // Fill the array with the lol object details.
-    Handle<JSObject> detail;
-    Handle<String> desc;
-    Handle<HeapObject> target;
-
-    LiveObjectList* first_lol = (older_ != NULL) ?
-                                older_->next_ : LiveObjectList::first_;
-    LiveObjectList* last_lol = (newer_ != NULL) ? newer_->next_ : NULL;
-
-    LolForwardIterator it(first_lol, last_lol);
-    for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
-      HeapObject* heap_obj = it.Obj();
-
-      // Skip objects that have been filtered out.
-      if (!filter->Matches(heap_obj)) {
-        continue;
-      }
-
-      // Only report objects that are in the section of interest.
-      if (count >= start) {
-        target = Handle<HeapObject>(heap_obj);
-        bool success = AddObjDetail(elements_arr,
-                                    index++,
-                                    it.Id(),
-                                    target,
-                                    NULL,
-                                    id_sym,
-                                    desc_sym,
-                                    size_sym,
-                                    detail,
-                                    desc,
-                                    error);
-        if (!success) return false;
-      }
-      count++;
-    }
-    return true;
-  }
-
- private:
-  LiveObjectList* older_;
-  LiveObjectList* newer_;
-};
-
-
-class RetainersDumpWriter: public DumpWriter {
- public:
-  RetainersDumpWriter(Handle<HeapObject> target,
-                      Handle<JSObject> instance_filter,
-                      Handle<JSFunction> args_function)
-      : target_(target),
-        instance_filter_(instance_filter),
-        args_function_(args_function) {
-  }
-
-  void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) {
-    Handle<FixedArray> retainers_arr;
-    Handle<Object> error;
-
-    *size = -1;
-    LiveObjectList::GetRetainers(target_,
-                                 instance_filter_,
-                                 retainers_arr,
-                                 0,
-                                 Smi::kMaxValue,
-                                 count,
-                                 filter,
-                                 NULL,
-                                 *args_function_,
-                                 error);
-  }
-
-  bool Write(Handle<FixedArray> elements_arr,
-             int start,
-             int dump_limit,
-             LolFilter* filter,
-             Handle<Object> error) {
-    int dummy;
-    int count;
-
-    // Fill the retainer objects.
-    count = LiveObjectList::GetRetainers(target_,
-                                         instance_filter_,
-                                         elements_arr,
-                                         start,
-                                         dump_limit,
-                                         &dummy,
-                                         filter,
-                                         NULL,
-                                         *args_function_,
-                                         error);
-    if (count < 0) {
-        return false;
-    }
-    return true;
-  }
-
- private:
-  Handle<HeapObject> target_;
-  Handle<JSObject> instance_filter_;
-  Handle<JSFunction> args_function_;
-};
-
-
-class LiveObjectSummary {
- public:
-  explicit LiveObjectSummary(LolFilter* filter)
-      : total_count_(0),
-        total_size_(0),
-        found_root_(false),
-        found_weak_root_(false),
-        filter_(filter) {
-    memset(counts_, 0, sizeof(counts_[0]) * kNumberOfEntries);
-    memset(sizes_, 0, sizeof(sizes_[0]) * kNumberOfEntries);
-  }
-
-  void Add(HeapObject* heap_obj) {
-    int size = heap_obj->Size();
-    LiveObjectType type = GetObjectType(heap_obj);
-    ASSERT(type != kInvalidLiveObjType);
-    counts_[type]++;
-    sizes_[type] += size;
-    total_count_++;
-    total_size_ += size;
-  }
-
-  void set_found_root() { found_root_ = true; }
-  void set_found_weak_root() { found_weak_root_ = true; }
-
-  inline int Count(LiveObjectType type) {
-    return counts_[type];
-  }
-  inline int Size(LiveObjectType type) {
-    return sizes_[type];
-  }
-  inline int total_count() {
-    return total_count_;
-  }
-  inline int total_size() {
-    return total_size_;
-  }
-  inline bool found_root() {
-    return found_root_;
-  }
-  inline bool found_weak_root() {
-    return found_weak_root_;
-  }
-  int GetNumberOfEntries() {
-    int entries = 0;
-    for (int i = 0; i < kNumberOfEntries; i++) {
-      if (counts_[i]) entries++;
-    }
-    return entries;
-  }
-
-  inline LolFilter* filter() { return filter_; }
-
-  static const int kNumberOfEntries = kNumberOfTypes;
-
- private:
-  int counts_[kNumberOfEntries];
-  int sizes_[kNumberOfEntries];
-  int total_count_;
-  int total_size_;
-  bool found_root_;
-  bool found_weak_root_;
-
-  LolFilter* filter_;
-};
-
-
-// Abstraction for a summary writer.
-class SummaryWriter {
- public:
-  virtual ~SummaryWriter() {}
-  virtual void Write(LiveObjectSummary* summary) = 0;
-};
-
-
-// A summary writer for filling in a summary of lol lists and diffs.
-class LolSummaryWriter: public SummaryWriter {
- public:
-  LolSummaryWriter(LiveObjectList* older_lol,
-                   LiveObjectList* newer_lol)
-      : older_(older_lol), newer_(newer_lol) {
-  }
-
-  void Write(LiveObjectSummary* summary) {
-    LolFilter* filter = summary->filter();
-
-    // Fill the summary with the lol object details.
-    LolIterator it(older_, newer_);
-    for (it.Init(); !it.Done(); it.Next()) {
-      HeapObject* heap_obj = it.Obj();
-      if (!filter->Matches(heap_obj)) {
-        continue;
-      }
-      summary->Add(heap_obj);
-    }
-  }
-
- private:
-  LiveObjectList* older_;
-  LiveObjectList* newer_;
-};
-
-
-// A summary writer for filling in a retainers list.
-class RetainersSummaryWriter: public SummaryWriter {
- public:
-  RetainersSummaryWriter(Handle<HeapObject> target,
-                         Handle<JSObject> instance_filter,
-                         Handle<JSFunction> args_function)
-      : target_(target),
-        instance_filter_(instance_filter),
-        args_function_(args_function) {
-  }
-
-  void Write(LiveObjectSummary* summary) {
-    Handle<FixedArray> retainers_arr;
-    Handle<Object> error;
-    int dummy_total_count;
-    LiveObjectList::GetRetainers(target_,
-                                 instance_filter_,
-                                 retainers_arr,
-                                 0,
-                                 Smi::kMaxValue,
-                                 &dummy_total_count,
-                                 summary->filter(),
-                                 summary,
-                                 *args_function_,
-                                 error);
-  }
-
- private:
-  Handle<HeapObject> target_;
-  Handle<JSObject> instance_filter_;
-  Handle<JSFunction> args_function_;
-};
-
-
-uint32_t LiveObjectList::next_element_id_ = 1;
-int LiveObjectList::list_count_ = 0;
-int LiveObjectList::last_id_ = 0;
-LiveObjectList* LiveObjectList::first_ = NULL;
-LiveObjectList* LiveObjectList::last_ = NULL;
-
-
-LiveObjectList::LiveObjectList(LiveObjectList* prev, int capacity)
-    : prev_(prev),
-      next_(NULL),
-      capacity_(capacity),
-      obj_count_(0) {
-  elements_ = NewArray<Element>(capacity);
-  id_ = ++last_id_;
-
-  list_count_++;
-}
-
-
-LiveObjectList::~LiveObjectList() {
-  DeleteArray<Element>(elements_);
-  delete prev_;
-}
-
-
-int LiveObjectList::GetTotalObjCountAndSize(int* size_p) {
-  int size = 0;
-  int count = 0;
-  LiveObjectList* lol = this;
-  do {
-    // Only compute total size if requested i.e. when size_p is not null.
-    if (size_p != NULL) {
-      Element* elements = lol->elements_;
-      for (int i = 0; i < lol->obj_count_; i++) {
-        HeapObject* heap_obj = elements[i].obj_;
-        size += heap_obj->Size();
-      }
-    }
-    count += lol->obj_count_;
-    lol = lol->prev_;
-  } while (lol != NULL);
-
-  if (size_p != NULL) {
-    *size_p = size;
-  }
-  return count;
-}
-
-
-// Adds an object to the lol.
-// Returns true if successful, else returns false.
-bool LiveObjectList::Add(HeapObject* obj) {
-  // If the object is already accounted for in the prev list which we inherit
-  // from, then no need to add it to this list.
-  if ((prev() != NULL) && (prev()->Find(obj) != NULL)) {
-    return true;
-  }
-  ASSERT(obj_count_ <= capacity_);
-  if (obj_count_ == capacity_) {
-    // The heap must have grown and we have more objects than capacity to store
-    // them.
-    return false;  // Fail this addition.
-  }
-  Element& element = elements_[obj_count_++];
-  element.id_ = next_element_id_++;
-  element.obj_ = obj;
-  return true;
-}
-
-
-// Comparator used for sorting and searching the lol.
-int LiveObjectList::CompareElement(const Element* a, const Element* b) {
-  const HeapObject* obj1 = a->obj_;
-  const HeapObject* obj2 = b->obj_;
-  // For lol elements, it doesn't matter which comes first if 2 elements point
-  // to the same object (which gets culled later).  Hence, we only care about
-  // the the greater than / less than relationships.
-  return (obj1 > obj2) ? 1 : (obj1 == obj2) ? 0 : -1;
-}
-
-
-// Looks for the specified object in the lol, and returns its element if found.
-LiveObjectList::Element* LiveObjectList::Find(HeapObject* obj) {
-  LiveObjectList* lol = this;
-  Element key;
-  Element* result = NULL;
-
-  key.obj_ = obj;
-  // Iterate through the chain of lol's to look for the object.
-  while ((result == NULL) && (lol != NULL)) {
-    result = reinterpret_cast<Element*>(
-        bsearch(&key, lol->elements_, lol->obj_count_,
-                sizeof(Element),
-                reinterpret_cast<RawComparer>(CompareElement)));
-    lol = lol->prev_;
-  }
-  return result;
-}
-
-
-// "Nullifies" (convert the HeapObject* into an SMI) so that it will get cleaned
-// up in the GCEpilogue, while preserving the sort order of the lol.
-// NOTE: the lols need to be already sorted before NullifyMostRecent() is
-// called.
-void LiveObjectList::NullifyMostRecent(HeapObject* obj) {
-  LiveObjectList* lol = last();
-  Element key;
-  Element* result = NULL;
-
-  key.obj_ = obj;
-  // Iterate through the chain of lol's to look for the object.
-  while (lol != NULL) {
-    result = reinterpret_cast<Element*>(
-        bsearch(&key, lol->elements_, lol->obj_count_,
-                sizeof(Element),
-                reinterpret_cast<RawComparer>(CompareElement)));
-    if (result != NULL) {
-      // Since there may be more than one (we are nullifying dup's after all),
-      // find the first in the current lol, and nullify that.  The lol should
-      // be sorted already to make this easy (see the use of SortAll()).
-      int i = result - lol->elements_;
-
-      // NOTE: we sort the lol in increasing order.  So, if an object has been
-      // "nullified" (its lowest bit will be cleared to make it look like an
-      // SMI), it would/should show up before the equivalent dups that have not
-      // yet been "nullified".  Hence, we should be searching backwards for the
-      // first occurence of a matching object and nullify that instance.  This
-      // will ensure that we preserve the expected sorting order.
-      for (i--; i > 0; i--) {
-        Element* element = &lol->elements_[i];
-        HeapObject* curr_obj = element->obj_;
-        if (curr_obj != obj) {
-            break;  // No more matches.  Let's move on.
-        }
-        result = element;  // Let this earlier match be the result.
-      }
-
-      // Nullify the object.
-      NullifyNonLivePointer(&result->obj_);
-      return;
-    }
-    lol = lol->prev_;
-  }
-}
-
-
-// Sorts the lol.
-void LiveObjectList::Sort() {
-  if (obj_count_ > 0) {
-    Vector<Element> elements_v(elements_, obj_count_);
-    elements_v.Sort(CompareElement);
-  }
-}
-
-
-// Sorts all captured lols starting from the latest.
-void LiveObjectList::SortAll() {
-  LiveObjectList* lol = last();
-  while (lol != NULL) {
-    lol->Sort();
-    lol = lol->prev_;
-  }
-}
-
-
-// Counts the number of objects in the heap.
-static int CountHeapObjects() {
-  int count = 0;
-  // Iterate over all the heap spaces and count the number of objects.
-  HeapIterator iterator;
-  HeapObject* heap_obj = NULL;
-  while ((heap_obj = iterator.next()) != NULL) {
-    count++;
-  }
-  return count;
-}
-
-
-// Captures a current snapshot of all objects in the heap.
-MaybeObject* LiveObjectList::Capture() {
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  HandleScope scope(isolate);
-
-  // Count the number of objects in the heap.
-  int total_count = CountHeapObjects();
-  int count = total_count;
-  int size = 0;
-
-  LiveObjectList* last_lol = last();
-  if (last_lol != NULL) {
-    count -= last_lol->TotalObjCount();
-  }
-
-  LiveObjectList* lol;
-
-  // Create a lol large enough to track all the objects.
-  lol = new LiveObjectList(last_lol, count);
-  if (lol == NULL) {
-    return NULL;  // No memory to proceed.
-  }
-
-  // The HeapIterator needs to be in its own scope because it disables
-  // allocation, and we need allocate below.
-  {
-    // Iterate over all the heap spaces and add the objects.
-    HeapIterator iterator;
-    HeapObject* heap_obj = NULL;
-    bool failed = false;
-    while (!failed && (heap_obj = iterator.next()) != NULL) {
-      failed = !lol->Add(heap_obj);
-      size += heap_obj->Size();
-    }
-    ASSERT(!failed);
-
-    lol->Sort();
-
-    // Add the current lol to the list of lols.
-    if (last_ != NULL) {
-      last_->next_ = lol;
-    } else {
-      first_ = lol;
-    }
-    last_ = lol;
-
-#ifdef VERIFY_LOL
-    if (FLAG_verify_lol) {
-      Verify(true);
-    }
-#endif
-  }
-
-  Handle<String> id_sym = factory->LookupAsciiSymbol("id");
-  Handle<String> count_sym = factory->LookupAsciiSymbol("count");
-  Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-
-  Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
-  if (result->IsFailure()) return Object::cast(*result);
-
-  { MaybeObject* maybe_result = result->SetProperty(*id_sym,
-                                                    Smi::FromInt(lol->id()),
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-  }
-  { MaybeObject* maybe_result = result->SetProperty(*count_sym,
-                                                    Smi::FromInt(total_count),
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-  }
-  { MaybeObject* maybe_result = result->SetProperty(*size_sym,
-                                                    Smi::FromInt(size),
-                                                    NONE,
-                                                    kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-  }
-
-  return *result;
-}
-
-
-// Delete doesn't actually deletes an lol.  It just marks it as invisible since
-// its contents are considered to be part of subsequent lists as well.  The
-// only time we'll actually delete the lol is when we Reset() or if the lol is
-// invisible, and its element count reaches 0.
-bool LiveObjectList::Delete(int id) {
-  LiveObjectList* lol = last();
-  while (lol != NULL) {
-    if (lol->id() == id) {
-      break;
-    }
-    lol = lol->prev_;
-  }
-
-  // If no lol is found for this id, then we fail to delete.
-  if (lol == NULL) return false;
-
-  // Else, mark the lol as invisible i.e. id == 0.
-  lol->id_ = 0;
-  list_count_--;
-  ASSERT(list_count_ >= 0);
-  if (lol->obj_count_ == 0) {
-    // Point the next lol's prev to this lol's prev.
-    LiveObjectList* next = lol->next_;
-    LiveObjectList* prev = lol->prev_;
-    // Point next's prev to prev.
-    if (next != NULL) {
-      next->prev_ = lol->prev_;
-    } else {
-      last_ = lol->prev_;
-    }
-    // Point prev's next to next.
-    if (prev != NULL) {
-      prev->next_ = lol->next_;
-    } else {
-      first_ = lol->next_;
-    }
-
-    lol->prev_ = NULL;
-    lol->next_ = NULL;
-
-    // Delete this now empty and invisible lol.
-    delete lol;
-  }
-
-  // Just in case we've marked everything invisible, then clean up completely.
-  if (list_count_ == 0) {
-    Reset();
-  }
-
-  return true;
-}
-
-
-MaybeObject* LiveObjectList::Dump(int older_id,
-                                  int newer_id,
-                                  int start_idx,
-                                  int dump_limit,
-                                  Handle<JSObject> filter_obj) {
-  if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) {
-    return Failure::Exception();  // Fail: 0 is not a valid lol id.
-  }
-  if (newer_id < older_id) {
-    // They are not in the expected order.  Swap them.
-    int temp = older_id;
-    older_id = newer_id;
-    newer_id = temp;
-  }
-
-  LiveObjectList* newer_lol = FindLolForId(newer_id, last());
-  LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
-
-  // If the id is defined, and we can't find a LOL for it, then we have an
-  // invalid id.
-  if ((newer_id != 0) && (newer_lol == NULL)) {
-    return Failure::Exception();  // Fail: the newer lol id is invalid.
-  }
-  if ((older_id != 0) && (older_lol == NULL)) {
-    return Failure::Exception();  // Fail: the older lol id is invalid.
-  }
-
-  LolFilter filter(filter_obj);
-  LolDumpWriter writer(older_lol, newer_lol);
-  return DumpPrivate(&writer, start_idx, dump_limit, &filter);
-}
-
-
-MaybeObject* LiveObjectList::DumpPrivate(DumpWriter* writer,
-                                         int start,
-                                         int dump_limit,
-                                         LolFilter* filter) {
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-
-  HandleScope scope(isolate);
-
-  // Calculate the number of entries of the dump.
-  int count = -1;
-  int size = -1;
-  writer->ComputeTotalCountAndSize(filter, &count, &size);
-
-  // Adjust for where to start the dump.
-  if ((start < 0) || (start >= count)) {
-    return Failure::Exception();  // invalid start.
-  }
-
-  int remaining_count = count - start;
-  if (dump_limit > remaining_count) {
-    dump_limit = remaining_count;
-  }
-
-  // Allocate an array to hold the result.
-  Handle<FixedArray> elements_arr = factory->NewFixedArray(dump_limit);
-  if (elements_arr->IsFailure()) return Object::cast(*elements_arr);
-
-  // Fill in the dump.
-  Handle<Object> error;
-  bool success = writer->Write(elements_arr,
-                               start,
-                               dump_limit,
-                               filter,
-                               error);
-  if (!success) return Object::cast(*error);
-
-  MaybeObject* maybe_result;
-
-  // Allocate the result body.
-  Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
-  if (body->IsFailure()) return Object::cast(*body);
-
-  // Set the updated body.count.
-  Handle<String> count_sym = factory->LookupAsciiSymbol("count");
-  maybe_result = body->SetProperty(*count_sym,
-                                   Smi::FromInt(count),
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  // Set the updated body.size if appropriate.
-  if (size >= 0) {
-    Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-    maybe_result = body->SetProperty(*size_sym,
-                                     Smi::FromInt(size),
-                                     NONE,
-                                     kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-  }
-
-  // Set body.first_index.
-  Handle<String> first_sym = factory->LookupAsciiSymbol("first_index");
-  maybe_result = body->SetProperty(*first_sym,
-                                   Smi::FromInt(start),
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  // Allocate the JSArray of the elements.
-  Handle<JSObject> elements = factory->NewJSObject(isolate->array_function());
-  if (elements->IsFailure()) return Object::cast(*elements);
-
-  maybe_result = Handle<JSArray>::cast(elements)->SetContent(*elements_arr);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  // Set body.elements.
-  Handle<String> elements_sym = factory->LookupAsciiSymbol("elements");
-  maybe_result = body->SetProperty(*elements_sym,
-                                   *elements,
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  return *body;
-}
-
-
-MaybeObject* LiveObjectList::Summarize(int older_id,
-                                       int newer_id,
-                                       Handle<JSObject> filter_obj) {
-  if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) {
-    return Failure::Exception();  // Fail: 0 is not a valid lol id.
-  }
-  if (newer_id < older_id) {
-    // They are not in the expected order.  Swap them.
-    int temp = older_id;
-    older_id = newer_id;
-    newer_id = temp;
-  }
-
-  LiveObjectList* newer_lol = FindLolForId(newer_id, last());
-  LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
-
-  // If the id is defined, and we can't find a LOL for it, then we have an
-  // invalid id.
-  if ((newer_id != 0) && (newer_lol == NULL)) {
-    return Failure::Exception();  // Fail: the newer lol id is invalid.
-  }
-  if ((older_id != 0) && (older_lol == NULL)) {
-    return Failure::Exception();  // Fail: the older lol id is invalid.
-  }
-
-  LolFilter filter(filter_obj);
-  LolSummaryWriter writer(older_lol, newer_lol);
-  return SummarizePrivate(&writer, &filter, false);
-}
-
-
-// Creates a summary report for the debugger.
-// Note: the SummaryWriter takes care of iterating over objects and filling in
-// the summary.
-MaybeObject* LiveObjectList::SummarizePrivate(SummaryWriter* writer,
-                                              LolFilter* filter,
-                                              bool is_tracking_roots) {
-  HandleScope scope;
-  MaybeObject* maybe_result;
-
-  LiveObjectSummary summary(filter);
-  writer->Write(&summary);
-
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-
-  // The result body will look like this:
-  // body: {
-  //   count: <total_count>,
-  //   size: <total_size>,
-  //   found_root: <boolean>,       // optional.
-  //   found_weak_root: <boolean>,  // optional.
-  //   summary: [
-  //     {
-  //       desc: "<object type name>",
-  //       count: <count>,
-  //       size: size
-  //     },
-  //     ...
-  //   ]
-  // }
-
-  // Prefetch some needed symbols.
-  Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
-  Handle<String> count_sym = factory->LookupAsciiSymbol("count");
-  Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-  Handle<String> summary_sym = factory->LookupAsciiSymbol("summary");
-
-  // Allocate the summary array.
-  int entries_count = summary.GetNumberOfEntries();
-  Handle<FixedArray> summary_arr =
-      factory->NewFixedArray(entries_count);
-  if (summary_arr->IsFailure()) return Object::cast(*summary_arr);
-
-  int idx = 0;
-  for (int i = 0; i < LiveObjectSummary::kNumberOfEntries; i++) {
-    // Allocate the summary record.
-    Handle<JSObject> detail = factory->NewJSObject(isolate->object_function());
-    if (detail->IsFailure()) return Object::cast(*detail);
-
-    // Fill in the summary record.
-    LiveObjectType type = static_cast<LiveObjectType>(i);
-    int count = summary.Count(type);
-    if (count) {
-      const char* desc_cstr = GetObjectTypeDesc(type);
-      Handle<String> desc = factory->LookupAsciiSymbol(desc_cstr);
-      int size = summary.Size(type);
-
-      maybe_result = detail->SetProperty(*desc_sym,
-                                         *desc,
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-      maybe_result = detail->SetProperty(*count_sym,
-                                         Smi::FromInt(count),
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-      maybe_result = detail->SetProperty(*size_sym,
-                                         Smi::FromInt(size),
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-
-      summary_arr->set(idx++, *detail);
-    }
-  }
-
-  // Wrap the summary fixed array in a JS array.
-  Handle<JSObject> summary_obj =
-    factory->NewJSObject(isolate->array_function());
-  if (summary_obj->IsFailure()) return Object::cast(*summary_obj);
-
-  maybe_result = Handle<JSArray>::cast(summary_obj)->SetContent(*summary_arr);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  // Create the body object.
-  Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
-  if (body->IsFailure()) return Object::cast(*body);
-
-  // Fill out the body object.
-  int total_count = summary.total_count();
-  int total_size = summary.total_size();
-  maybe_result = body->SetProperty(*count_sym,
-                                   Smi::FromInt(total_count),
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  maybe_result = body->SetProperty(*size_sym,
-                                   Smi::FromInt(total_size),
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  if (is_tracking_roots) {
-    int found_root = summary.found_root();
-    int found_weak_root = summary.found_weak_root();
-    Handle<String> root_sym = factory->LookupAsciiSymbol("found_root");
-    Handle<String> weak_root_sym =
-        factory->LookupAsciiSymbol("found_weak_root");
-    maybe_result = body->SetProperty(*root_sym,
-                                     Smi::FromInt(found_root),
-                                     NONE,
-                                     kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-    maybe_result = body->SetProperty(*weak_root_sym,
-                                     Smi::FromInt(found_weak_root),
-                                     NONE,
-                                     kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-  }
-
-  maybe_result = body->SetProperty(*summary_sym,
-                                   *summary_obj,
-                                   NONE,
-                                   kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  return *body;
-}
-
-
-// Returns an array listing the captured lols.
-// Note: only dumps the section starting at start_idx and only up to
-// dump_limit entries.
-MaybeObject* LiveObjectList::Info(int start_idx, int dump_limit) {
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-
-  HandleScope scope(isolate);
-  MaybeObject* maybe_result;
-
-  int total_count = LiveObjectList::list_count();
-  int dump_count = total_count;
-
-  // Adjust for where to start the dump.
-  if (total_count == 0) {
-      start_idx = 0;  // Ensure this to get an empty list.
-  } else if ((start_idx < 0) || (start_idx >= total_count)) {
-    return Failure::Exception();  // invalid start.
-  }
-  dump_count -= start_idx;
-
-  // Adjust for the dump limit.
-  if (dump_count > dump_limit) {
-    dump_count = dump_limit;
-  }
-
-  // Allocate an array to hold the result.
-  Handle<FixedArray> list = factory->NewFixedArray(dump_count);
-  if (list->IsFailure()) return Object::cast(*list);
-
-  // Prefetch some needed symbols.
-  Handle<String> id_sym = factory->LookupAsciiSymbol("id");
-  Handle<String> count_sym = factory->LookupAsciiSymbol("count");
-  Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-
-  // Fill the array with the lol details.
-  int idx = 0;
-  LiveObjectList* lol = first_;
-  while ((lol != NULL) && (idx < start_idx)) {  // Skip tail entries.
-    if (lol->id() != 0) {
-      idx++;
-    }
-    lol = lol->next();
-  }
-  idx = 0;
-  while ((lol != NULL) && (dump_limit != 0)) {
-    if (lol->id() != 0) {
-      int count;
-      int size;
-      count = lol->GetTotalObjCountAndSize(&size);
-
-      Handle<JSObject> detail =
-          factory->NewJSObject(isolate->object_function());
-      if (detail->IsFailure()) return Object::cast(*detail);
-
-      maybe_result = detail->SetProperty(*id_sym,
-                                         Smi::FromInt(lol->id()),
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-      maybe_result = detail->SetProperty(*count_sym,
-                                         Smi::FromInt(count),
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-      maybe_result = detail->SetProperty(*size_sym,
-                                         Smi::FromInt(size),
-                                         NONE,
-                                         kNonStrictMode);
-      if (maybe_result->IsFailure()) return maybe_result;
-      list->set(idx++, *detail);
-      dump_limit--;
-    }
-    lol = lol->next();
-  }
-
-  // Return the result as a JS array.
-  Handle<JSObject> lols = factory->NewJSObject(isolate->array_function());
-
-  maybe_result = Handle<JSArray>::cast(lols)->SetContent(*list);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
-  if (result->IsFailure()) return Object::cast(*result);
-
-  maybe_result = result->SetProperty(*count_sym,
-                                     Smi::FromInt(total_count),
-                                     NONE,
-                                     kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  Handle<String> first_sym = factory->LookupAsciiSymbol("first_index");
-  maybe_result = result->SetProperty(*first_sym,
-                                     Smi::FromInt(start_idx),
-                                     NONE,
-                                     kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  Handle<String> lists_sym = factory->LookupAsciiSymbol("lists");
-  maybe_result = result->SetProperty(*lists_sym,
-                                     *lols,
-                                     NONE,
-                                     kNonStrictMode);
-  if (maybe_result->IsFailure()) return maybe_result;
-
-  return *result;
-}
-
-
-// Deletes all captured lols.
-void LiveObjectList::Reset() {
-  LiveObjectList* lol = last();
-  // Just delete the last.  Each lol will delete it's prev automatically.
-  delete lol;
-
-  next_element_id_ = 1;
-  list_count_ = 0;
-  last_id_ = 0;
-  first_ = NULL;
-  last_ = NULL;
-}
-
-
-// Gets the object for the specified obj id.
-Object* LiveObjectList::GetObj(int obj_id) {
-  Element* element = FindElementFor<int>(GetElementId, obj_id);
-  if (element != NULL) {
-    return Object::cast(element->obj_);
-  }
-  return HEAP->undefined_value();
-}
-
-
-// Gets the obj id for the specified address if valid.
-int LiveObjectList::GetObjId(Object* obj) {
-  // Make a heap object pointer from the address.
-  HeapObject* hobj = HeapObject::cast(obj);
-  Element* element = FindElementFor<HeapObject*>(GetElementObj, hobj);
-  if (element != NULL) {
-    return element->id_;
-  }
-  return 0;  // Invalid address.
-}
-
-
-// Gets the obj id for the specified address if valid.
-Object* LiveObjectList::GetObjId(Handle<String> address) {
-  SmartArrayPointer<char> addr_str =
-      address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-
-  Isolate* isolate = Isolate::Current();
-
-  // Extract the address value from the string.
-  int value =
-      static_cast<int>(StringToInt(isolate->unicode_cache(), *address, 16));
-  Object* obj = reinterpret_cast<Object*>(value);
-  return Smi::FromInt(GetObjId(obj));
-}
-
-
-// Helper class for copying HeapObjects.
-class LolVisitor: public ObjectVisitor {
- public:
-  LolVisitor(HeapObject* target, Handle<HeapObject> handle_to_skip)
-      : target_(target), handle_to_skip_(handle_to_skip), found_(false) {}
-
-  void VisitPointer(Object** p) { CheckPointer(p); }
-
-  void VisitPointers(Object** start, Object** end) {
-    // Check all HeapObject pointers in [start, end).
-    for (Object** p = start; !found() && p < end; p++) CheckPointer(p);
-  }
-
-  inline bool found() const { return found_; }
-  inline bool reset() { return found_ = false; }
-
- private:
-  inline void CheckPointer(Object** p) {
-    Object* object = *p;
-    if (HeapObject::cast(object) == target_) {
-      // We may want to skip this handle because the handle may be a local
-      // handle in a handle scope in one of our callers.  Once we return,
-      // that handle will be popped.  Hence, we don't want to count it as
-      // a root that would have kept the target object alive.
-      if (!handle_to_skip_.is_null() &&
-          handle_to_skip_.location() == reinterpret_cast<HeapObject**>(p)) {
-        return;  // Skip this handle.
-      }
-      found_ = true;
-    }
-  }
-
-  HeapObject* target_;
-  Handle<HeapObject> handle_to_skip_;
-  bool found_;
-};
-
-
-inline bool AddRootRetainerIfFound(const LolVisitor& visitor,
-                                   LolFilter* filter,
-                                   LiveObjectSummary* summary,
-                                   void (*SetRootFound)(LiveObjectSummary* s),
-                                   int start,
-                                   int dump_limit,
-                                   int* total_count,
-                                   Handle<FixedArray> retainers_arr,
-                                   int* count,
-                                   int* index,
-                                   const char* root_name,
-                                   Handle<String> id_sym,
-                                   Handle<String> desc_sym,
-                                   Handle<String> size_sym,
-                                   Handle<Object> error) {
-  HandleScope scope;
-
-  // Scratch handles.
-  Handle<JSObject> detail;
-  Handle<String> desc;
-  Handle<HeapObject> retainer;
-
-  if (visitor.found()) {
-    if (!filter->is_active()) {
-      (*total_count)++;
-      if (summary) {
-        SetRootFound(summary);
-      } else if ((*total_count > start) && ((*index) < dump_limit)) {
-        (*count)++;
-        if (!retainers_arr.is_null()) {
-          return AddObjDetail(retainers_arr,
-                              (*index)++,
-                              0,
-                              retainer,
-                              root_name,
-                              id_sym,
-                              desc_sym,
-                              size_sym,
-                              detail,
-                              desc,
-                              error);
-        }
-      }
-    }
-  }
-  return true;
-}
-
-
-inline void SetFoundRoot(LiveObjectSummary* summary) {
-  summary->set_found_root();
-}
-
-
-inline void SetFoundWeakRoot(LiveObjectSummary* summary) {
-  summary->set_found_weak_root();
-}
-
-
-int LiveObjectList::GetRetainers(Handle<HeapObject> target,
-                                 Handle<JSObject> instance_filter,
-                                 Handle<FixedArray> retainers_arr,
-                                 int start,
-                                 int dump_limit,
-                                 int* total_count,
-                                 LolFilter* filter,
-                                 LiveObjectSummary* summary,
-                                 JSFunction* arguments_function,
-                                 Handle<Object> error) {
-  HandleScope scope;
-
-  // Scratch handles.
-  Handle<JSObject> detail;
-  Handle<String> desc;
-  Handle<HeapObject> retainer;
-
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-
-  // Prefetch some needed symbols.
-  Handle<String> id_sym = factory->LookupAsciiSymbol("id");
-  Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
-  Handle<String> size_sym = factory->LookupAsciiSymbol("size");
-
-  NoHandleAllocation ha;
-  int count = 0;
-  int index = 0;
-  Handle<JSObject> last_obj;
-
-  *total_count = 0;
-
-  // Iterate roots.
-  LolVisitor lol_visitor(*target, target);
-  isolate->heap()->IterateStrongRoots(&lol_visitor, VISIT_ALL);
-  if (!AddRootRetainerIfFound(lol_visitor,
-                              filter,
-                              summary,
-                              SetFoundRoot,
-                              start,
-                              dump_limit,
-                              total_count,
-                              retainers_arr,
-                              &count,
-                              &index,
-                              "<root>",
-                              id_sym,
-                              desc_sym,
-                              size_sym,
-                              error)) {
-    return -1;
-  }
-
-  lol_visitor.reset();
-  isolate->heap()->IterateWeakRoots(&lol_visitor, VISIT_ALL);
-  if (!AddRootRetainerIfFound(lol_visitor,
-                              filter,
-                              summary,
-                              SetFoundWeakRoot,
-                              start,
-                              dump_limit,
-                              total_count,
-                              retainers_arr,
-                              &count,
-                              &index,
-                              "<weak root>",
-                              id_sym,
-                              desc_sym,
-                              size_sym,
-                              error)) {
-    return -1;
-  }
-
-  // Iterate the live object lists.
-  LolIterator it(NULL, last());
-  for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
-    HeapObject* heap_obj = it.Obj();
-
-    // Only look at all JSObjects.
-    if (heap_obj->IsJSObject()) {
-      // Skip context extension objects and argument arrays as these are
-      // checked in the context of functions using them.
-      JSObject* obj = JSObject::cast(heap_obj);
-      if (obj->IsJSContextExtensionObject() ||
-          obj->map()->constructor() == arguments_function) {
-        continue;
-      }
-
-      // Check if the JS object has a reference to the object looked for.
-      if (obj->ReferencesObject(*target)) {
-        // Check instance filter if supplied. This is normally used to avoid
-        // references from mirror objects (see Runtime_IsInPrototypeChain).
-        if (!instance_filter->IsUndefined()) {
-          Object* V = obj;
-          while (true) {
-            Object* prototype = V->GetPrototype();
-            if (prototype->IsNull()) {
-              break;
-            }
-            if (*instance_filter == prototype) {
-              obj = NULL;  // Don't add this object.
-              break;
-            }
-            V = prototype;
-          }
-        }
-
-        if (obj != NULL) {
-          // Skip objects that have been filtered out.
-          if (filter->Matches(heap_obj)) {
-            continue;
-          }
-
-          // Valid reference found add to instance array if supplied an update
-          // count.
-          last_obj = Handle<JSObject>(obj);
-          (*total_count)++;
-
-          if (summary != NULL) {
-            summary->Add(heap_obj);
-          } else if ((*total_count > start) && (index < dump_limit)) {
-            count++;
-            if (!retainers_arr.is_null()) {
-              retainer = Handle<HeapObject>(heap_obj);
-              bool success = AddObjDetail(retainers_arr,
-                                          index++,
-                                          it.Id(),
-                                          retainer,
-                                          NULL,
-                                          id_sym,
-                                          desc_sym,
-                                          size_sym,
-                                          detail,
-                                          desc,
-                                          error);
-              if (!success) return -1;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // Check for circular reference only. This can happen when the object is only
-  // referenced from mirrors and has a circular reference in which case the
-  // object is not really alive and would have been garbage collected if not
-  // referenced from the mirror.
-
-  if (*total_count == 1 && !last_obj.is_null() && *last_obj == *target) {
-    count = 0;
-    *total_count = 0;
-  }
-
-  return count;
-}
-
-
-MaybeObject* LiveObjectList::GetObjRetainers(int obj_id,
-                                             Handle<JSObject> instance_filter,
-                                             bool verbose,
-                                             int start,
-                                             int dump_limit,
-                                             Handle<JSObject> filter_obj) {
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  Heap* heap = isolate->heap();
-
-  HandleScope scope(isolate);
-
-  // Get the target object.
-  HeapObject* heap_obj = HeapObject::cast(GetObj(obj_id));
-  if (heap_obj == heap->undefined_value()) {
-    return heap_obj;
-  }
-
-  Handle<HeapObject> target = Handle<HeapObject>(heap_obj);
-
-  // Get the constructor function for context extension and arguments array.
-  JSObject* arguments_boilerplate =
-      isolate->context()->native_context()->arguments_boilerplate();
-  JSFunction* arguments_function =
-      JSFunction::cast(arguments_boilerplate->map()->constructor());
-
-  Handle<JSFunction> args_function = Handle<JSFunction>(arguments_function);
-  LolFilter filter(filter_obj);
-
-  if (!verbose) {
-    RetainersSummaryWriter writer(target, instance_filter, args_function);
-    return SummarizePrivate(&writer, &filter, true);
-
-  } else {
-    RetainersDumpWriter writer(target, instance_filter, args_function);
-    Object* body_obj;
-    MaybeObject* maybe_result =
-        DumpPrivate(&writer, start, dump_limit, &filter);
-    if (!maybe_result->ToObject(&body_obj)) {
-      return maybe_result;
-    }
-
-    // Set body.id.
-    Handle<JSObject> body = Handle<JSObject>(JSObject::cast(body_obj));
-    Handle<String> id_sym = factory->LookupAsciiSymbol("id");
-    maybe_result = body->SetProperty(*id_sym,
-                                     Smi::FromInt(obj_id),
-                                     NONE,
-                                     kNonStrictMode);
-    if (maybe_result->IsFailure()) return maybe_result;
-
-    return *body;
-  }
-}
-
-
-Object* LiveObjectList::PrintObj(int obj_id) {
-  Object* obj = GetObj(obj_id);
-  if (!obj) {
-    return HEAP->undefined_value();
-  }
-
-  EmbeddedVector<char, 128> temp_filename;
-  static int temp_count = 0;
-  const char* path_prefix = ".";
-
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  Heap* heap = isolate->heap();
-
-  if (FLAG_lol_workdir) {
-    path_prefix = FLAG_lol_workdir;
-  }
-  OS::SNPrintF(temp_filename, "%s/lol-print-%d", path_prefix, ++temp_count);
-
-  FILE* f = OS::FOpen(temp_filename.start(), "w+");
-
-  PrintF(f, "@%d ", LiveObjectList::GetObjId(obj));
-#ifdef OBJECT_PRINT
-#ifdef INSPECTOR
-  Inspector::DumpObjectType(f, obj);
-#endif  // INSPECTOR
-  PrintF(f, "\n");
-  obj->Print(f);
-#else  // !OBJECT_PRINT
-  obj->ShortPrint(f);
-#endif  // !OBJECT_PRINT
-  PrintF(f, "\n");
-  Flush(f);
-  fclose(f);
-
-  // Create a string from the temp_file.
-  // Note: the mmapped resource will take care of closing the file.
-  MemoryMappedExternalResource* resource =
-      new MemoryMappedExternalResource(temp_filename.start(), true);
-  if (resource->exists() && !resource->is_empty()) {
-    ASSERT(resource->IsAscii());
-    Handle<String> dump_string =
-        factory->NewExternalStringFromAscii(resource);
-    heap->external_string_table()->AddString(*dump_string);
-    return *dump_string;
-  } else {
-    delete resource;
-  }
-  return HEAP->undefined_value();
-}
-
-
-class LolPathTracer: public PathTracer {
- public:
-  LolPathTracer(FILE* out,
-                Object* search_target,
-                WhatToFind what_to_find)
-      : PathTracer(search_target, what_to_find, VISIT_ONLY_STRONG), out_(out) {}
-
- private:
-  void ProcessResults();
-
-  FILE* out_;
-};
-
-
-void LolPathTracer::ProcessResults() {
-  if (found_target_) {
-    PrintF(out_, "=====================================\n");
-    PrintF(out_, "====        Path to object       ====\n");
-    PrintF(out_, "=====================================\n\n");
-
-    ASSERT(!object_stack_.is_empty());
-    Object* prev = NULL;
-    for (int i = 0, index = 0; i < object_stack_.length(); i++) {
-      Object* obj = object_stack_[i];
-
-      // Skip this object if it is basically the internals of the
-      // previous object (which would have dumped its details already).
-      if (prev && prev->IsJSObject() &&
-          (obj != search_target_)) {
-        JSObject* jsobj = JSObject::cast(prev);
-        if (obj->IsFixedArray() &&
-            jsobj->properties() == FixedArray::cast(obj)) {
-          // Skip this one because it would have been printed as the
-          // properties of the last object already.
-          continue;
-        } else if (obj->IsHeapObject() &&
-                   jsobj->elements() == HeapObject::cast(obj)) {
-          // Skip this one because it would have been printed as the
-          // elements of the last object already.
-          continue;
-        }
-      }
-
-      // Print a connecting arrow.
-      if (i > 0) PrintF(out_, "\n     |\n     |\n     V\n\n");
-
-      // Print the object index.
-      PrintF(out_, "[%d] ", ++index);
-
-      // Print the LOL object ID:
-      int id = LiveObjectList::GetObjId(obj);
-      if (id > 0) PrintF(out_, "@%d ", id);
-
-#ifdef OBJECT_PRINT
-#ifdef INSPECTOR
-      Inspector::DumpObjectType(out_, obj);
-#endif  // INSPECTOR
-      PrintF(out_, "\n");
-      obj->Print(out_);
-#else  // !OBJECT_PRINT
-      obj->ShortPrint(out_);
-      PrintF(out_, "\n");
-#endif  // !OBJECT_PRINT
-      Flush(out_);
-    }
-    PrintF(out_, "\n");
-    PrintF(out_, "=====================================\n\n");
-    Flush(out_);
-  }
-}
-
-
-Object* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) {
-  EmbeddedVector<char, 128> temp_filename;
-  static int temp_count = 0;
-  const char* path_prefix = ".";
-
-  if (FLAG_lol_workdir) {
-    path_prefix = FLAG_lol_workdir;
-  }
-  OS::SNPrintF(temp_filename, "%s/lol-getpath-%d", path_prefix, ++temp_count);
-
-  FILE* f = OS::FOpen(temp_filename.start(), "w+");
-
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  Heap* heap = isolate->heap();
-
-  // Save the previous verbosity.
-  bool prev_verbosity = FLAG_use_verbose_printer;
-  FLAG_use_verbose_printer = false;
-
-  // Dump the paths.
-  {
-    // The tracer needs to be scoped because its usage asserts no allocation,
-    // and we need to allocate the result string below.
-    LolPathTracer tracer(f, obj2, LolPathTracer::FIND_FIRST);
-
-    bool found = false;
-    if (obj1 == NULL) {
-      // Check for ObjectGroups that references this object.
-      // TODO(mlam): refactor this to be more modular.
-      {
-        List<ObjectGroup*>* groups = isolate->global_handles()->object_groups();
-        for (int i = 0; i < groups->length(); i++) {
-          ObjectGroup* group = groups->at(i);
-          if (group == NULL) continue;
-
-          bool found_group = false;
-          for (size_t j = 0; j < group->length_; j++) {
-            Object* object = *(group->objects_[j]);
-            HeapObject* hobj = HeapObject::cast(object);
-            if (obj2 == hobj) {
-              found_group = true;
-              break;
-            }
-          }
-
-          if (found_group) {
-            PrintF(f,
-                   "obj %p is a member of object group %p {\n",
-                   reinterpret_cast<void*>(obj2),
-                   reinterpret_cast<void*>(group));
-            for (size_t j = 0; j < group->length_; j++) {
-              Object* object = *(group->objects_[j]);
-              if (!object->IsHeapObject()) continue;
-
-              HeapObject* hobj = HeapObject::cast(object);
-              int id = GetObjId(hobj);
-              if (id != 0) {
-                PrintF(f, "  @%d:", id);
-              } else {
-                PrintF(f, "  <no id>:");
-              }
-
-              char buffer[512];
-              GenerateObjectDesc(hobj, buffer, sizeof(buffer));
-              PrintF(f, " %s", buffer);
-              if (hobj == obj2) {
-                PrintF(f, " <===");
-              }
-              PrintF(f, "\n");
-            }
-            PrintF(f, "}\n");
-          }
-        }
-      }
-
-      PrintF(f, "path from roots to obj %p\n", reinterpret_cast<void*>(obj2));
-      heap->IterateRoots(&tracer, VISIT_ONLY_STRONG);
-      found = tracer.found();
-
-      if (!found) {
-        PrintF(f, "  No paths found. Checking symbol tables ...\n");
-        SymbolTable* symbol_table = HEAP->raw_unchecked_symbol_table();
-        tracer.VisitPointers(reinterpret_cast<Object**>(&symbol_table),
-                             reinterpret_cast<Object**>(&symbol_table)+1);
-        found = tracer.found();
-        if (!found) {
-          symbol_table->IteratePrefix(&tracer);
-          found = tracer.found();
-        }
-      }
-
-      if (!found) {
-        PrintF(f, "  No paths found. Checking weak roots ...\n");
-        // Check weak refs next.
-        isolate->global_handles()->IterateWeakRoots(&tracer);
-        found = tracer.found();
-      }
-
-    } else {
-      PrintF(f, "path from obj %p to obj %p:\n",
-             reinterpret_cast<void*>(obj1), reinterpret_cast<void*>(obj2));
-      tracer.TracePathFrom(reinterpret_cast<Object**>(&obj1));
-      found = tracer.found();
-    }
-
-    if (!found) {
-      PrintF(f, "  No paths found\n\n");
-    }
-  }
-
-  // Flush and clean up the dumped file.
-  Flush(f);
-  fclose(f);
-
-  // Restore the previous verbosity.
-  FLAG_use_verbose_printer = prev_verbosity;
-
-  // Create a string from the temp_file.
-  // Note: the mmapped resource will take care of closing the file.
-  MemoryMappedExternalResource* resource =
-      new MemoryMappedExternalResource(temp_filename.start(), true);
-  if (resource->exists() && !resource->is_empty()) {
-    ASSERT(resource->IsAscii());
-    Handle<String> path_string =
-        factory->NewExternalStringFromAscii(resource);
-    heap->external_string_table()->AddString(*path_string);
-    return *path_string;
-  } else {
-    delete resource;
-  }
-  return heap->undefined_value();
-}
-
-
-Object* LiveObjectList::GetPath(int obj_id1,
-                                int obj_id2,
-                                Handle<JSObject> instance_filter) {
-  HandleScope scope;
-
-  // Get the target object.
-  HeapObject* obj1 = NULL;
-  if (obj_id1 != 0) {
-    obj1 = HeapObject::cast(GetObj(obj_id1));
-    if (obj1 == HEAP->undefined_value()) {
-      return obj1;
-    }
-  }
-
-  HeapObject* obj2 = HeapObject::cast(GetObj(obj_id2));
-  if (obj2 == HEAP->undefined_value()) {
-    return obj2;
-  }
-
-  return GetPathPrivate(obj1, obj2);
-}
-
-
-void LiveObjectList::DoProcessNonLive(HeapObject* obj) {
-  // We should only be called if we have at least one lol to search.
-  ASSERT(last() != NULL);
-  Element* element = last()->Find(obj);
-  if (element != NULL) {
-    NullifyNonLivePointer(&element->obj_);
-  }
-}
-
-
-void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) {
-  LiveObjectList* lol = last();
-  while (lol != NULL) {
-    Element* elements = lol->elements_;
-    int count = lol->obj_count_;
-    for (int i = 0; i < count; i++) {
-      HeapObject** p = &elements[i].obj_;
-      v->VisitPointer(reinterpret_cast<Object** >(p));
-    }
-    lol = lol->prev_;
-  }
-}
-
-
-// Purpose: Called by GCEpilogue to purge duplicates.  Not to be called by
-// anyone else.
-void LiveObjectList::PurgeDuplicates() {
-  bool is_sorted = false;
-  LiveObjectList* lol = last();
-  if (!lol) {
-    return;  // Nothing to purge.
-  }
-
-  int total_count = lol->TotalObjCount();
-  if (!total_count) {
-    return;  // Nothing to purge.
-  }
-
-  Element* elements = NewArray<Element>(total_count);
-  int count = 0;
-
-  // Copy all the object elements into a consecutive array.
-  while (lol) {
-    memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element));
-    count += lol->obj_count_;
-    lol = lol->prev_;
-  }
-  qsort(elements, total_count, sizeof(Element),
-        reinterpret_cast<RawComparer>(CompareElement));
-
-  ASSERT(count == total_count);
-
-  // Iterate over all objects in the consolidated list and check for dups.
-  total_count--;
-  for (int i = 0; i < total_count; ) {
-    Element* curr = &elements[i];
-    HeapObject* curr_obj = curr->obj_;
-    int j = i+1;
-    bool done = false;
-
-    while (!done && (j < total_count)) {
-      // Process if the element's object is still live after the current GC.
-      // Non-live objects will be converted to SMIs i.e. not HeapObjects.
-      if (curr_obj->IsHeapObject()) {
-        Element* next = &elements[j];
-        HeapObject* next_obj = next->obj_;
-        if (next_obj->IsHeapObject()) {
-          if (curr_obj != next_obj) {
-            done = true;
-            continue;  // Live object but no match.  Move on.
-          }
-
-          // NOTE: we've just GCed the LOLs.  Hence, they are no longer sorted.
-          // Since we detected at least one need to search for entries, we'll
-          // sort it to enable the use of NullifyMostRecent() below.  We only
-          // need to sort it once (except for one exception ... see below).
-          if (!is_sorted) {
-            SortAll();
-            is_sorted = true;
-          }
-
-          // We have a match.  Need to nullify the most recent ref to this
-          // object.  We'll keep the oldest ref:
-          // Note: we will nullify the element record in the LOL
-          // database, not in the local sorted copy of the elements.
-          NullifyMostRecent(curr_obj);
-        }
-      }
-      // Either the object was already marked for purging, or we just marked
-      // it.  Either way, if there's more than one dup, then we need to check
-      // the next element for another possible dup against the current as well
-      // before we move on.  So, here we go.
-      j++;
-    }
-
-    // We can move on to checking the match on the next element.
-    i = j;
-  }
-
-  DeleteArray<Element>(elements);
-}
-
-
-// Purpose: Purges dead objects and resorts the LOLs.
-void LiveObjectList::GCEpiloguePrivate() {
-  // Note: During the GC, ConsStrings may be collected and pointers may be
-  // forwarded to its constituent string.  As a result, we may find dupes of
-  // objects references in the LOL list.
-  // Another common way we get dups is that free chunks that have been swept
-  // in the oldGen heap may be kept as ByteArray objects in a free list.
-  //
-  // When we promote live objects from the youngGen, the object may be moved
-  // to the start of these free chunks.  Since there is no free or move event
-  // for the free chunks, their addresses will show up 2 times: once for their
-  // original free ByteArray selves, and once for the newly promoted youngGen
-  // object.  Hence, we can get a duplicate address in the LOL again.
-  //
-  // We need to eliminate these dups because the LOL implementation expects to
-  // only have at most one unique LOL reference to any object at any time.
-  PurgeDuplicates();
-
-  // After the GC, sweep away all free'd Elements and compact.
-  LiveObjectList* prev = NULL;
-  LiveObjectList* next = NULL;
-
-  // Iterating from the youngest lol to the oldest lol.
-  for (LiveObjectList* lol = last(); lol; lol = prev) {
-    Element* elements = lol->elements_;
-    prev = lol->prev();  // Save the prev.
-
-    // Remove any references to collected objects.
-    int i = 0;
-    while (i < lol->obj_count_) {
-      Element& element = elements[i];
-      if (!element.obj_->IsHeapObject()) {
-        // If the HeapObject address was converted into a SMI, then this
-        // is a dead object.  Copy the last element over this one.
-        element = elements[lol->obj_count_ - 1];
-        lol->obj_count_--;
-        // We've just moved the last element into this index.  We'll revisit
-        // this index again.  Hence, no need to increment the iterator.
-      } else {
-        i++;  // Look at the next element next.
-      }
-    }
-
-    int new_count = lol->obj_count_;
-
-    // Check if there are any more elements to keep after purging the dead ones.
-    if (new_count == 0) {
-      DeleteArray<Element>(elements);
-      lol->elements_ = NULL;
-      lol->capacity_ = 0;
-      ASSERT(lol->obj_count_ == 0);
-
-      // If the list is also invisible, the clean up the list as well.
-      if (lol->id_ == 0) {
-        // Point the next lol's prev to this lol's prev.
-        if (next) {
-          next->prev_ = lol->prev_;
-        } else {
-          last_ = lol->prev_;
-        }
-
-        // Delete this now empty and invisible lol.
-        delete lol;
-
-        // Don't point the next to this lol since it is now deleted.
-        // Leave the next pointer pointing to the current lol.
-        continue;
-      }
-
-    } else {
-      // If the obj_count_ is less than the capacity and the difference is
-      // greater than a specified threshold, then we should shrink the list.
-      int diff = lol->capacity_ - new_count;
-      const int kMaxUnusedSpace = 64;
-      if (diff > kMaxUnusedSpace) {  // Threshold for shrinking.
-        // Shrink the list.
-        Element* new_elements = NewArray<Element>(new_count);
-        memcpy(new_elements, elements, new_count * sizeof(Element));
-
-        DeleteArray<Element>(elements);
-        lol->elements_ = new_elements;
-        lol->capacity_ = new_count;
-      }
-      ASSERT(lol->obj_count_ == new_count);
-
-      lol->Sort();  // We've moved objects.  Re-sort in case.
-    }
-
-    // Save the next (for the previous link) in case we need it later.
-    next = lol;
-  }
-
-#ifdef VERIFY_LOL
-  if (FLAG_verify_lol) {
-    Verify();
-  }
-#endif
-}
-
-
-#ifdef VERIFY_LOL
-void LiveObjectList::Verify(bool match_heap_exactly) {
-  OS::Print("Verifying the LiveObjectList database:\n");
-
-  LiveObjectList* lol = last();
-  if (lol == NULL) {
-    OS::Print("  No lol database to verify\n");
-    return;
-  }
-
-  OS::Print("  Preparing the lol database ...\n");
-  int total_count = lol->TotalObjCount();
-
-  Element* elements = NewArray<Element>(total_count);
-  int count = 0;
-
-  // Copy all the object elements into a consecutive array.
-  OS::Print("  Copying the lol database ...\n");
-  while (lol != NULL) {
-    memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element));
-    count += lol->obj_count_;
-    lol = lol->prev_;
-  }
-  qsort(elements, total_count, sizeof(Element),
-        reinterpret_cast<RawComparer>(CompareElement));
-
-  ASSERT(count == total_count);
-
-  // Iterate over all objects in the heap and check for:
-  // 1. object in LOL but not in heap i.e. error.
-  // 2. object in heap but not in LOL (possibly not an error).  Usually
-  //    just means that we don't have the a capture of the latest heap.
-  //    That is unless we did this verify immediately after a capture,
-  //    and specified match_heap_exactly = true.
-
-  int number_of_heap_objects = 0;
-  int number_of_matches = 0;
-  int number_not_in_heap = total_count;
-  int number_not_in_lol = 0;
-
-  OS::Print("  Start verify ...\n");
-  OS::Print("  Verifying ...");
-  Flush();
-  HeapIterator iterator;
-  HeapObject* heap_obj = NULL;
-  while ((heap_obj = iterator.next()) != NULL) {
-    number_of_heap_objects++;
-
-    // Check if the heap_obj is in the lol.
-    Element key;
-    key.obj_ = heap_obj;
-
-    Element* result = reinterpret_cast<Element*>(
-        bsearch(&key, elements, total_count, sizeof(Element),
-                reinterpret_cast<RawComparer>(CompareElement)));
-
-    if (result != NULL) {
-      number_of_matches++;
-      number_not_in_heap--;
-      // Mark it as found by changing it into a SMI (mask off low bit).
-      // Note: we cannot use HeapObject::cast() here because it asserts that
-      // the HeapObject bit is set on the address, but we're unsetting it on
-      // purpose here for our marking.
-      result->obj_ = reinterpret_cast<HeapObject*>(heap_obj->address());
-
-    } else {
-      number_not_in_lol++;
-      if (match_heap_exactly) {
-        OS::Print("heap object %p NOT in lol database\n", heap_obj);
-      }
-    }
-    // Show some sign of life.
-    if (number_of_heap_objects % 1000 == 0) {
-      OS::Print(".");
-      fflush(stdout);
-    }
-  }
-  OS::Print("\n");
-
-  // Reporting lol objects not found in the heap.
-  if (number_not_in_heap) {
-    int found = 0;
-    for (int i = 0; (i < total_count) && (found < number_not_in_heap); i++) {
-      Element& element = elements[i];
-      if (element.obj_->IsHeapObject()) {
-        OS::Print("lol database object [%d of %d] %p NOT in heap\n",
-                  i, total_count, element.obj_);
-        found++;
-      }
-    }
-  }
-
-  DeleteArray<Element>(elements);
-
-  OS::Print("number of objects in lol database %d\n", total_count);
-  OS::Print("number of heap objects .......... %d\n", number_of_heap_objects);
-  OS::Print("number of matches ............... %d\n", number_of_matches);
-  OS::Print("number NOT in heap .............. %d\n", number_not_in_heap);
-  OS::Print("number NOT in lol database ...... %d\n", number_not_in_lol);
-
-  if (number_of_matches != total_count) {
-    OS::Print("  *** ERROR: "
-              "NOT all lol database objects match heap objects.\n");
-  }
-  if (number_not_in_heap != 0) {
-    OS::Print("  *** ERROR: %d lol database objects not found in heap.\n",
-              number_not_in_heap);
-  }
-  if (match_heap_exactly) {
-    if (!(number_not_in_lol == 0)) {
-      OS::Print("  *** ERROR: %d heap objects NOT found in lol database.\n",
-                number_not_in_lol);
-    }
-  }
-
-  ASSERT(number_of_matches == total_count);
-  ASSERT(number_not_in_heap == 0);
-  ASSERT(number_not_in_lol == (number_of_heap_objects - total_count));
-  if (match_heap_exactly) {
-    ASSERT(total_count == number_of_heap_objects);
-    ASSERT(number_not_in_lol == 0);
-  }
-
-  OS::Print("  Verify the lol database is sorted ...\n");
-  lol = last();
-  while (lol != NULL) {
-    Element* elements = lol->elements_;
-    for (int i = 0; i < lol->obj_count_ - 1; i++) {
-      if (elements[i].obj_ >= elements[i+1].obj_) {
-        OS::Print("  *** ERROR: lol %p obj[%d] %p > obj[%d] %p\n",
-                  lol, i, elements[i].obj_, i+1, elements[i+1].obj_);
-      }
-    }
-    lol = lol->prev_;
-  }
-
-  OS::Print("  DONE verifying.\n\n\n");
-}
-
-
-void LiveObjectList::VerifyNotInFromSpace() {
-  OS::Print("VerifyNotInFromSpace() ...\n");
-  LolIterator it(NULL, last());
-  Heap* heap = ISOLATE->heap();
-  int i = 0;
-  for (it.Init(); !it.Done(); it.Next()) {
-    HeapObject* heap_obj = it.Obj();
-    if (heap->InFromSpace(heap_obj)) {
-      OS::Print(" ERROR: VerifyNotInFromSpace: [%d] obj %p in From space %p\n",
-                i++, heap_obj, Heap::new_space()->FromSpaceStart());
-    }
-  }
-}
-#endif  // VERIFY_LOL
-
-
-} }  // namespace v8::internal
-
-#endif  // LIVE_OBJECT_LIST
diff --git a/src/liveobjectlist.h b/src/liveobjectlist.h
deleted file mode 100644
index 1aa9196..0000000
--- a/src/liveobjectlist.h
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2011 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_LIVEOBJECTLIST_H_
-#define V8_LIVEOBJECTLIST_H_
-
-#include "v8.h"
-
-#include "checks.h"
-#include "heap.h"
-#include "objects.h"
-#include "globals.h"
-
-namespace v8 {
-namespace internal {
-
-#ifdef LIVE_OBJECT_LIST
-
-#ifdef DEBUG
-// The following symbol when defined enables thorough verification of lol data.
-// FLAG_verify_lol will also need to set to true to enable the verification.
-#define VERIFY_LOL
-#endif
-
-
-typedef int LiveObjectType;
-class LolFilter;
-class LiveObjectSummary;
-class DumpWriter;
-class SummaryWriter;
-
-
-// The LiveObjectList is both a mechanism for tracking a live capture of
-// objects in the JS heap, as well as is the data structure which represents
-// each of those captures.  Unlike a snapshot, the lol is live.  For example,
-// if an object in a captured lol dies and is collected by the GC, the lol
-// will reflect that the object is no longer available.  The term
-// LiveObjectList (and lol) is used to describe both the mechanism and the
-// data structure depending on context of use.
-//
-// In captured lols, objects are tracked using their address and an object id.
-// The object id is unique.  Once assigned to an object, the object id can never
-// be assigned to another object.  That is unless all captured lols are deleted
-// which allows the user to start over with a fresh set of lols and object ids.
-// The uniqueness of the object ids allows the user to track specific objects
-// and inspect its longevity while debugging JS code in execution.
-//
-// The lol comes with utility functions to capture, dump, summarize, and diff
-// captured lols amongst other functionality.  These functionality are
-// accessible via the v8 debugger interface.
-class LiveObjectList {
- public:
-  inline static void GCEpilogue();
-  inline static void GCPrologue();
-  inline static void IterateElements(ObjectVisitor* v);
-  inline static void ProcessNonLive(HeapObject* obj);
-  inline static void UpdateReferencesForScavengeGC();
-
-  // Note: LOLs can be listed by calling Dump(0, <lol id>), and 2 LOLs can be
-  // compared/diff'ed using Dump(<lol id1>, <lol id2>, ...).  This will yield
-  // a verbose dump of all the objects in the resultant lists.
-  //   Similarly, a summarized result of a LOL listing or a diff can be
-  // attained using the Summarize(0, <lol id>) and Summarize(<lol id1,
-  // <lol id2>, ...) respectively.
-
-  static MaybeObject* Capture();
-  static bool Delete(int id);
-  static MaybeObject* Dump(int id1,
-                           int id2,
-                           int start_idx,
-                           int dump_limit,
-                           Handle<JSObject> filter_obj);
-  static MaybeObject* Info(int start_idx, int dump_limit);
-  static MaybeObject* Summarize(int id1, int id2, Handle<JSObject> filter_obj);
-
-  static void Reset();
-  static Object* GetObj(int obj_id);
-  static int GetObjId(Object* obj);
-  static Object* GetObjId(Handle<String> address);
-  static MaybeObject* GetObjRetainers(int obj_id,
-                                      Handle<JSObject> instance_filter,
-                                      bool verbose,
-                                      int start,
-                                      int count,
-                                      Handle<JSObject> filter_obj);
-
-  static Object* GetPath(int obj_id1,
-                         int obj_id2,
-                         Handle<JSObject> instance_filter);
-  static Object* PrintObj(int obj_id);
-
- private:
-  struct Element {
-    int id_;
-    HeapObject* obj_;
-  };
-
-  explicit LiveObjectList(LiveObjectList* prev, int capacity);
-  ~LiveObjectList();
-
-  static void GCEpiloguePrivate();
-  static void IterateElementsPrivate(ObjectVisitor* v);
-
-  static void DoProcessNonLive(HeapObject* obj);
-
-  static int CompareElement(const Element* a, const Element* b);
-
-  static Object* GetPathPrivate(HeapObject* obj1, HeapObject* obj2);
-
-  static int GetRetainers(Handle<HeapObject> target,
-                          Handle<JSObject> instance_filter,
-                          Handle<FixedArray> retainers_arr,
-                          int start,
-                          int dump_limit,
-                          int* total_count,
-                          LolFilter* filter,
-                          LiveObjectSummary* summary,
-                          JSFunction* arguments_function,
-                          Handle<Object> error);
-
-  static MaybeObject* DumpPrivate(DumpWriter* writer,
-                                  int start,
-                                  int dump_limit,
-                                  LolFilter* filter);
-  static MaybeObject* SummarizePrivate(SummaryWriter* writer,
-                                       LolFilter* filter,
-                                       bool is_tracking_roots);
-
-  static bool NeedLOLProcessing() { return (last() != NULL); }
-  static void NullifyNonLivePointer(HeapObject** p) {
-    // Mask out the low bit that marks this as a heap object.  We'll use this
-    // cleared bit as an indicator that this pointer needs to be collected.
-    //
-    // Meanwhile, we still preserve its approximate value so that we don't
-    // have to resort the elements list all the time.
-    //
-    // Note: Doing so also makes this HeapObject* look like an SMI.  Hence,
-    // GC pointer updater will ignore it when it gets scanned.
-    *p = reinterpret_cast<HeapObject*>((*p)->address());
-  }
-
-  LiveObjectList* prev() { return prev_; }
-  LiveObjectList* next() { return next_; }
-  int id() { return id_; }
-
-  static int list_count() { return list_count_; }
-  static LiveObjectList* last() { return last_; }
-
-  inline static LiveObjectList* FindLolForId(int id, LiveObjectList* start_lol);
-  int TotalObjCount() { return GetTotalObjCountAndSize(NULL); }
-  int GetTotalObjCountAndSize(int* size_p);
-
-  bool Add(HeapObject* obj);
-  Element* Find(HeapObject* obj);
-  static void NullifyMostRecent(HeapObject* obj);
-  void Sort();
-  static void SortAll();
-
-  static void PurgeDuplicates();  // Only to be called by GCEpilogue.
-
-#ifdef VERIFY_LOL
-  static void Verify(bool match_heap_exactly = false);
-  static void VerifyNotInFromSpace();
-#endif
-
-  // Iterates the elements in every lol and returns the one that matches the
-  // specified key.  If no matching element is found, then it returns NULL.
-  template <typename T>
-  inline static LiveObjectList::Element*
-      FindElementFor(T (*GetValue)(LiveObjectList::Element*), T key);
-
-  inline static int GetElementId(Element* element);
-  inline static HeapObject* GetElementObj(Element* element);
-
-  // Instance fields.
-  LiveObjectList* prev_;
-  LiveObjectList* next_;
-  int id_;
-  int capacity_;
-  int obj_count_;
-  Element* elements_;
-
-  // Statics for managing all the lists.
-  static uint32_t next_element_id_;
-  static int list_count_;
-  static int last_id_;
-  static LiveObjectList* first_;
-  static LiveObjectList* last_;
-
-  friend class LolIterator;
-  friend class LolForwardIterator;
-  friend class LolDumpWriter;
-  friend class RetainersDumpWriter;
-  friend class RetainersSummaryWriter;
-  friend class UpdateLiveObjectListVisitor;
-};
-
-
-// Helper class for updating the LiveObjectList HeapObject pointers.
-class UpdateLiveObjectListVisitor: public ObjectVisitor {
- public:
-  void VisitPointer(Object** p) { UpdatePointer(p); }
-
-  void VisitPointers(Object** start, Object** end) {
-    // Copy all HeapObject pointers in [start, end).
-    for (Object** p = start; p < end; p++) UpdatePointer(p);
-  }
-
- private:
-  // Based on Heap::ScavengeObject() but only does forwarding of pointers
-  // to live new space objects, and not actually keep them alive.
-  void UpdatePointer(Object** p) {
-    Object* object = *p;
-    if (!HEAP->InNewSpace(object)) return;
-
-    HeapObject* heap_obj = HeapObject::cast(object);
-    ASSERT(HEAP->InFromSpace(heap_obj));
-
-    // We use the first word (where the map pointer usually is) of a heap
-    // object to record the forwarding pointer.  A forwarding pointer can
-    // point to an old space, the code space, or the to space of the new
-    // generation.
-    MapWord first_word = heap_obj->map_word();
-
-    // If the first word is a forwarding address, the object has already been
-    // copied.
-    if (first_word.IsForwardingAddress()) {
-      *p = first_word.ToForwardingAddress();
-      return;
-
-    // Else, it's a dead object.
-    } else {
-      LiveObjectList::NullifyNonLivePointer(reinterpret_cast<HeapObject**>(p));
-    }
-  }
-};
-
-
-#else  // !LIVE_OBJECT_LIST
-
-
-class LiveObjectList {
- public:
-  inline static void GCEpilogue() {}
-  inline static void GCPrologue() {}
-  inline static void IterateElements(ObjectVisitor* v) {}
-  inline static void ProcessNonLive(HeapObject* obj) {}
-  inline static void UpdateReferencesForScavengeGC() {}
-
-  inline static MaybeObject* Capture() { return HEAP->undefined_value(); }
-  inline static bool Delete(int id) { return false; }
-  inline static MaybeObject* Dump(int id1,
-                                  int id2,
-                                  int start_idx,
-                                  int dump_limit,
-                                  Handle<JSObject> filter_obj) {
-    return HEAP->undefined_value();
-  }
-  inline static MaybeObject* Info(int start_idx, int dump_limit) {
-    return HEAP->undefined_value();
-  }
-  inline static MaybeObject* Summarize(int id1,
-                                       int id2,
-                                       Handle<JSObject> filter_obj) {
-    return HEAP->undefined_value();
-  }
-
-  inline static void Reset() {}
-  inline static Object* GetObj(int obj_id) { return HEAP->undefined_value(); }
-  inline static Object* GetObjId(Handle<String> address) {
-    return HEAP->undefined_value();
-  }
-  inline static MaybeObject* GetObjRetainers(int obj_id,
-                                             Handle<JSObject> instance_filter,
-                                             bool verbose,
-                                             int start,
-                                             int count,
-                                             Handle<JSObject> filter_obj) {
-    return HEAP->undefined_value();
-  }
-
-  inline static Object* GetPath(int obj_id1,
-                                int obj_id2,
-                                Handle<JSObject> instance_filter) {
-    return HEAP->undefined_value();
-  }
-  inline static Object* PrintObj(int obj_id) { return HEAP->undefined_value(); }
-};
-
-
-#endif  // LIVE_OBJECT_LIST
-
-} }  // namespace v8::internal
-
-#endif  // V8_LIVEOBJECTLIST_H_
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index d867197..9606092 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -36,7 +36,6 @@
 #include "heap-profiler.h"
 #include "ic-inl.h"
 #include "incremental-marking.h"
-#include "liveobjectlist-inl.h"
 #include "mark-compact.h"
 #include "objects-visiting.h"
 #include "objects-visiting-inl.h"
@@ -835,8 +834,6 @@
   // GC, because it relies on the new address of certain old space
   // objects (empty string, illegal builtin).
   heap()->isolate()->stub_cache()->Clear();
-
-  heap()->external_string_table_.CleanUp();
 }
 
 
@@ -935,6 +932,16 @@
 }
 
 
+bool CodeFlusher::ContainsCandidate(SharedFunctionInfo* shared_info) {
+  SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
+  while (candidate != NULL) {
+    if (candidate == shared_info) return true;
+    candidate = GetNextCandidate(candidate);
+  }
+  return false;
+}
+
+
 void CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) {
   // The function is no longer a candidate, make sure it gets visited
   // again so that previous flushing decisions are revisited.
@@ -2059,6 +2066,7 @@
   symbol_table->ElementsRemoved(v.PointersRemoved());
   heap()->external_string_table_.Iterate(&v);
   heap()->external_string_table_.CleanUp();
+  heap()->error_object_list_.RemoveUnmarked(heap());
 
   // Process the weak references.
   MarkCompactWeakObjectRetainer mark_compact_object_retainer;
@@ -2583,9 +2591,6 @@
                     size,
                     NEW_SPACE);
     } else {
-      // Process the dead object before we write a NULL into its header.
-      LiveObjectList::ProcessNonLive(object);
-
       // Mark dead objects in the new space with null in their map field.
       Memory::Address_at(object->address()) = NULL;
     }
@@ -2985,7 +2990,6 @@
                              GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS);
     // Update roots.
     heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
-    LiveObjectList::IterateElements(&updating_visitor);
   }
 
   { GCTracer::Scope gc_scope(tracer_,
@@ -3098,6 +3102,9 @@
   heap_->UpdateReferencesInExternalStringTable(
       &UpdateReferenceInExternalStringTableEntry);
 
+  // Update pointers in the new error object list.
+  heap_->error_object_list()->UpdateReferences();
+
   if (!FLAG_watch_ic_patching) {
     // Update JSFunction pointers from the runtime profiler.
     heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
diff --git a/src/mark-compact.h b/src/mark-compact.h
index 8821c3d..b34be6b 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -423,6 +423,10 @@
     if (GetNextCandidate(shared_info) == NULL) {
       SetNextCandidate(shared_info, shared_function_info_candidates_head_);
       shared_function_info_candidates_head_ = shared_info;
+    } else {
+      // TODO(mstarzinger): Active in release mode to flush out problems.
+      // Should be turned back into an ASSERT or removed completely.
+      CHECK(ContainsCandidate(shared_info));
     }
   }
 
@@ -434,6 +438,8 @@
     }
   }
 
+  bool ContainsCandidate(SharedFunctionInfo* shared_info);
+
   void EvictCandidate(SharedFunctionInfo* shared_info);
   void EvictCandidate(JSFunction* function);
 
diff --git a/src/messages.js b/src/messages.js
index d238e3f..4a8143e 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -820,7 +820,7 @@
        %_CallFunction(this.receiver,
                       ownName,
                       ObjectLookupSetter) === this.fun ||
-       this.receiver[ownName] === this.fun)) {
+       %GetDataProperty(this.receiver, ownName) === this.fun)) {
     // To handle DontEnum properties we guess that the method has
     // the same name as the function.
     return ownName;
@@ -829,8 +829,7 @@
   for (var prop in this.receiver) {
     if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun ||
         %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun ||
-        (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) &&
-         this.receiver[prop] === this.fun)) {
+        %GetDataProperty(this.receiver, prop) === this.fun) {
       // If we find more than one match bail out to avoid confusion.
       if (name) {
         return null;
@@ -883,7 +882,8 @@
 }
 
 function CallSiteIsConstructor() {
-  var constructor = this.receiver ? this.receiver.constructor : null;
+  var receiver = this.receiver;
+  var constructor = receiver ? %GetDataProperty(receiver, "constructor") : null;
   if (!constructor) {
     return false;
   }
@@ -933,12 +933,14 @@
     var typeName = GetTypeName(this, true);
     var methodName = this.getMethodName();
     if (functionName) {
-      if (typeName && functionName.indexOf(typeName) != 0) {
+      if (typeName &&
+          %_CallFunction(functionName, typeName, StringIndexOf) != 0) {
         line += typeName + ".";
       }
       line += functionName;
-      if (methodName && functionName.lastIndexOf("." + methodName) !=
-          functionName.length - methodName.length - 1) {
+      if (methodName &&
+          (%_CallFunction(functionName, "." + methodName, StringIndexOf) !=
+           functionName.length - methodName.length - 1)) {
         line += " [as " + methodName + "]";
       }
     } else {
@@ -1016,17 +1018,37 @@
   return eval_origin;
 }
 
-function FormatStackTrace(error, frames) {
-  var lines = [];
+
+function FormatErrorString(error) {
   try {
-    lines.push(error.toString());
+    return %_CallFunction(error, ErrorToString);
   } catch (e) {
     try {
-      lines.push("<error: " + e + ">");
+      return "<error: " + e + ">";
     } catch (ee) {
-      lines.push("<error>");
+      return "<error>";
     }
   }
+}
+
+
+function GetStackFrames(raw_stack) {
+  var frames = new InternalArray();
+  for (var i = 0; i < raw_stack.length; i += 4) {
+    var recv = raw_stack[i];
+    var fun = raw_stack[i + 1];
+    var code = raw_stack[i + 2];
+    var pc = raw_stack[i + 3];
+    var pos = %FunctionGetPositionForOffset(code, pc);
+    frames.push(new CallSite(recv, fun, pos));
+  }
+  return frames;
+}
+
+
+function FormatStackTrace(error_string, frames) {
+  var lines = new InternalArray();
+  lines.push(error_string);
   for (var i = 0; i < frames.length; i++) {
     var frame = frames[i];
     var line;
@@ -1042,25 +1064,9 @@
     }
     lines.push("    at " + line);
   }
-  return lines.join("\n");
+  return %_CallFunction(lines, "\n", ArrayJoin);
 }
 
-function FormatRawStackTrace(error, raw_stack) {
-  var frames = [ ];
-  for (var i = 0; i < raw_stack.length; i += 4) {
-    var recv = raw_stack[i];
-    var fun = raw_stack[i + 1];
-    var code = raw_stack[i + 2];
-    var pc = raw_stack[i + 3];
-    var pos = %FunctionGetPositionForOffset(code, pc);
-    frames.push(new CallSite(recv, fun, pos));
-  }
-  if (IS_FUNCTION($Error.prepareStackTrace)) {
-    return $Error.prepareStackTrace(error, frames);
-  } else {
-    return FormatStackTrace(error, frames);
-  }
-}
 
 function GetTypeName(obj, requireConstructor) {
   var constructor = obj.receiver.constructor;
@@ -1076,24 +1082,51 @@
   return constructorName;
 }
 
+
+// Flag to prevent recursive call of Error.prepareStackTrace.
+var formatting_custom_stack_trace = false;
+
+
 function captureStackTrace(obj, cons_opt) {
   var stackTraceLimit = $Error.stackTraceLimit;
   if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return;
   if (stackTraceLimit < 0 || stackTraceLimit > 10000) {
     stackTraceLimit = 10000;
   }
-  var raw_stack = %CollectStackTrace(obj,
-                                     cons_opt ? cons_opt : captureStackTrace,
-                                     stackTraceLimit);
+  var stack = %CollectStackTrace(obj,
+                                 cons_opt ? cons_opt : captureStackTrace,
+                                 stackTraceLimit);
+
+  // Don't be lazy if the error stack formatting is custom (observable).
+  if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) {
+    var array = [];
+    %MoveArrayContents(GetStackFrames(stack), array);
+    formatting_custom_stack_trace = true;
+    try {
+      obj.stack = $Error.prepareStackTrace(obj, array);
+    } catch (e) {
+      throw e;  // The custom formatting function threw.  Rethrow.
+    } finally {
+      formatting_custom_stack_trace = false;
+    }
+    return;
+  }
+
+  var error_string = FormatErrorString(obj);
   // Note that 'obj' and 'this' maybe different when called on objects that
   // have the error object on its prototype chain.  The getter replaces itself
   // with a data property as soon as the stack trace has been formatted.
+  // The getter must not change the object layout as it may be called after GC.
   var getter = function() {
-    var value = FormatRawStackTrace(obj, raw_stack);
-    raw_stack = void 0;
-    %DefineOrRedefineDataProperty(obj, 'stack', value, NONE);
-    return value;
+    if (IS_STRING(stack)) return stack;
+    // Stack is still a raw array awaiting to be formatted.
+    stack = FormatStackTrace(error_string, GetStackFrames(stack));
+    // Release context value.
+    error_string = void 0;
+    return stack;
   };
+  %MarkOneShotGetter(getter);
+
   // The 'stack' property of the receiver is set as data property.  If
   // the receiver is the same as holder, this accessor pair is replaced.
   var setter = function(v) {
@@ -1240,23 +1273,32 @@
   // error object copy, but can be found on the prototype chain of 'this'.
   // When the stack trace is formatted, this accessor property is replaced by
   // a data property.
+  var error_string = boilerplate.name + ": " + boilerplate.message;
+
+  // The getter must not change the object layout as it may be called after GC.
   function getter() {
     var holder = this;
     while (!IS_ERROR(holder)) {
       holder = %GetPrototype(holder);
       if (holder == null) return MakeSyntaxError('illegal_access', []);
     }
-    var raw_stack = %GetOverflowedRawStackTrace(holder);
-    var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack)
-                                     : void 0;
-    %DefineOrRedefineDataProperty(holder, 'stack', result, NONE);
-    return result;
+    var stack = %GetOverflowedStackTrace(holder);
+    if (IS_STRING(stack)) return stack;
+    if (IS_ARRAY(stack)) {
+      var result = FormatStackTrace(error_string, GetStackFrames(stack));
+      %SetOverflowedStackTrace(holder, result);
+      return result;
+    }
+    return void 0;
   }
+  %MarkOneShotGetter(getter);
 
   // The 'stack' property of the receiver is set as data property.  If
   // the receiver is the same as holder, this accessor pair is replaced.
   function setter(v) {
     %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
+    // Release the stack trace that is stored as hidden property, if exists.
+    %SetOverflowedStackTrace(this, void 0);
   }
 
   %DefineOrRedefineAccessorProperty(
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 3d01be6..bcd068b 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -3965,6 +3965,17 @@
 }
 
 
+static void JumpIfOOM(MacroAssembler* masm,
+                      Register value,
+                      Register scratch,
+                      Label* oom_label) {
+  STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3);
+  STATIC_ASSERT(kFailureTag == 3);
+  __ andi(scratch, value, 0xf);
+  __ Branch(oom_label, eq, scratch, Operand(0xf));
+}
+
+
 void CEntryStub::GenerateCore(MacroAssembler* masm,
                               Label* throw_normal_exception,
                               Label* throw_termination_exception,
@@ -4071,14 +4082,7 @@
   __ Branch(&retry, eq, t0, Operand(zero_reg));
 
   // Special handling of out of memory exceptions.
-  Failure* out_of_memory = Failure::OutOfMemoryException();
-  __ Branch(USE_DELAY_SLOT,
-            throw_out_of_memory_exception,
-            eq,
-            v0,
-            Operand(reinterpret_cast<int32_t>(out_of_memory)));
-  // If we throw the OOM exception, the value of a3 doesn't matter.
-  // Any instruction can be in the delay slot that's not a jump.
+  JumpIfOOM(masm, v0, t0, throw_out_of_memory_exception);
 
   // Retrieve the pending exception and clear the variable.
   __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
@@ -4170,8 +4174,11 @@
   __ sw(a0, MemOperand(a2));
 
   // Set pending exception and v0 to out of memory exception.
-  Failure* out_of_memory = Failure::OutOfMemoryException();
+  Label already_have_failure;
+  JumpIfOOM(masm, v0, t0, &already_have_failure);
+  Failure* out_of_memory = Failure::OutOfMemoryException(0x1);
   __ li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
+  __ bind(&already_have_failure);
   __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
                                       isolate)));
   __ sw(v0, MemOperand(a2));
@@ -6684,6 +6691,11 @@
   __ And(at, t0, Operand(kAsciiDataHintMask));
   __ and_(at, at, t1);
   __ Branch(&ascii_data, ne, at, Operand(zero_reg));
+  __ Xor(t0, t0, Operand(t1));
+  STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
+  __ And(t0, t0, Operand(kOneByteStringTag | kAsciiDataHintTag));
+  __ Branch(&ascii_data, eq, t0,
+      Operand(kOneByteStringTag | kAsciiDataHintTag));
 
   // Allocate a two byte cons string.
   __ AllocateTwoByteConsString(v0, t2, t0, t1, &call_runtime);
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 27835af..1ea8fd9 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -533,9 +533,9 @@
     __ Check(eq, "Non-smi value", at, Operand(zero_reg));
 
     __ lw(at, FieldMemOperand(string, String::kLengthOffset));
-    __ Check(lt, "Index is too large", at, Operand(index));
+    __ Check(lt, "Index is too large", index, Operand(at));
 
-    __ Check(ge, "Index is negative", index, Operand(Smi::FromInt(0)));
+    __ Check(ge, "Index is negative", index, Operand(zero_reg));
 
     __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
     __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
@@ -543,9 +543,9 @@
     __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask));
     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
-    __ Check(eq, "Unexpected string type", at,
-        Operand(encoding == String::ONE_BYTE_ENCODING
-                    ? one_byte_seq_type : two_byte_seq_type));
+    __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING
+        ? one_byte_seq_type : two_byte_seq_type));
+    __ Check(eq, "Unexpected string type", at, Operand(zero_reg));
   }
 
   __ Addu(at,
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 02ca145..4484ed3 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4218,7 +4218,7 @@
   __ Branch(&not_applicable, ne, scratch, Operand(from_map));
 
   __ li(new_map_reg, Operand(to_map));
-  if (IsFastSmiElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) {
+  if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
     __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
     // Write barrier.
     __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
@@ -5620,6 +5620,11 @@
 }
 
 
+void LCodeGen::DoDummyUse(LDummyUse* instr) {
+  // Nothing to see here, move on!
+}
+
+
 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   Register object = ToRegister(instr->object());
   Register key = ToRegister(instr->key());
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 8ce576d..4d9603e 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -682,6 +682,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
+  return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 7f87b02..a9116ef 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -93,6 +93,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(DummyUse)                                   \
   V(ElementsKind)                               \
   V(FastLiteral)                                \
   V(FixedArrayBaseLength)                       \
@@ -401,6 +402,15 @@
 };
 
 
+class LDummyUse: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDummyUse(LOperand* value) {
+    inputs_[0] = value;
+  }
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
+};
+
+
 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index e0c5787..64f3631 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -4944,10 +4944,8 @@
     Register scratch2,
     Label* failure) {
   int kFlatAsciiStringMask =
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask;
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
   int kFlatAsciiStringTag = ASCII_STRING_TYPE;
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
   ASSERT(kFlatAsciiStringTag <= 0xffff);  // Ensure this fits 16-bit immed.
   andi(scratch1, first, kFlatAsciiStringMask);
   Branch(failure, ne, scratch1, Operand(kFlatAsciiStringTag));
@@ -4960,10 +4958,8 @@
                                                             Register scratch,
                                                             Label* failure) {
   int kFlatAsciiStringMask =
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask;
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
   int kFlatAsciiStringTag = ASCII_STRING_TYPE;
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
   And(scratch, type, Operand(kFlatAsciiStringMask));
   Branch(failure, ne, scratch, Operand(kFlatAsciiStringTag));
 }
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index 6ace471..1ae2a7a 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -341,7 +341,17 @@
     __ Or(t0, t0, Operand(0x20));  // Also convert input character.
     __ Branch(&fail, ne, t0, Operand(a3));
     __ Subu(a3, a3, Operand('a'));
+#ifndef ENABLE_LATIN_1
     __ Branch(&fail, hi, a3, Operand('z' - 'a'));  // Is a3 a lowercase letter?
+#else
+    __ Branch(&loop_check, ls, a3, Operand('z' - 'a'));
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ Subu(a3, a3, Operand(224 - 'a'));
+    // Weren't Latin-1 letters.
+    __ Branch(&fail, hi, a3, Operand(254 - 224));
+    // Check for 247.
+    __ Branch(&fail, eq, a3, Operand(247 - 224));
+#endif
 
     __ bind(&loop_check);
     __ Branch(&loop, lt, a0, Operand(a1));
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index e99c45b..593e955 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -474,7 +474,7 @@
 
 void SeqOneByteString::SeqOneByteStringVerify() {
 #ifndef ENABLE_LATIN_1
-  CHECK(!HasOnlyAsciiChars() || String::IsAscii(GetChars(), length()));
+  CHECK(String::IsAscii(GetChars(), length()));
 #endif
 }
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 34983cd..a865edc 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -341,7 +341,12 @@
 
 bool String::HasOnlyAsciiChars() {
   uint32_t type = map()->instance_type();
+#ifndef ENABLE_LATIN_1
+  return (type & kStringEncodingMask) == kOneByteStringTag ||
+         (type & kAsciiDataHintMask) == kAsciiDataHintTag;
+#else
   return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
+#endif
 }
 
 
@@ -3373,6 +3378,11 @@
 }
 
 
+inline bool Map::CanTrackAllocationSite() {
+  return instance_type() == JS_ARRAY_TYPE;
+}
+
+
 void Map::set_owns_descriptors(bool is_shared) {
   set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
 }
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 309cddf..33af403 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -211,7 +211,7 @@
   // when they might be keeping a Context alive, or when the heap is about
   // to be serialized.
   if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
-      && (target->ic_state() == MEGAMORPHIC ||
+      && (target->ic_state() == MEGAMORPHIC || target->ic_state() == GENERIC ||
           target->ic_state() == POLYMORPHIC || heap->flush_monomorphic_ics() ||
           Serializer::enabled() || target->ic_age() != heap->global_ic_age())) {
     IC::Clear(rinfo->pc());
diff --git a/src/objects.cc b/src/objects.cc
index 2f2bd64..1ef8f58 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -627,6 +627,8 @@
         // that even though we may not actually end up loading the named
         // property from the current object, we still check that we have
         // access to it.
+        // TODO(dcarney): revert.
+        CHECK(current->IsJSObject());
         JSObject* checked = JSObject::cast(current);
         if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
           return checked->GetPropertyWithFailedAccessCheck(receiver,
@@ -7508,6 +7510,31 @@
 }
 
 
+// Heuristic: We only need to create allocation site info if the boilerplate
+// elements kind is the initial elements kind.
+AllocationSiteMode AllocationSiteInfo::GetMode(
+    ElementsKind boilerplate_elements_kind) {
+  if (FLAG_track_allocation_sites &&
+      IsFastSmiElementsKind(boilerplate_elements_kind)) {
+    return TRACK_ALLOCATION_SITE;
+  }
+
+  return DONT_TRACK_ALLOCATION_SITE;
+}
+
+
+AllocationSiteMode AllocationSiteInfo::GetMode(ElementsKind from,
+                                               ElementsKind to) {
+  if (FLAG_track_allocation_sites &&
+      IsFastSmiElementsKind(from) &&
+      (IsFastObjectElementsKind(to) || IsFastDoubleElementsKind(to))) {
+    return TRACK_ALLOCATION_SITE;
+  }
+
+  return DONT_TRACK_ALLOCATION_SITE;
+}
+
+
 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   // For array indexes mix the length into the hash as an array index could
   // be zero.
@@ -9036,6 +9063,7 @@
     case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE";
     case POLYMORPHIC: return "POLYMORPHIC";
     case MEGAMORPHIC: return "MEGAMORPHIC";
+    case GENERIC: return "GENERIC";
     case DEBUG_STUB: return "DEBUG_STUB";
   }
   UNREACHABLE();
@@ -9875,6 +9903,10 @@
     ElementsKind kind = HasFastHoleyElements()
         ? FAST_HOLEY_ELEMENTS
         : FAST_ELEMENTS;
+
+    MaybeObject* trans = PossiblyTransitionArrayBoilerplate(kind);
+    if (trans->IsFailure()) return trans;
+
     MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(),
                                                           kind);
     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
@@ -10406,15 +10438,31 @@
 MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate(
     ElementsKind to_kind) {
   MaybeObject* ret = NULL;
-  if (IsJSArray()) {
-    AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this);
-    if (info != NULL) {
-      JSObject* payload = JSObject::cast(info->payload());
-      if (payload->GetElementsKind() != to_kind) {
-        if (IsMoreGeneralElementsKindTransition(payload->GetElementsKind(),
-                                                to_kind)) {
-          ret = payload->TransitionElementsKind(to_kind);
-        }
+  if (!FLAG_track_allocation_sites || !IsJSArray()) {
+    return ret;
+  }
+
+  AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this);
+  if (info == NULL) {
+    return ret;
+  }
+
+  ASSERT(info->payload()->IsJSArray());
+  JSArray* payload = JSArray::cast(info->payload());
+  ElementsKind kind = payload->GetElementsKind();
+  if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
+    // If the array is huge, it's not likely to be defined in a local
+    // function, so we shouldn't make new instances of it very often.
+    uint32_t length = 0;
+    CHECK(payload->length()->ToArrayIndex(&length));
+    if (length <= 8 * 1024) {
+      ret = payload->TransitionElementsKind(to_kind);
+      if (FLAG_trace_track_allocation_sites) {
+        PrintF(
+            "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n",
+            reinterpret_cast<void*>(this),
+            ElementsKindToString(kind),
+            ElementsKindToString(to_kind));
       }
     }
   }
diff --git a/src/objects.h b/src/objects.h
index 8b3bbd4..f9178cc 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -538,46 +538,39 @@
 enum InstanceType {
   // String types.
   SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
-  ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
-                      kSeqStringTag,
+  ASCII_SYMBOL_TYPE = kOneByteStringTag | kSymbolTag | kSeqStringTag,
   CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
-  CONS_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
-                           kConsStringTag,
+  CONS_ASCII_SYMBOL_TYPE = kOneByteStringTag | kSymbolTag | kConsStringTag,
   SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
                                kExternalStringTag | kShortExternalStringTag,
   SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
       kTwoByteStringTag | kSymbolTag | kExternalStringTag |
       kAsciiDataHintTag | kShortExternalStringTag,
-  SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag |
-                                     kExternalStringTag | kSymbolTag |
-                                     kShortExternalStringTag,
+  SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kOneByteStringTag | kExternalStringTag |
+                                     kSymbolTag | kShortExternalStringTag,
   EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
   EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
       kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
   EXTERNAL_ASCII_SYMBOL_TYPE =
-      kOneByteStringTag | kAsciiDataHintTag | kSymbolTag | kExternalStringTag,
+      kOneByteStringTag | kSymbolTag | kExternalStringTag,
   STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
-  ASCII_STRING_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSeqStringTag,
+  ASCII_STRING_TYPE = kOneByteStringTag | kSeqStringTag,
   CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
-  CONS_ASCII_STRING_TYPE =
-      kOneByteStringTag | kAsciiDataHintTag | kConsStringTag,
+  CONS_ASCII_STRING_TYPE = kOneByteStringTag | kConsStringTag,
   SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
-  SLICED_ASCII_STRING_TYPE =
-      kOneByteStringTag | kAsciiDataHintTag | kSlicedStringTag,
+  SLICED_ASCII_STRING_TYPE = kOneByteStringTag | kSlicedStringTag,
   SHORT_EXTERNAL_STRING_TYPE =
       kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag,
   SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
       kTwoByteStringTag | kExternalStringTag |
       kAsciiDataHintTag | kShortExternalStringTag,
   SHORT_EXTERNAL_ASCII_STRING_TYPE =
-      kOneByteStringTag | kAsciiDataHintTag |
-      kExternalStringTag | kShortExternalStringTag,
+      kOneByteStringTag | kExternalStringTag | kShortExternalStringTag,
   EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
   EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
       kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
   // LAST_STRING_TYPE
-  EXTERNAL_ASCII_STRING_TYPE =
-      kOneByteStringTag | kAsciiDataHintTag | kExternalStringTag,
+  EXTERNAL_ASCII_STRING_TYPE = kOneByteStringTag | kExternalStringTag,
   PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,
 
   // Objects allocated in their own spaces (never in new space).
@@ -4988,7 +4981,7 @@
     set_bit_field3(EnumLengthBits::update(bit_field3(), length));
   }
 
-
+  inline bool CanTrackAllocationSite();
   inline bool owns_descriptors();
   inline void set_owns_descriptors(bool is_shared);
   inline bool is_observed();
@@ -6912,9 +6905,10 @@
 };
 
 
-enum AllocationSiteInfoMode {
-  DONT_TRACK_ALLOCATION_SITE_INFO,
-  TRACK_ALLOCATION_SITE_INFO
+enum AllocationSiteMode {
+  DONT_TRACK_ALLOCATION_SITE,
+  TRACK_ALLOCATION_SITE,
+  LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
 };
 
 
@@ -6930,6 +6924,9 @@
   // Returns NULL if no AllocationSiteInfo is available for object.
   static AllocationSiteInfo* FindForJSObject(JSObject* object);
 
+  static AllocationSiteMode GetMode(ElementsKind boilerplate_elements_kind);
+  static AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
+
   static const int kPayloadOffset = HeapObject::kHeaderSize;
   static const int kSize = kPayloadOffset + kPointerSize;
 
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index ce45bab..e89d2cc 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -535,19 +535,20 @@
       // the beginning of the filename or the end of the line.
       do {
         c = getc(fp);
-      } while ((c != EOF) && (c != '\n') && (c != '/'));
+      } while ((c != EOF) && (c != '\n') && (c != '/') && (c != '['));
       if (c == EOF) break;  // EOF: Was unexpected, just exit.
 
       // Process the filename if found.
-      if (c == '/') {
-        ungetc(c, fp);  // Push the '/' back into the stream to be read below.
+      if ((c == '/') || (c == '[')) {
+        // Push the '/' or '[' back into the stream to be read below.
+        ungetc(c, fp);
 
         // Read to the end of the line. Exit if the read fails.
         if (fgets(lib_name, kLibNameLen, fp) == NULL) break;
 
         // Drop the newline character read by fgets. We do not need to check
         // for a zero-length string because we know that we at least read the
-        // '/' character.
+        // '/' or '[' character.
         lib_name[strlen(lib_name) - 1] = '\0';
       } else {
         // No library name found, just record the raw address range.
@@ -1207,7 +1208,9 @@
 #if defined(ANDROID)
     syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF);
 #else
-    syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF);
+    int result = syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF);
+    USE(result);
+    ASSERT(result == 0);
 #endif
   }
 
diff --git a/src/runtime.cc b/src/runtime.cc
index b508ad3..b5f04e3 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -48,7 +48,6 @@
 #include "json-parser.h"
 #include "json-stringifier.h"
 #include "liveedit.h"
-#include "liveobjectlist-inl.h"
 #include "misc-intrinsics.h"
 #include "parser.h"
 #include "platform.h"
@@ -668,7 +667,11 @@
       isolate->heap()->fixed_cow_array_map()) {
     isolate->counters()->cow_arrays_created_runtime()->Increment();
   }
-  return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
+
+  JSObject* boilerplate_object = JSObject::cast(*boilerplate);
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(
+      boilerplate_object->GetElementsKind());
+  return isolate->heap()->CopyJSObject(boilerplate_object, mode);
 }
 
 
@@ -1098,14 +1101,15 @@
 
   PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
   if (attrs == ABSENT) return heap->undefined_value();
-  AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name);
+  AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
+  Handle<AccessorPair> accessors(raw_accessors, isolate);
 
   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
-  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL));
+  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
 
-  if (accessors == NULL) {
+  if (raw_accessors == NULL) {
     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
     // GetProperty does access check.
     Handle<Object> value = GetProperty(obj, name);
@@ -5803,7 +5807,9 @@
 namespace {
 
 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
-
+#ifdef ENABLE_LATIN_1
+static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
+#endif
 
 // Given a word and two range boundaries returns a word with high bit
 // set in every byte iff the corresponding input byte was strictly in
@@ -5817,7 +5823,10 @@
   ASSERT((w & (kOneInEveryByte * 0x7F)) == w);
   // Use strict inequalities since in edge cases the function could be
   // further simplified.
-  ASSERT(0 < m && m < n && n < 0x7F);
+  ASSERT(0 < m && m < n);
+#ifndef ENABLE_LATIN_1
+  ASSERT(n < 0x7F);
+#endif
   // Has high bit set in every w byte less than n.
   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   // Has high bit set in every w byte greater than m.
@@ -5834,7 +5843,11 @@
 
 template <AsciiCaseConversion dir>
 struct FastAsciiConverter {
+#ifdef ENABLE_LATIN_1
+  static bool Convert(char* dst, char* src, int length, bool* changed_out) {
+#else
   static bool Convert(char* dst, char* src, int length) {
+#endif
 #ifdef DEBUG
     char* saved_dst = dst;
     char* saved_src = src;
@@ -5846,12 +5859,18 @@
     const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
     const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
     bool changed = false;
+#ifdef ENABLE_LATIN_1
+    uintptr_t or_acc = 0;
+#endif
     char* const limit = src + length;
 #ifdef V8_HOST_CAN_READ_UNALIGNED
     // Process the prefix of the input that requires no conversion one
     // (machine) word at a time.
     while (src <= limit - sizeof(uintptr_t)) {
       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
+#ifdef ENABLE_LATIN_1
+      or_acc |= w;
+#endif
       if (AsciiRangeMask(w, lo, hi) != 0) {
         changed = true;
         break;
@@ -5864,6 +5883,9 @@
     // required one word at a time.
     while (src <= limit - sizeof(uintptr_t)) {
       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
+#ifdef ENABLE_LATIN_1
+      or_acc |= w;
+#endif
       uintptr_t m = AsciiRangeMask(w, lo, hi);
       // The mask has high (7th) bit set in every byte that needs
       // conversion and we know that the distance between cases is
@@ -5877,6 +5899,9 @@
     // unaligned access is not supported).
     while (src < limit) {
       char c = *src;
+#ifdef ENABLE_LATIN_1
+      or_acc |= c;
+#endif
       if (lo < c && c < hi) {
         c ^= (1 << 5);
         changed = true;
@@ -5885,10 +5910,20 @@
       ++src;
       ++dst;
     }
+#ifdef ENABLE_LATIN_1
+    if ((or_acc & kAsciiMask) != 0) {
+      return false;
+    }
+#endif
 #ifdef DEBUG
     CheckConvert(saved_dst, saved_src, length, changed);
 #endif
+#ifdef ENABLE_LATIN_1
+    *changed_out = changed;
+    return true;
+#else
     return changed;
+#endif
   }
 
 #ifdef DEBUG
@@ -5941,7 +5976,6 @@
   // Assume that the string is not empty; we need this assumption later
   if (length == 0) return s;
 
-#ifndef ENABLE_LATIN_1
   // Simpler handling of ASCII strings.
   //
   // NOTE: This assumes that the upper/lower case of an ASCII
@@ -5954,13 +5988,25 @@
       if (!maybe_o->ToObject(&o)) return maybe_o;
     }
     SeqOneByteString* result = SeqOneByteString::cast(o);
+#ifndef ENABLE_LATIN_1
     bool has_changed_character = ConvertTraits::AsciiConverter::Convert(
         reinterpret_cast<char*>(result->GetChars()),
         reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
         length);
     return has_changed_character ? result : s;
-  }
+#else
+    bool has_changed_character;
+    bool is_ascii = ConvertTraits::AsciiConverter::Convert(
+        reinterpret_cast<char*>(result->GetChars()),
+        reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
+        length,
+        &has_changed_character);
+    // If not ASCII, we discard the result and take the 2 byte path.
+    if (is_ascii) {
+      return has_changed_character ? result : s;
+    }
 #endif
+  }
 
   Object* answer;
   { MaybeObject* maybe_answer =
@@ -12934,206 +12980,6 @@
   return Smi::FromInt(usage);
 }
 
-
-// Captures a live object list from the present heap.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLOLEnabled) {
-#ifdef LIVE_OBJECT_LIST
-  return isolate->heap()->true_value();
-#else
-  return isolate->heap()->false_value();
-#endif
-}
-
-
-// Captures a live object list from the present heap.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CaptureLOL) {
-#ifdef LIVE_OBJECT_LIST
-  return LiveObjectList::Capture();
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Deletes the specified live object list.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
-#ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_ARG_CHECKED(id, 0);
-  bool success = LiveObjectList::Delete(id);
-  return isolate->heap()->ToBoolean(success);
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Generates the response to a debugger request for a dump of the objects
-// contained in the difference between the captured live object lists
-// specified by id1 and id2.
-// If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
-// dumped.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_SMI_ARG_CHECKED(id1, 0);
-  CONVERT_SMI_ARG_CHECKED(id2, 1);
-  CONVERT_SMI_ARG_CHECKED(start, 2);
-  CONVERT_SMI_ARG_CHECKED(count, 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 4);
-  EnterDebugger enter_debugger;
-  return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Gets the specified object as requested by the debugger.
-// This is only used for obj ids shown in live object lists.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
-#ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
-  Object* result = LiveObjectList::GetObj(obj_id);
-  return result;
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Gets the obj id for the specified address if valid.
-// This is only used for obj ids shown in live object lists.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_ARG_HANDLE_CHECKED(String, address, 0);
-  Object* result = LiveObjectList::GetObjId(address);
-  return result;
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Gets the retainers that references the specified object alive.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
-  RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
-  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
-  RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
-  RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi());
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 5);
-
-  Handle<JSObject> instance_filter;
-  if (args[1]->IsJSObject()) {
-    instance_filter = args.at<JSObject>(1);
-  }
-  bool verbose = false;
-  if (args[2]->IsBoolean()) {
-    verbose = args[2]->IsTrue();
-  }
-  int start = 0;
-  if (args[3]->IsSmi()) {
-    start = args.smi_at(3);
-  }
-  int limit = Smi::kMaxValue;
-  if (args[4]->IsSmi()) {
-    limit = args.smi_at(4);
-  }
-
-  return LiveObjectList::GetObjRetainers(obj_id,
-                                         instance_filter,
-                                         verbose,
-                                         start,
-                                         limit,
-                                         filter_obj);
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Gets the reference path between 2 objects.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
-  CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
-  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
-
-  Handle<JSObject> instance_filter;
-  if (args[2]->IsJSObject()) {
-    instance_filter = args.at<JSObject>(2);
-  }
-
-  Object* result =
-      LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter);
-  return result;
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Generates the response to a debugger request for a list of all
-// previously captured live object lists.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
-#ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_ARG_CHECKED(start, 0);
-  CONVERT_SMI_ARG_CHECKED(count, 1);
-  return LiveObjectList::Info(start, count);
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Gets a dump of the specified object as requested by the debugger.
-// This is only used for obj ids shown in live object lists.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
-  Object* result = LiveObjectList::PrintObj(obj_id);
-  return result;
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Resets and releases all previously captured live object lists.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) {
-#ifdef LIVE_OBJECT_LIST
-  LiveObjectList::Reset();
-  return isolate->heap()->undefined_value();
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
-
-// Generates the response to a debugger request for a summary of the types
-// of objects in the difference between the captured live object lists
-// specified by id1 and id2.
-// If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
-// summarized.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
-#ifdef LIVE_OBJECT_LIST
-  HandleScope scope;
-  CONVERT_SMI_ARG_CHECKED(id1, 0);
-  CONVERT_SMI_ARG_CHECKED(id2, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 2);
-
-  EnterDebugger enter_debugger;
-  return LiveObjectList::Summarize(id1, id2, filter_obj);
-#else
-  return isolate->heap()->undefined_value();
-#endif
-}
-
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
@@ -13219,19 +13065,49 @@
 }
 
 
-// Retrieve the raw stack trace collected on stack overflow and delete
-// it since it is used only once to avoid keeping it alive.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedRawStackTrace) {
+// Mark a function to recognize when called after GC to format the stack trace.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MarkOneShotGetter) {
+  ASSERT_EQ(args.length(), 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  HandleScope scope(isolate);
+  Handle<String> key = isolate->factory()->hidden_stack_trace_symbol();
+  JSObject::SetHiddenProperty(fun, key, key);
+  return *fun;
+}
+
+
+// Retrieve the stack trace.  This could be the raw stack trace collected
+// on stack overflow or the already formatted stack trace string.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) {
+  HandleScope scope(isolate);
   ASSERT_EQ(args.length(), 1);
   CONVERT_ARG_CHECKED(JSObject, error_object, 0);
   String* key = isolate->heap()->hidden_stack_trace_symbol();
   Object* result = error_object->GetHiddenProperty(key);
-  RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
-  error_object->DeleteHiddenProperty(key);
+  RUNTIME_ASSERT(result->IsJSArray() ||
+                 result->IsString() ||
+                 result->IsUndefined());
   return result;
 }
 
 
+// Set or clear the stack trace attached to an stack overflow error object.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) {
+  HandleScope scope(isolate);
+  ASSERT_EQ(args.length(), 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1);
+  Handle<String> key = isolate->factory()->hidden_stack_trace_symbol();
+  if (value->IsUndefined()) {
+    error_object->DeleteHiddenProperty(*key);
+  } else {
+    RUNTIME_ASSERT(value->IsString());
+    JSObject::SetHiddenProperty(error_object, key, value);
+  }
+  return *error_object;
+}
+
+
 // Returns V8 version as a string.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
   ASSERT_EQ(args.length(), 0);
diff --git a/src/runtime.h b/src/runtime.h
index b72813d..0bdc811 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -238,7 +238,9 @@
   F(FunctionIsBuiltin, 1, 1) \
   F(GetScript, 1, 1) \
   F(CollectStackTrace, 3, 1) \
-  F(GetOverflowedRawStackTrace, 1, 1) \
+  F(MarkOneShotGetter, 1, 1) \
+  F(GetOverflowedStackTrace, 1, 1) \
+  F(SetOverflowedStackTrace, 2, 1) \
   F(GetV8Version, 0, 1) \
   \
   F(ClassOf, 1, 1) \
@@ -476,20 +478,6 @@
   F(SetFlags, 1, 1) \
   F(CollectGarbage, 1, 1) \
   F(GetHeapUsage, 0, 1) \
-  \
-  /* LiveObjectList support*/ \
-  F(HasLOLEnabled, 0, 1) \
-  F(CaptureLOL, 0, 1) \
-  F(DeleteLOL, 1, 1) \
-  F(DumpLOL, 5, 1) \
-  F(GetLOLObj, 1, 1) \
-  F(GetLOLObjId, 1, 1) \
-  F(GetLOLObjRetainers, 6, 1) \
-  F(GetLOLPath, 3, 1) \
-  F(InfoLOL, 2, 1) \
-  F(PrintLOLObj, 1, 1) \
-  F(ResetLOL, 0, 1) \
-  F(SummarizeLOL, 3, 1)
 
 #else
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
diff --git a/src/spaces.cc b/src/spaces.cc
index 35619d1..b004dfa 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -27,7 +27,6 @@
 
 #include "v8.h"
 
-#include "liveobjectlist-inl.h"
 #include "macro-assembler.h"
 #include "mark-compact.h"
 #include "platform.h"
diff --git a/src/type-info.cc b/src/type-info.cc
index 00e8ee8..75e915b 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -488,7 +488,7 @@
       isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
     // TODO(fschneider): We could collect the maps and signal that
     // we need a generic store (or load) here.
-    ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
+    ASSERT(Handle<Code>::cast(object)->ic_state() == GENERIC);
   } else if (object->IsMap()) {
     types->Add(Handle<Map>::cast(object), zone());
   } else if (FLAG_collect_megamorphic_maps_from_stub_cache &&
diff --git a/src/unicode-inl.h b/src/unicode-inl.h
index c3a00ed..b4e2cb5 100644
--- a/src/unicode-inl.h
+++ b/src/unicode-inl.h
@@ -79,6 +79,36 @@
 }
 
 
+bool Latin1::NonLatin1CanBeConvertedToLatin1(uint16_t c) {
+  ASSERT(c > Latin1::kMaxChar);
+  switch (c) {
+    case 0x130:
+    case 0x131:
+    case 0x149:
+    case 0x178:
+    case 0x17f:
+    case 0x1f0:
+    case 0x1e96:
+    case 0x1e97:
+    case 0x1e98:
+    case 0x1e99:
+    case 0x1e9a:
+    case 0x1e9e:
+    case 0x212a:
+    case 0x212b:
+    case 0xfb00:
+    case 0xfb01:
+    case 0xfb02:
+    case 0xfb03:
+    case 0xfb04:
+    case 0xfb05:
+    case 0xfb06:
+      return true;
+  }
+  return false;
+}
+
+
 unsigned Utf8::Encode(char* str, uchar c, int previous) {
   static const int kMask = ~(1 << 6);
   if (c <= kMaxOneByteChar) {
diff --git a/src/unicode.h b/src/unicode.h
index 61dbab4..0278576 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -140,6 +140,7 @@
 #else
   static const unsigned kMaxChar = 0xff;
 #endif
+  static inline bool NonLatin1CanBeConvertedToLatin1(uint16_t);
 };
 
 class Utf8 {
diff --git a/src/v8globals.h b/src/v8globals.h
index 807be30..65e8455 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -263,6 +263,8 @@
   POLYMORPHIC,
   // Many receiver types have been seen.
   MEGAMORPHIC,
+  // A generic handler is installed and no extra typefeedback is recorded.
+  GENERIC,
   // Special state for debug break or step in prepare stubs.
   DEBUG_STUB
 };
diff --git a/src/v8threads.cc b/src/v8threads.cc
index 32ea5e1..925e198 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -42,15 +42,18 @@
 bool Locker::active_ = false;
 
 
-// Constructor for the Locker object.  Once the Locker is constructed the
-// current thread will be guaranteed to have the lock for a given isolate.
-Locker::Locker(v8::Isolate* isolate)
-  : has_lock_(false),
-    top_level_(true),
-    isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
-  if (isolate_ == NULL) {
-    isolate_ = i::Isolate::GetDefaultIsolateForLocking();
-  }
+Locker::Locker() {
+  Initialize(i::Isolate::GetDefaultIsolateForLocking());
+}
+
+
+// Once the Locker is initialized, the current thread will be guaranteed to have
+// the lock for a given isolate.
+void Locker::Initialize(v8::Isolate* isolate) {
+  ASSERT(isolate != NULL);
+  has_lock_= false;
+  top_level_ = true;
+  isolate_ = reinterpret_cast<i::Isolate*>(isolate);
   // Record that the Locker has been used at least once.
   active_ = true;
   // Get the big lock if necessary.
@@ -86,10 +89,8 @@
 
 
 bool Locker::IsLocked(v8::Isolate* isolate) {
+  ASSERT(isolate != NULL);
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  if (internal_isolate == NULL) {
-    internal_isolate = i::Isolate::GetDefaultIsolateForLocking();
-  }
   return internal_isolate->thread_manager()->IsLockedByCurrentThread();
 }
 
@@ -115,11 +116,14 @@
 }
 
 
-Unlocker::Unlocker(v8::Isolate* isolate)
-  : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
-  if (isolate_ == NULL) {
-    isolate_ = i::Isolate::GetDefaultIsolateForLocking();
-  }
+Unlocker::Unlocker() {
+  Initialize(i::Isolate::GetDefaultIsolateForLocking());
+}
+
+
+void Unlocker::Initialize(v8::Isolate* isolate) {
+  ASSERT(isolate != NULL);
+  isolate_ = reinterpret_cast<i::Isolate*>(isolate);
   ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
   if (isolate_->IsDefaultIsolate()) {
     isolate_->Exit();
@@ -479,7 +483,7 @@
 
 // Acknowledge the preemption by the receiving thread.
 void ContextSwitcher::PreemptionReceived() {
-  ASSERT(Locker::IsLocked());
+  ASSERT(Locker::IsLocked(i::Isolate::GetDefaultIsolateForLocking()));
   // There is currently no accounting being done for this. But could be in the
   // future, which is why we leave this in.
 }
diff --git a/src/v8utils.cc b/src/v8utils.cc
index 627169e..58ad4e5 100644
--- a/src/v8utils.cc
+++ b/src/v8utils.cc
@@ -273,97 +273,4 @@
   }
 }
 
-
-MemoryMappedExternalResource::MemoryMappedExternalResource(const char* filename)
-    : filename_(NULL),
-      data_(NULL),
-      length_(0),
-      remove_file_on_cleanup_(false) {
-  Init(filename);
-}
-
-
-MemoryMappedExternalResource::
-    MemoryMappedExternalResource(const char* filename,
-                                 bool remove_file_on_cleanup)
-    : filename_(NULL),
-      data_(NULL),
-      length_(0),
-      remove_file_on_cleanup_(remove_file_on_cleanup) {
-  Init(filename);
-}
-
-
-MemoryMappedExternalResource::~MemoryMappedExternalResource() {
-  // Release the resources if we had successfully acquired them:
-  if (file_ != NULL) {
-    delete file_;
-    if (remove_file_on_cleanup_) {
-      OS::Remove(filename_);
-    }
-    DeleteArray<char>(filename_);
-  }
-}
-
-
-void MemoryMappedExternalResource::Init(const char* filename) {
-  file_ = OS::MemoryMappedFile::open(filename);
-  if (file_ != NULL) {
-    filename_ = StrDup(filename);
-    data_ = reinterpret_cast<char*>(file_->memory());
-    length_ = file_->size();
-  }
-}
-
-
-bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
-  bool is_ascii = true;
-
-  int line_no = 1;
-  const char* start_of_line = data_;
-  const char* end = data_ + length_;
-  for (const char* p = data_; p < end; p++) {
-    char c = *p;
-    if ((c & 0x80) != 0) {
-      // Non-ASCII detected:
-      is_ascii = false;
-
-      // Report the error and abort if appropriate:
-      if (abort_if_failed) {
-        int char_no = static_cast<int>(p - start_of_line) - 1;
-
-        ASSERT(filename_ != NULL);
-        PrintF("\n\n\n"
-               "Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
-               c, filename_, line_no, char_no);
-
-        // Allow for some context up to kNumberOfLeadingContextChars chars
-        // before the offending non-ASCII char to help the user see where
-        // the offending char is.
-        const int kNumberOfLeadingContextChars = 10;
-        const char* err_context = p - kNumberOfLeadingContextChars;
-        if (err_context < data_) {
-          err_context = data_;
-        }
-        // Compute the length of the error context and print it.
-        int err_context_length = static_cast<int>(p - err_context);
-        if (err_context_length != 0) {
-          PrintF(" after \"%.*s\"", err_context_length, err_context);
-        }
-        PrintF(".\n\n\n");
-        OS::Abort();
-      }
-
-      break;  // Non-ASCII detected.  No need to continue scanning.
-    }
-    if (c == '\n') {
-      start_of_line = p;
-      line_no++;
-    }
-  }
-
-  return is_ascii;
-}
-
-
 } }  // namespace v8::internal
diff --git a/src/v8utils.h b/src/v8utils.h
index 2064c5a..793d34d 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -249,7 +249,8 @@
     }
     // Number of characters in a uintptr_t.
     static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT
-    while (dest <= limit - kStepSize) {
+    ASSERT(dest + kStepSize > dest);  // Check for overflow.
+    while (dest + kStepSize <= limit) {
       *reinterpret_cast<uintptr_t*>(dest) =
           *reinterpret_cast<const uintptr_t*>(src);
       dest += kStepSize;
@@ -263,37 +264,6 @@
 }
 
 
-// A resource for using mmapped files to back external strings that are read
-// from files.
-class MemoryMappedExternalResource: public
-    v8::String::ExternalAsciiStringResource {
- public:
-  explicit MemoryMappedExternalResource(const char* filename);
-  MemoryMappedExternalResource(const char* filename,
-                               bool remove_file_on_cleanup);
-  virtual ~MemoryMappedExternalResource();
-
-  virtual const char* data() const { return data_; }
-  virtual size_t length() const { return length_; }
-
-  bool exists() const { return file_ != NULL; }
-  bool is_empty() const { return length_ == 0; }
-
-  bool EnsureIsAscii(bool abort_if_failed) const;
-  bool EnsureIsAscii() const { return EnsureIsAscii(true); }
-  bool IsAscii() const { return EnsureIsAscii(false); }
-
- private:
-  void Init(const char* filename);
-
-  char* filename_;
-  OS::MemoryMappedFile* file_;
-
-  const char* data_;
-  size_t length_;
-  bool remove_file_on_cleanup_;
-};
-
 class StringBuilder : public SimpleStringBuilder {
  public:
   explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
diff --git a/src/version.cc b/src/version.cc
index e996622..a95ba1a 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     16
-#define BUILD_NUMBER      4
-#define PATCH_LEVEL       2
+#define BUILD_NUMBER      6
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 160a0df..b989a88 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -1646,6 +1646,15 @@
 }
 
 
+void Assembler::movzxwl(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xB7);
+  emit_modrm(dst, src);
+}
+
+
 void Assembler::repmovsb() {
   EnsureSpace ensure_space(this);
   emit(0xF3);
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index f2243d3..406df27 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -732,6 +732,7 @@
   void movzxbl(Register dst, const Operand& src);
   void movzxwq(Register dst, const Operand& src);
   void movzxwl(Register dst, const Operand& src);
+  void movzxwl(Register dst, Register src);
 
   // Repeated moves.
 
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 3f17d03..82f9100 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -316,7 +316,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
-    AllocationSiteInfoMode allocation_site_info_mode,
+    AllocationSiteMode allocation_site_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -332,7 +332,7 @@
   }
   int size = JSArray::kSize;
   int allocation_info_start = size;
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     size += AllocationSiteInfo::kSize;
   }
   size += elements_size;
@@ -345,7 +345,7 @@
   }
   __ AllocateInNewSpace(size, rax, rbx, rdx, fail, flags);
 
-  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+  if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ LoadRoot(kScratchRegister, Heap::kAllocationSiteInfoMapRootIndex);
     __ movq(FieldOperand(rax, allocation_info_start), kScratchRegister);
     __ movq(FieldOperand(rax, allocation_info_start + kPointerSize), rcx);
@@ -363,7 +363,7 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
-    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
       __ lea(rdx, Operand(rax, JSArray::kSize + AllocationSiteInfo::kSize));
     } else {
       __ lea(rdx, Operand(rax, JSArray::kSize));
@@ -414,22 +414,14 @@
   FastCloneShallowArrayStub::Mode mode = mode_;
   // rcx is boilerplate object.
   Factory* factory = masm->isolate()->factory();
-  AllocationSiteInfoMode allocation_site_info_mode =
-      DONT_TRACK_ALLOCATION_SITE_INFO;
-  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
-    mode = CLONE_ANY_ELEMENTS;
-    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
-  }
-
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ movq(rbx, FieldOperand(rcx, JSArray::kElementsOffset));
     __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
            factory->fixed_cow_array_map());
     __ j(not_equal, &check_fast_elements);
-    GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, 0, COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     __ ret(3 * kPointerSize);
 
@@ -437,9 +429,8 @@
     __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
            factory->fixed_array_map());
     __ j(not_equal, &double_elements);
-    GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS,
-                                        allocation_site_info_mode,
+    GenerateFastCloneShallowArrayCommon(masm, length_, CLONE_ELEMENTS,
+                                        allocation_site_mode_,
                                         &slow_case);
     __ ret(3 * kPointerSize);
 
@@ -471,7 +462,8 @@
   }
 
   GenerateFastCloneShallowArrayCommon(masm, length_, mode,
-                                      allocation_site_info_mode, &slow_case);
+                                      allocation_site_mode_,
+                                      &slow_case);
   __ ret(3 * kPointerSize);
 
   __ bind(&slow_case);
@@ -4782,6 +4774,11 @@
   // r9: second instance type.
   __ testb(rcx, Immediate(kAsciiDataHintMask));
   __ j(not_zero, &ascii_data);
+  __ xor_(r8, r9);
+  STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
+  __ andb(r8, Immediate(kOneByteStringTag | kAsciiDataHintTag));
+  __ cmpb(r8, Immediate(kOneByteStringTag | kAsciiDataHintTag));
+  __ j(equal, &ascii_data);
   // Allocate a two byte cons string.
   __ AllocateTwoByteConsString(rcx, rdi, no_reg, &call_runtime);
   __ jmp(&allocated);
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 0b2480a..36880bd 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -251,7 +251,8 @@
 #define __ ACCESS_MASM(masm)
 
 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
-    MacroAssembler* masm) {
+    MacroAssembler* masm, AllocationSiteMode mode,
+    Label* allocation_site_info_found) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rbx    : target map
@@ -259,6 +260,12 @@
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
+  if (mode == TRACK_ALLOCATION_SITE) {
+    ASSERT(allocation_site_info_found != NULL);
+    masm->TestJSArrayForAllocationSiteInfo(rdx, rdi,
+                                           allocation_site_info_found);
+  }
+
   // Set transitioned map.
   __ movq(FieldOperand(rdx, HeapObject::kMapOffset), rbx);
   __ RecordWriteField(rdx,
@@ -272,7 +279,7 @@
 
 
 void ElementsTransitionGenerator::GenerateSmiToDouble(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rbx    : target map
@@ -283,7 +290,7 @@
   // The fail label is not actually used since we do not allocate.
   Label allocated, new_backing_store, only_change_map, done;
 
-  if (FLAG_track_allocation_sites) {
+  if (mode == TRACK_ALLOCATION_SITE) {
     masm->TestJSArrayForAllocationSiteInfo(rdx, rdi, fail);
   }
 
@@ -398,7 +405,7 @@
 
 
 void ElementsTransitionGenerator::GenerateDoubleToObject(
-    MacroAssembler* masm, Label* fail) {
+    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rbx    : target map
@@ -408,6 +415,10 @@
   // -----------------------------------
   Label loop, entry, convert_hole, gc_required, only_change_map;
 
+  if (mode == TRACK_ALLOCATION_SITE) {
+    masm->TestJSArrayForAllocationSiteInfo(rdx, rdi, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ movq(r8, FieldOperand(rdx, JSObject::kElementsOffset));
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 6f18c19..46447de 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1689,6 +1689,7 @@
     __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
     FastCloneShallowArrayStub stub(
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
+        DONT_TRACK_ALLOCATION_SITE,
         length);
     __ CallStub(&stub);
   } else if (expr->depth() > 1) {
@@ -1698,21 +1699,19 @@
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
+    FastCloneShallowArrayStub::Mode mode =
+        FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+    AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
+        ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
+
     // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot
     // change, so it's possible to specialize the stub in advance.
-    FastCloneShallowArrayStub::Mode mode = has_constant_fast_elements
-        ? FastCloneShallowArrayStub::CLONE_ELEMENTS
-        : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
-
-    // Tracking allocation info allows us to pre-transition later if it makes
-    // sense.
-    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
-        FLAG_track_allocation_sites) {
-      mode = FastCloneShallowArrayStub::
-          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    if (has_constant_fast_elements) {
+      mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
+      allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
     }
 
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     __ CallStub(&stub);
   }
 
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index f3061af..657c88a 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -709,7 +709,9 @@
                                          rbx,
                                          rdi,
                                          slow);
-  ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+  AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                        FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
   __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
@@ -720,7 +722,9 @@
                                          rbx,
                                          rdi,
                                          slow);
-  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+  mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
+                                                                   slow);
   __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 
@@ -734,7 +738,8 @@
                                          rbx,
                                          rdi,
                                          slow);
-  ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+  mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
   __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 }
@@ -1670,7 +1675,9 @@
   // Must return the modified receiver in eax.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+                                                          FAST_DOUBLE_ELEMENTS);
+    ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
     __ movq(rax, rdx);
     __ Ret();
     __ bind(&fail);
@@ -1693,7 +1700,9 @@
   // Must return the modified receiver in eax.
   if (!FLAG_trace_elements_transitions) {
     Label fail;
-    ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+    AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS,
+                                                          FAST_ELEMENTS);
+    ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
     __ movq(rax, rdx);
     __ Ret();
     __ bind(&fail);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 8c4dafa..87eb954 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3603,8 +3603,7 @@
 
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
   // Only operate on the lower 32 bit of rax.
-  __ movl(rdx, rax);
-  __ andl(rdx, Immediate(0xFFFF));
+  __ movzxwl(rdx, rax);
   __ imull(rdx, rdx, Immediate(18273));
   __ shrl(rax, Immediate(16));
   __ addl(rax, rdx);
@@ -3612,8 +3611,7 @@
   __ movl(FieldOperand(rbx, ByteArray::kHeaderSize), rax);
 
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
-  __ movl(rdx, rcx);
-  __ andl(rdx, Immediate(0xFFFF));
+  __ movzxwl(rdx, rcx);
   __ imull(rdx, rdx, Immediate(36969));
   __ shrl(rcx, Immediate(16));
   __ addl(rcx, rdx);
@@ -3629,10 +3627,10 @@
   // 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)).
-  __ movl(rcx, Immediate(0x49800000));  // 1.0 x 2^20 as single.
-  __ movd(xmm2, rcx);
+  __ movq(rcx, V8_INT64_C(0x4130000000000000),
+          RelocInfo::NONE64);  // 1.0 x 2^20 as double
+  __ movq(xmm2, rcx);
   __ movd(xmm1, rax);
-  __ cvtss2sd(xmm2, xmm2);
   __ xorps(xmm1, xmm2);
   __ subsd(xmm1, xmm2);
 }
@@ -4903,6 +4901,8 @@
   Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();
+  AllocationSiteMode allocation_site_mode =
+      instr->hydrogen()->allocation_site_mode();
 
   // Deopt if the array literal boilerplate ElementsKind is of a type different
   // than the expected one. The check isn't necessary if the boilerplate has
@@ -4933,7 +4933,7 @@
     ASSERT(instr->hydrogen()->depth() == 1);
     FastCloneShallowArrayStub::Mode mode =
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+    FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   } else if (instr->hydrogen()->depth() > 1) {
     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
@@ -4942,9 +4942,9 @@
   } else {
     FastCloneShallowArrayStub::Mode mode =
         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS
-            ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
-            : FastCloneShallowArrayStub::CLONE_ELEMENTS;
-    FastCloneShallowArrayStub stub(mode, length);
+        ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
+        : FastCloneShallowArrayStub::CLONE_ELEMENTS;
+    FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   }
 }
@@ -4953,10 +4953,14 @@
 void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
                             Register result,
                             Register source,
-                            int* offset) {
+                            int* offset,
+                            AllocationSiteMode mode) {
   ASSERT(!source.is(rcx));
   ASSERT(!result.is(rcx));
 
+  bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
+      object->map()->CanTrackAllocationSite();
+
   // Only elements backing stores for non-COW arrays need to be copied.
   Handle<FixedArrayBase> elements(object->elements());
   bool has_elements = elements->length() > 0 &&
@@ -4966,8 +4970,13 @@
   // this object and its backing store.
   int object_offset = *offset;
   int object_size = object->map()->instance_size();
-  int elements_offset = *offset + object_size;
   int elements_size = has_elements ? elements->Size() : 0;
+  int elements_offset = *offset + object_size;
+  if (create_allocation_site_info) {
+    elements_offset += AllocationSiteInfo::kSize;
+    *offset += AllocationSiteInfo::kSize;
+  }
+
   *offset += object_size + elements_size;
 
   // Copy object header.
@@ -4992,7 +5001,8 @@
       __ lea(rcx, Operand(result, *offset));
       __ movq(FieldOperand(result, total_offset), rcx);
       __ LoadHeapObject(source, value_object);
-      EmitDeepCopy(value_object, result, source, offset);
+      EmitDeepCopy(value_object, result, source, offset,
+                   DONT_TRACK_ALLOCATION_SITE);
     } else if (value->IsHeapObject()) {
       __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value));
       __ movq(FieldOperand(result, total_offset), rcx);
@@ -5002,6 +5012,13 @@
     }
   }
 
+  // Build Allocation Site Info if desired
+  if (create_allocation_site_info) {
+    __ LoadRoot(kScratchRegister, Heap::kAllocationSiteInfoMapRootIndex);
+    __ movq(FieldOperand(result, object_size), kScratchRegister);
+    __ movq(FieldOperand(result, object_size + kPointerSize), source);
+  }
+
   if (has_elements) {
     // Copy elements backing store header.
     __ LoadHeapObject(source, elements);
@@ -5032,7 +5049,8 @@
           __ lea(rcx, Operand(result, *offset));
           __ movq(FieldOperand(result, total_offset), rcx);
           __ LoadHeapObject(source, value_object);
-          EmitDeepCopy(value_object, result, source, offset);
+          EmitDeepCopy(value_object, result, source, offset,
+                       DONT_TRACK_ALLOCATION_SITE);
         } else if (value->IsHeapObject()) {
           __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value));
           __ movq(FieldOperand(result, total_offset), rcx);
@@ -5082,7 +5100,8 @@
   __ bind(&allocated);
   int offset = 0;
   __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate());
-  EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset);
+  EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset,
+               instr->hydrogen()->allocation_site_mode());
   ASSERT_EQ(size, offset);
 }
 
@@ -5360,6 +5379,11 @@
 }
 
 
+void LCodeGen::DoDummyUse(LDummyUse* instr) {
+  // Nothing to see here, move on!
+}
+
+
 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   LOperand* obj = instr->object();
   LOperand* key = instr->key();
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 2fa10e1..08557ab 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -334,7 +334,8 @@
   void EmitDeepCopy(Handle<JSObject> object,
                     Register result,
                     Register source,
-                    int* offset);
+                    int* offset,
+                    AllocationSiteMode mode);
 
   struct JumpTableEntry {
     inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 85eeee1..c31de81 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -690,6 +690,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
+  return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 9def5c5..ffec14a 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -93,6 +93,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(DummyUse)                                   \
   V(ElementsKind)                               \
   V(FastLiteral)                                \
   V(FixedArrayBaseLength)                       \
@@ -404,6 +405,15 @@
 };
 
 
+class LDummyUse: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDummyUse(LOperand* value) {
+    inputs_[0] = value;
+  }
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
+};
+
+
 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 6e9e78e..52699e7 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -2218,19 +2218,16 @@
   // Check that both are flat ASCII strings.
   ASSERT(kNotStringTag != 0);
   const int kFlatAsciiStringMask =
-      kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
-      kStringRepresentationMask;
+      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
   const int kFlatAsciiStringTag = ASCII_STRING_TYPE;
 
   andl(scratch1, Immediate(kFlatAsciiStringMask));
   andl(scratch2, Immediate(kFlatAsciiStringMask));
   // Interleave the bits to check both scratch1 and scratch2 in one test.
-  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
-  shl(scratch1, Immediate(8));
-  orl(scratch1, scratch2);
+  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
+  lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
   cmpl(scratch1,
-       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 8)));
+       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
   j(not_equal, on_fail, near_jump);
 }
 
@@ -2266,19 +2263,17 @@
 
   // Check that both are flat ASCII strings.
   ASSERT(kNotStringTag != 0);
-  const int kFlatAsciiStringMask = kIsNotStringMask | kStringRepresentationMask
-          | kStringEncodingMask | kAsciiDataHintTag;
+  const int kFlatAsciiStringMask =
+      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
   const int kFlatAsciiStringTag = ASCII_STRING_TYPE;
 
   andl(scratch1, Immediate(kFlatAsciiStringMask));
   andl(scratch2, Immediate(kFlatAsciiStringMask));
   // Interleave the bits to check both scratch1 and scratch2 in one test.
-  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
-  ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
-  shl(scratch1, Immediate(8));
-  orl(scratch1, scratch2);
+  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
+  lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
   cmpl(scratch1,
-       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 8)));
+       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
   j(not_equal, on_fail, near_jump);
 }
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 82727ef..46d74b6 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1579,7 +1579,9 @@
                                                &try_holey_map);
 
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         // Restore edi.
         __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
         __ jmp(&fast_object);
@@ -1591,7 +1593,9 @@
                                                rdi,
                                                &call_builtin);
         ElementsTransitionGenerator::
-            GenerateMapChangeElementsTransition(masm());
+            GenerateMapChangeElementsTransition(masm(),
+                                                DONT_TRACK_ALLOCATION_SITE,
+                                                NULL);
         __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
         __ bind(&fast_object);
       } else {
diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc
index f638ed4..f173760 100644
--- a/test/cctest/cctest.cc
+++ b/test/cctest/cctest.cc
@@ -69,8 +69,12 @@
 }
 
 
+v8::Isolate* CcTest::default_isolate_;
+
 int main(int argc, char* argv[]) {
   v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
+  CcTest::set_default_isolate(v8::Isolate::GetCurrent());
+  CHECK(CcTest::default_isolate() != NULL);
   int tests_run = 0;
   bool print_run_count = true;
   for (int i = 1; i < argc; i++) {
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index 88cb9b8..f9f3b42 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -57,13 +57,17 @@
   CcTest(TestFunction* callback, const char* file, const char* name,
          const char* dependency, bool enabled);
   void Run() { callback_(); }
-  static int test_count();
   static CcTest* last() { return last_; }
   CcTest* prev() { return prev_; }
   const char* file() { return file_; }
   const char* name() { return name_; }
   const char* dependency() { return dependency_; }
   bool enabled() { return enabled_; }
+  static void set_default_isolate(v8::Isolate* default_isolate) {
+    default_isolate_ = default_isolate;
+  }
+  static v8::Isolate* default_isolate() { return default_isolate_; }
+
  private:
   TestFunction* callback_;
   const char* file_;
@@ -72,6 +76,7 @@
   bool enabled_;
   static CcTest* last_;
   CcTest* prev_;
+  static v8::Isolate* default_isolate_;
 };
 
 // Switches between all the Api tests using the threading support.
@@ -87,13 +92,6 @@
 class ApiTestFuzzer: public v8::internal::Thread {
  public:
   void CallTest();
-  explicit ApiTestFuzzer(int num)
-      : Thread("ApiTestFuzzer"),
-        test_number_(num),
-        gate_(v8::internal::OS::CreateSemaphore(0)),
-        active_(true) {
-  }
-  ~ApiTestFuzzer() { delete gate_; }
 
   // The ApiTestFuzzer is also a Thread, so it has a Run method.
   virtual void Run();
@@ -112,6 +110,14 @@
   static void Fuzz();
 
  private:
+  explicit ApiTestFuzzer(int num)
+      : Thread("ApiTestFuzzer"),
+        test_number_(num),
+        gate_(v8::internal::OS::CreateSemaphore(0)),
+        active_(true) {
+  }
+  ~ApiTestFuzzer() { delete gate_; }
+
   static bool fuzzing_;
   static int tests_being_run_;
   static int current_;
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index ab59e33..b457ef2 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -56,6 +56,9 @@
 # We do not yet shrink weak maps after they have been emptied by the GC
 test-weakmaps/Shrinking: FAIL
 
+# Deferred stack trace formatting is temporarily disabled.
+test-heap/ReleaseStackTraceData: PASS || FAIL
+
 ##############################################################################
 [ $arch == arm ]
 
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 6f5c841..d3b8824 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -25,9 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// We want to test our deprecated API entries, too.
-#define V8_DISABLE_DEPRECATIONS 1
-
 #include <limits.h>
 
 #ifndef WIN32
@@ -171,6 +168,23 @@
 }
 
 
+THREADED_TEST(IsolateOfContext) {
+  v8::HandleScope scope;
+  v8::Persistent<Context> env = Context::New();
+
+  CHECK(!env->InContext());
+  CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
+  env->Enter();
+  CHECK(env->InContext());
+  CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
+  env->Exit();
+  CHECK(!env->InContext());
+  CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
+
+  env.Dispose();
+}
+
+
 THREADED_TEST(ReceiverSignature) {
   v8::HandleScope scope;
   LocalContext env;
@@ -887,7 +901,7 @@
 
 static void* expected_ptr;
 static v8::Handle<v8::Value> callback(const v8::Arguments& args) {
-  void* ptr = v8::External::Unwrap(args.Data());
+  void* ptr = v8::External::Cast(*args.Data())->Value();
   CHECK_EQ(expected_ptr, ptr);
   return v8::True();
 }
@@ -897,7 +911,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  v8::Handle<v8::Value> data = v8::External::Wrap(expected_ptr);
+  v8::Handle<v8::Value> data = v8::External::New(expected_ptr);
 
   v8::Handle<v8::Object> obj = v8::Object::New();
   obj->Set(v8_str("func"),
@@ -2025,82 +2039,12 @@
 }
 
 
-THREADED_TEST(InternalFieldsNativePointers) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
-  Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
-  instance_templ->SetInternalFieldCount(1);
-  Local<v8::Object> obj = templ->GetFunction()->NewInstance();
-  CHECK_EQ(1, obj->InternalFieldCount());
-  CHECK(obj->GetPointerFromInternalField(0) == NULL);
-
-  char* data = new char[100];
-
-  void* aligned = data;
-  CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1));
-  void* unaligned = data + 1;
-  CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
-
-  // Check reading and writing aligned pointers.
-  obj->SetPointerInInternalField(0, aligned);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
-
-  // Check reading and writing unaligned pointers.
-  obj->SetPointerInInternalField(0, unaligned);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
-
-  delete[] data;
-}
-
-
-THREADED_TEST(InternalFieldsNativePointersAndExternal) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
-  Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
-  instance_templ->SetInternalFieldCount(1);
-  Local<v8::Object> obj = templ->GetFunction()->NewInstance();
-  CHECK_EQ(1, obj->InternalFieldCount());
-  CHECK(obj->GetPointerFromInternalField(0) == NULL);
-
-  char* data = new char[100];
-
-  void* aligned = data;
-  CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1));
-  void* unaligned = data + 1;
-  CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
-
-  obj->SetPointerInInternalField(0, aligned);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0)));
-
-  obj->SetPointerInInternalField(0, unaligned);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0)));
-
-  obj->SetInternalField(0, v8::External::Wrap(aligned));
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
-
-  obj->SetInternalField(0, v8::External::Wrap(unaligned));
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
-
-  delete[] data;
-}
-
-
 static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj,
                                                void* value) {
   CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
-  obj->SetPointerInInternalField(0, value);
+  obj->SetAlignedPointerInInternalField(0, value);
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(value, obj->GetPointerFromInternalField(0));
+  CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0));
 }
 
 
@@ -2355,18 +2299,18 @@
 
   // Make sure unaligned pointers are wrapped properly.
   char* data = i::StrDup("0123456789");
-  Local<v8::Value> zero = v8::External::Wrap(&data[0]);
-  Local<v8::Value> one = v8::External::Wrap(&data[1]);
-  Local<v8::Value> two = v8::External::Wrap(&data[2]);
-  Local<v8::Value> three = v8::External::Wrap(&data[3]);
+  Local<v8::Value> zero = v8::External::New(&data[0]);
+  Local<v8::Value> one = v8::External::New(&data[1]);
+  Local<v8::Value> two = v8::External::New(&data[2]);
+  Local<v8::Value> three = v8::External::New(&data[3]);
 
-  char* char_ptr = reinterpret_cast<char*>(v8::External::Unwrap(zero));
+  char* char_ptr = reinterpret_cast<char*>(v8::External::Cast(*zero)->Value());
   CHECK_EQ('0', *char_ptr);
-  char_ptr = reinterpret_cast<char*>(v8::External::Unwrap(one));
+  char_ptr = reinterpret_cast<char*>(v8::External::Cast(*one)->Value());
   CHECK_EQ('1', *char_ptr);
-  char_ptr = reinterpret_cast<char*>(v8::External::Unwrap(two));
+  char_ptr = reinterpret_cast<char*>(v8::External::Cast(*two)->Value());
   CHECK_EQ('2', *char_ptr);
-  char_ptr = reinterpret_cast<char*>(v8::External::Unwrap(three));
+  char_ptr = reinterpret_cast<char*>(v8::External::Cast(*three)->Value());
   CHECK_EQ('3', *char_ptr);
   i::DeleteArray(data);
 }
@@ -6276,6 +6220,10 @@
   CHECK_EQ(0, strcmp("abc", buf));
   CHECK_EQ(0, buf[3]);
   CHECK_EQ(0, strcmp("def", buf + 4));
+
+  CHECK_EQ(0, str->WriteAscii(NULL, 0, 0, String::NO_NULL_TERMINATION));
+  CHECK_EQ(0, str->WriteUtf8(NULL, 0, 0, String::NO_NULL_TERMINATION));
+  CHECK_EQ(0, str->Write(NULL, 0, 0, String::NO_NULL_TERMINATION));
 }
 
 
@@ -6293,8 +6241,10 @@
       Local<v8::String>::Cast(a->Get(i));
     Local<v8::Number> expected_len =
       Local<v8::Number>::Cast(alens->Get(i));
+#ifndef ENABLE_LATIN_1
     CHECK_EQ(expected_len->Value() != string->Length(),
              string->MayContainNonAscii());
+#endif
     int length = GetUtf8Length(string);
     CHECK_EQ(static_cast<int>(expected_len->Value()), length);
   }
@@ -9904,7 +9854,8 @@
 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
                                                   const AccessorInfo& info) {
   ApiTestFuzzer::Fuzz();
-  int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
+  int* call_count =
+      reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value());
   ++(*call_count);
   if ((*call_count) % 20 == 0) {
     HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -10063,7 +10014,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -10091,7 +10042,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -10122,7 +10073,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -10159,7 +10110,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -10196,7 +10147,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -10236,7 +10187,7 @@
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
   templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
                                  NULL, NULL, NULL, NULL,
-                                 v8::External::Wrap(&interceptor_call_count));
+                                 v8::External::New(&interceptor_call_count));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -11066,7 +11017,7 @@
   gate_->Wait();
   {
     // ... get the V8 lock and start running the test.
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     CallTest();
   }
   // This test finished.
@@ -11130,7 +11081,7 @@
   // If the new thread is the same as the current thread there is nothing to do.
   if (NextThread()) {
     // Now it can start.
-    v8::Unlocker unlocker;
+    v8::Unlocker unlocker(CcTest::default_isolate());
     // Wait till someone starts us again.
     gate_->Wait();
     // And we're off.
@@ -11182,12 +11133,12 @@
 
 
 static v8::Handle<Value> ThrowInJS(const v8::Arguments& args) {
-  CHECK(v8::Locker::IsLocked());
+  CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
   ApiTestFuzzer::Fuzz();
-  v8::Unlocker unlocker;
+  v8::Unlocker unlocker(CcTest::default_isolate());
   const char* code = "throw 7;";
   {
-    v8::Locker nested_locker;
+    v8::Locker nested_locker(CcTest::default_isolate());
     v8::HandleScope scope;
     v8::Handle<Value> exception;
     { v8::TryCatch try_catch;
@@ -11205,12 +11156,12 @@
 
 
 static v8::Handle<Value> ThrowInJSNoCatch(const v8::Arguments& args) {
-  CHECK(v8::Locker::IsLocked());
+  CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
   ApiTestFuzzer::Fuzz();
-  v8::Unlocker unlocker;
+  v8::Unlocker unlocker(CcTest::default_isolate());
   const char* code = "throw 7;";
   {
-    v8::Locker nested_locker;
+    v8::Locker nested_locker(CcTest::default_isolate());
     v8::HandleScope scope;
     v8::Handle<Value> value = CompileRun(code);
     CHECK(value.IsEmpty());
@@ -11222,8 +11173,8 @@
 // These are locking tests that don't need to be run again
 // as part of the locking aggregation tests.
 TEST(NestedLockers) {
-  v8::Locker locker;
-  CHECK(v8::Locker::IsLocked());
+  v8::Locker locker(CcTest::default_isolate());
+  CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
   v8::HandleScope scope;
   LocalContext env;
   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(ThrowInJS);
@@ -11244,7 +11195,7 @@
 // These are locking tests that don't need to be run again
 // as part of the locking aggregation tests.
 TEST(NestedLockersNoTryCatch) {
-  v8::Locker locker;
+  v8::Locker locker(CcTest::default_isolate());
   v8::HandleScope scope;
   LocalContext env;
   Local<v8::FunctionTemplate> fun_templ =
@@ -11264,24 +11215,24 @@
 
 
 THREADED_TEST(RecursiveLocking) {
-  v8::Locker locker;
+  v8::Locker locker(CcTest::default_isolate());
   {
-    v8::Locker locker2;
-    CHECK(v8::Locker::IsLocked());
+    v8::Locker locker2(CcTest::default_isolate());
+    CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
   }
 }
 
 
 static v8::Handle<Value> UnlockForAMoment(const v8::Arguments& args) {
   ApiTestFuzzer::Fuzz();
-  v8::Unlocker unlocker;
+  v8::Unlocker unlocker(CcTest::default_isolate());
   return v8::Undefined();
 }
 
 
 THREADED_TEST(LockUnlockLock) {
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::HandleScope scope;
     LocalContext env;
     Local<v8::FunctionTemplate> fun_templ =
@@ -11295,7 +11246,7 @@
     CHECK_EQ(42, script->Run()->Int32Value());
   }
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::HandleScope scope;
     LocalContext env;
     Local<v8::FunctionTemplate> fun_templ =
@@ -12546,7 +12497,7 @@
 
     LongRunningRegExp();
     {
-      v8::Unlocker unlock;
+      v8::Unlocker unlock(CcTest::default_isolate());
       gc_thread.Join();
     }
     v8::Locker::StopPreemption();
@@ -12573,7 +12524,7 @@
     block_->Wait();
     while (gc_during_regexp_ < kRequiredGCs) {
       {
-        v8::Locker lock;
+        v8::Locker lock(CcTest::default_isolate());
         // TODO(lrn): Perhaps create some garbage before collecting.
         HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
         gc_count_++;
@@ -12633,7 +12584,7 @@
 // Test that a regular expression execution can be interrupted and
 // survive a garbage collection.
 TEST(RegExpInterruption) {
-  v8::Locker lock;
+  v8::Locker lock(CcTest::default_isolate());
   v8::V8::Initialize();
   v8::HandleScope scope;
   Local<Context> local_env;
@@ -12669,7 +12620,7 @@
 
     LongRunningApply();
     {
-      v8::Unlocker unlock;
+      v8::Unlocker unlock(CcTest::default_isolate());
       gc_thread.Join();
     }
     v8::Locker::StopPreemption();
@@ -12696,7 +12647,7 @@
     block_->Wait();
     while (gc_during_apply_ < kRequiredGCs) {
       {
-        v8::Locker lock;
+        v8::Locker lock(CcTest::default_isolate());
         HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
         gc_count_++;
       }
@@ -12742,7 +12693,7 @@
 // Test that nothing bad happens if we get a preemption just when we were
 // about to do an apply().
 TEST(ApplyInterruption) {
-  v8::Locker lock;
+  v8::Locker lock(CcTest::default_isolate());
   v8::V8::Initialize();
   v8::HandleScope scope;
   Local<Context> local_env;
@@ -12873,8 +12824,10 @@
         "var slice = lhs.substring(1, lhs.length - 1);"
         "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);");
 
+#ifndef ENABLE_LATIN_1
     CHECK(!lhs->MayContainNonAscii());
     CHECK(!rhs->MayContainNonAscii());
+#endif
 
     MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource);
     MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource);
@@ -12978,7 +12931,7 @@
     v8::Locker::StartPreemption(1);
     LongRunningRegExp();
     {
-      v8::Unlocker unlock;
+      v8::Unlocker unlock(CcTest::default_isolate());
       morph_thread.Join();
     }
     v8::Locker::StopPreemption();
@@ -13007,7 +12960,7 @@
     while (morphs_during_regexp_ < kRequiredModifications &&
            morphs_ < kMaxModifications) {
       {
-        v8::Locker lock;
+        v8::Locker lock(CcTest::default_isolate());
         // Swap string between ascii and two-byte representation.
         i::String* string = *input_;
         MorphAString(string, &ascii_resource_, &uc16_resource_);
@@ -13055,7 +13008,7 @@
 // Test that a regular expression execution can be interrupted and
 // the string changed without failing.
 TEST(RegExpStringModification) {
-  v8::Locker lock;
+  v8::Locker lock(CcTest::default_isolate());
   v8::V8::Initialize();
   v8::HandleScope scope;
   Local<Context> local_env;
@@ -15188,7 +15141,7 @@
 TEST(SetResourceConstraintsInThread) {
   uint32_t* set_limit;
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     static const int K = 1024;
     set_limit = ComputeStackLimit(128 * K);
 
@@ -15209,7 +15162,7 @@
     CHECK(stack_limit == set_limit);
   }
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     CHECK(stack_limit == set_limit);
   }
 }
@@ -15472,7 +15425,7 @@
 
     context->Enter();
     Local<v8::String> obj = v8::String::New("");
-    context->SetData(obj);
+    context->SetEmbedderData(0, obj);
     CompileRun(source_simple);
     context->Exit();
   }
@@ -16734,6 +16687,18 @@
 }
 
 
+TEST(WrapperClassId) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Persistent<v8::Object> object =
+      v8::Persistent<v8::Object>::New(v8::Object::New());
+  CHECK_EQ(0, object.WrapperClassId());
+  object.SetWrapperClassId(65535);
+  CHECK_EQ(65535, object.WrapperClassId());
+  object.Dispose();
+}
+
+
 TEST(RegExp) {
   v8::HandleScope scope;
   LocalContext context;
@@ -18195,4 +18160,5 @@
 THREADED_TEST(SemaphoreInterruption) {
   ThreadInterruptTest().RunTest();
 }
+
 #endif  // WIN32
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 21f7993..1e4261c 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -27,9 +27,6 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
-// TODO(svenpanne): Do not use Context::GetData and Context::SetData.
-#define V8_DISABLE_DEPRECATIONS 1
-
 #include <stdlib.h>
 
 #include "v8.h"
@@ -6222,7 +6219,7 @@
 // Check that the expected context is the one generating the debug event.
 static void ContextCheckMessageHandler(const v8::Debug::Message& message) {
   CHECK(message.GetEventContext() == expected_context);
-  CHECK(message.GetEventContext()->GetData()->StrictEquals(
+  CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
       expected_context_data));
   message_handler_hit_count++;
 
@@ -6255,16 +6252,16 @@
   context_2 = v8::Context::New(NULL, global_template, global_object);
 
   // Default data value is undefined.
-  CHECK(context_1->GetData()->IsUndefined());
-  CHECK(context_2->GetData()->IsUndefined());
+  CHECK(context_1->GetEmbedderData(0)->IsUndefined());
+  CHECK(context_2->GetEmbedderData(0)->IsUndefined());
 
   // Set and check different data values.
   v8::Handle<v8::String> data_1 = v8::String::New("1");
   v8::Handle<v8::String> data_2 = v8::String::New("2");
-  context_1->SetData(data_1);
-  context_2->SetData(data_2);
-  CHECK(context_1->GetData()->StrictEquals(data_1));
-  CHECK(context_2->GetData()->StrictEquals(data_2));
+  context_1->SetEmbedderData(0, data_1);
+  context_2->SetEmbedderData(0, data_2);
+  CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1));
+  CHECK(context_2->GetEmbedderData(0)->StrictEquals(data_2));
 
   // Simple test function which causes a break.
   const char* source = "function f() { debugger; }";
@@ -6419,12 +6416,12 @@
   context_1 = v8::Context::New(NULL, global_template);
 
   // Default data value is undefined.
-  CHECK(context_1->GetData()->IsUndefined());
+  CHECK(context_1->GetEmbedderData(0)->IsUndefined());
 
   // Set and check a data value.
   v8::Handle<v8::String> data_1 = v8::String::New("1");
-  context_1->SetData(data_1);
-  CHECK(context_1->GetData()->StrictEquals(data_1));
+  context_1->SetEmbedderData(0, data_1);
+  CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1));
 
   // Simple test function with eval that causes a break.
   const char* source = "function f() { eval('debugger;'); }";
@@ -6465,7 +6462,7 @@
 static void DebugEvalContextCheckMessageHandler(
     const v8::Debug::Message& message) {
   CHECK(message.GetEventContext() == expected_context);
-  CHECK(message.GetEventContext()->GetData()->StrictEquals(
+  CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
       expected_context_data));
   message_handler_hit_count++;
 
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 824c4e7..d379fbb 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -161,6 +161,7 @@
       CHECK_EQ(value, catcher.Exception());
     }
   }
+  HEAP->CollectAllAvailableGarbage();  // Clean slate for the next test.
 }
 
 
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 834e75b..634deef 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -2436,11 +2436,7 @@
     CHECK(!resource->IsDisposed());
   }
   HEAP->CollectAllAvailableGarbage();
-  // External source is being retained by the stack trace.
-  CHECK(!resource->IsDisposed());
 
-  CompileRun("error.stack;");
-  HEAP->CollectAllAvailableGarbage();
   // External source has been released.
   CHECK(resource->IsDisposed());
   delete resource;
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index 57f7178..3e93110 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -536,7 +536,7 @@
   virtual void Run() {
     v8::Locker lock1(isolate_);
     CHECK(v8::Locker::IsLocked(isolate_));
-    CHECK(!v8::Locker::IsLocked());
+    CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
     {
       v8::Isolate::Scope isolate_scope(isolate_);
       v8::HandleScope handle_scope;
@@ -546,13 +546,13 @@
     {
       v8::Unlocker unlock1(isolate_);
       CHECK(!v8::Locker::IsLocked(isolate_));
-      CHECK(!v8::Locker::IsLocked());
+      CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
       {
         v8::Locker lock2(isolate_);
         v8::Isolate::Scope isolate_scope(isolate_);
         v8::HandleScope handle_scope;
         CHECK(v8::Locker::IsLocked(isolate_));
-        CHECK(!v8::Locker::IsLocked());
+        CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
         v8::Context::Scope context_scope(context_);
         CalcFibAndCheck();
       }
@@ -594,16 +594,16 @@
   }
 
   virtual void Run() {
-    v8::Locker lock1;
+    v8::Locker lock1(CcTest::default_isolate());
     {
       v8::HandleScope handle_scope;
       v8::Context::Scope context_scope(context_);
       CalcFibAndCheck();
     }
     {
-      v8::Unlocker unlock1;
+      v8::Unlocker unlock1(CcTest::default_isolate());
       {
-        v8::Locker lock2;
+        v8::Locker lock2(CcTest::default_isolate());
         v8::HandleScope handle_scope;
         v8::Context::Scope context_scope(context_);
         CalcFibAndCheck();
@@ -624,7 +624,7 @@
 #endif
   Persistent<v8::Context> context;
   {
-    v8::Locker locker_;
+    v8::Locker locker_(CcTest::default_isolate());
     v8::HandleScope handle_scope;
     context = v8::Context::New();
   }
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index 0d2971b..3684b87 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -1275,3 +1275,40 @@
   CHECK(String::IsAscii(static_cast<char*>(NULL), 0));
   CHECK(String::IsOneByte(static_cast<uc16*>(NULL), 0));
 }
+
+
+static bool CanBeConvertedToLatin1(uint16_t c) {
+  CHECK(c > unibrow::Latin1::kMaxChar);
+  uint32_t result[4];
+  int chars;
+  chars = unibrow::ToLowercase::Convert(c, 0, result, NULL);
+  if (chars > 0) {
+    CHECK_LE(chars, static_cast<int>(sizeof(result)));
+    for (int i = 0; i < chars; i++) {
+      if (result[i] <= unibrow::Latin1::kMaxChar) {
+        return true;
+      }
+    }
+  }
+  chars = unibrow::ToUppercase::Convert(c, 0, result, NULL);
+  if (chars > 0) {
+    CHECK_LE(chars, static_cast<int>(sizeof(result)));
+    for (int i = 0; i < chars; i++) {
+      if (result[i] <= unibrow::Latin1::kMaxChar) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+TEST(Latin1) {
+#ifndef ENABLE_LATIN_1
+    if (true) return;
+#endif
+  for (uint16_t c = unibrow::Latin1::kMaxChar + 1; c != 0; c++) {
+    CHECK_EQ(CanBeConvertedToLatin1(c),
+             unibrow::Latin1::NonLatin1CanBeConvertedToLatin1(c));
+  }
+}
diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc
index cebabaa..7712a2c 100644
--- a/test/cctest/test-thread-termination.cc
+++ b/test/cctest/test-thread-termination.cc
@@ -202,7 +202,7 @@
  public:
   LoopingThread() : Thread("LoopingThread") { }
   void Run() {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::HandleScope scope;
     v8_thread_id_ = v8::V8::GetCurrentThreadId();
     v8::Handle<v8::ObjectTemplate> global =
@@ -228,7 +228,7 @@
 // from another thread when using Lockers and preemption.
 TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::V8::Initialize();
     v8::Locker::StartPreemption(1);
     semaphore = v8::internal::OS::CreateSemaphore(0);
@@ -246,7 +246,7 @@
     semaphore->Wait();
   }
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     for (int i = 0; i < kThreads; i++) {
       v8::V8::TerminateExecution(threads[i]->GetV8ThreadId());
     }
@@ -256,7 +256,7 @@
     delete threads[i];
   }
   {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::Locker::StopPreemption();
   }
 
@@ -372,4 +372,3 @@
                                             "f()"))->Run()->IsTrue());
   context.Dispose();
 }
-
diff --git a/test/cctest/test-threads.cc b/test/cctest/test-threads.cc
index 713d1e8..ffb29cd 100644
--- a/test/cctest/test-threads.cc
+++ b/test/cctest/test-threads.cc
@@ -34,7 +34,7 @@
 
 
 TEST(Preemption) {
-  v8::Locker locker;
+  v8::Locker locker(CcTest::default_isolate());
   v8::V8::Initialize();
   v8::HandleScope scope;
   v8::Context::Scope context_scope(v8::Context::New());
@@ -67,7 +67,7 @@
  public:
   ThreadA() : Thread("ThreadA") { }
   void Run() {
-    v8::Locker locker;
+    v8::Locker locker(CcTest::default_isolate());
     v8::HandleScope scope;
     v8::Context::Scope context_scope(v8::Context::New());
 
@@ -86,7 +86,7 @@
     turn = CLEAN_CACHE;
     do {
       {
-        v8::Unlocker unlocker;
+        v8::Unlocker unlocker(CcTest::default_isolate());
         Thread::YieldCPU();
       }
     } while (turn != SECOND_TIME_FILL_CACHE);
@@ -105,7 +105,7 @@
   void Run() {
     do {
       {
-        v8::Locker locker;
+        v8::Locker locker(CcTest::default_isolate());
         if (turn == CLEAN_CACHE) {
           v8::HandleScope scope;
           v8::Context::Scope context_scope(v8::Context::New());
diff --git a/test/cctest/testcfg.py b/test/cctest/testcfg.py
index 69a5db2..1d03a84 100644
--- a/test/cctest/testcfg.py
+++ b/test/cctest/testcfg.py
@@ -45,9 +45,9 @@
     os.makedirs(self.serdes_dir)
 
   def ListTests(self, context):
+    shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
     if utils.IsWindows():
       shell += '.exe'
-    shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
     output = commands.Execute([context.command_prefix,
                                shell,
                                '--list',
diff --git a/test/message/overwritten-builtins.out b/test/message/overwritten-builtins.out
index ccf2924..db31bbf 100644
--- a/test/message/overwritten-builtins.out
+++ b/test/message/overwritten-builtins.out
@@ -28,3 +28,6 @@
 *%(basename)s:31: TypeError: Cannot read property 'x' of undefined
 undefined.x
          ^
+TypeError: Cannot read property 'x' of undefined
+    at *%(basename)s:31:10
+
diff --git a/test/mjsunit/allocation-site-info.js b/test/mjsunit/allocation-site-info.js
new file mode 100644
index 0000000..f4263af
--- /dev/null
+++ b/test/mjsunit/allocation-site-info.js
@@ -0,0 +1,114 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --track-allocation-sites
+
+// Test element kind of objects.
+// Since --smi-only-arrays affects builtins, its default setting at compile
+// time sticks if built with snapshot.  If --smi-only-arrays is deactivated
+// by default, only a no-snapshot build actually has smi-only arrays enabled
+// in this test case.  Depending on whether smi-only arrays are actually
+// enabled, this test takes the appropriate code path to check smi-only arrays.
+
+support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
+
+if (support_smi_only_arrays) {
+  print("Tests include smi-only arrays.");
+} else {
+  print("Tests do NOT include smi-only arrays.");
+}
+
+var elements_kind = {
+  fast_smi_only            :  'fast smi only elements',
+  fast                     :  'fast elements',
+  fast_double              :  'fast double elements',
+  dictionary               :  'dictionary elements',
+  external_byte            :  'external byte elements',
+  external_unsigned_byte   :  'external unsigned byte elements',
+  external_short           :  'external short elements',
+  external_unsigned_short  :  'external unsigned short elements',
+  external_int             :  'external int elements',
+  external_unsigned_int    :  'external unsigned int elements',
+  external_float           :  'external float elements',
+  external_double          :  'external double elements',
+  external_pixel           :  'external pixel elements'
+}
+
+function getKind(obj) {
+  if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
+  if (%HasFastObjectElements(obj)) return elements_kind.fast;
+  if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
+  if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
+}
+
+function assertKind(expected, obj, name_opt) {
+  if (!support_smi_only_arrays &&
+      expected == elements_kind.fast_smi_only) {
+    expected = elements_kind.fast;
+  }
+  assertEquals(expected, getKind(obj), name_opt);
+}
+
+if (support_smi_only_arrays) {
+    function fastliteralcase(value) {
+        var literal = [1, 2, 3];
+        literal[0] = value;
+        return literal;
+    }
+
+    // Case: [1,2,3] as allocation site
+    obj = fastliteralcase(1);
+    assertKind(elements_kind.fast_smi_only, obj);
+    obj = fastliteralcase(1.5);
+    assertKind(elements_kind.fast_double, obj);
+    obj = fastliteralcase(2);
+    assertKind(elements_kind.fast_double, obj);
+
+    // Verify that we will not pretransition the double->fast path.
+    obj = fastliteralcase("elliot");
+    assertKind(elements_kind.fast, obj);
+
+    // This fails until we turn off optimistic transitions to the
+    // most general elements kind seen on keyed stores. It's a goal
+    // to turn it off, but for now we need it.
+    // obj = fastliteralcase(3);
+    // assertKind(elements_kind.fast_double, obj);
+
+    function fastliteralcase_smifast(value) {
+        var literal = [1, 2, 3, 4];
+        literal[0] = value;
+        return literal;
+    }
+
+    obj = fastliteralcase_smifast(1);
+    assertKind(elements_kind.fast_smi_only, obj);
+    obj = fastliteralcase_smifast("carter");
+    assertKind(elements_kind.fast, obj);
+    obj = fastliteralcase_smifast(2);
+    assertKind(elements_kind.fast, obj);
+}
\ No newline at end of file
diff --git a/test/mjsunit/eval-stack-trace.js b/test/mjsunit/eval-stack-trace.js
index 723d522..d83b84c 100644
--- a/test/mjsunit/eval-stack-trace.js
+++ b/test/mjsunit/eval-stack-trace.js
@@ -26,12 +26,13 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Return the stack frames of an Error object.
+
+Error.prepareStackTrace = function(error, frames) {
+  return frames;
+}
+
 Error.prototype.getFrames = function() {
-  Error.prepareStackTrace = function(error, frames) {
-    return frames;
-  }
   var frames = this.stack;
-  Error.prepareStackTrace = undefined;
   return frames;
 }
 
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index da961ca..c9770dc 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -40,6 +40,9 @@
 # Skip long running test in debug and allow it to timeout in release mode.
 # regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug
 
+# Deferred stack trace formatting is temporarily disabled.
+stack-traces-gc: PASS || FAIL
+
 ##############################################################################
 # Too slow in debug mode with --stress-opt
 compiler/regress-stacktrace-methods: PASS, SKIP if $mode == debug
diff --git a/src/inspector.h b/test/mjsunit/regress/regress-147497.js
similarity index 67%
rename from src/inspector.h
rename to test/mjsunit/regress/regress-147497.js
index 6962e21..92e29d1 100644
--- a/src/inspector.h
+++ b/test/mjsunit/regress/regress-147497.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// 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:
@@ -25,36 +25,21 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --expose-debug-as debug
 
-#ifndef V8_INSPECTOR_H_
-#define V8_INSPECTOR_H_
+Debug = debug.Debug;
 
-// Only build this code if we're configured with the INSPECTOR.
-#ifdef INSPECTOR
-
-#include "v8.h"
-
-#include "objects.h"
-
-namespace v8 {
-namespace internal {
-
-class Inspector {
- public:
-  static void DumpObjectType(FILE* out, Object* obj, bool print_more);
-  static void DumpObjectType(FILE* out, Object* obj) {
-    DumpObjectType(out, obj, false);
-  }
-  static void DumpObjectType(Object* obj, bool print_more) {
-    DumpObjectType(stdout, obj, print_more);
-  }
-  static void DumpObjectType(Object* obj) {
-    DumpObjectType(stdout, obj, false);
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    exec_state.prepareStep(Debug.StepAction.StepNext, 10);
   }
 };
 
-} }  // namespace v8::internal
+Debug.setListener(listener);
 
-#endif  // INSPECTOR
+var statement = "";
+for (var i = 0; i < 1024; i++) statement += "z";
+statement = 'with(0)' + statement + '=function foo(){}';
 
-#endif  // V8_INSPECTOR_H_
+debugger;
+eval(statement);
diff --git a/test/mjsunit/stack-traces-gc.js b/test/mjsunit/stack-traces-gc.js
new file mode 100644
index 0000000..dd878f2
--- /dev/null
+++ b/test/mjsunit/stack-traces-gc.js
@@ -0,0 +1,119 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --allow-natives-syntax
+
+var fired = [];
+for (var i = 0; i < 100; i++) fired[i] = false;
+
+function getter_function(i) {
+  return %MarkOneShotGetter( function() { fired[i] = true; } );
+}
+
+// Error objects that die young.
+for (var i = 0; i < 100; i++) {
+  var error = new Error();
+  // Replace the getter to observe whether it has been fired,
+  // and disguise it as original getter.
+  var getter = getter_function(i);
+  error.__defineGetter__("stack", getter);
+
+  error = undefined;
+}
+
+gc();
+for (var i = 0; i < 100; i++) {
+  assertFalse(fired[i]);
+}
+
+// Error objects that are kept alive.
+var array = [];
+for (var i = 0; i < 100; i++) {
+  var error = new Error();
+  var getter = getter_function(i);
+  // Replace the getter to observe whether it has been fired,
+  // and disguise it as original getter.
+  error.__defineGetter__("stack", getter);
+
+  array.push(error);
+  error = undefined;
+}
+
+gc();
+// We don't expect all stack traces to be formatted after only one GC.
+assertTrue(fired[0]);
+
+for (var i = 0; i < 10; i++) gc();
+for (var i = 0; i < 100; i++) assertTrue(fired[i]);
+
+// Error objects with custom stack getter.
+var custom_error = new Error();
+var custom_getter_fired = false;
+custom_error.__defineGetter__("stack",
+                              function() { custom_getter_fired = true; });
+gc();
+assertFalse(custom_getter_fired);
+
+// Check that formatting caused by GC is not somehow observable.
+var error;
+
+var obj = { foo: function foo() { throw new Error(); } };
+
+try {
+  obj.foo();
+} catch (e) {
+  delete obj.foo;
+  Object.defineProperty(obj, 'foo', {
+    get: function() { assertUnreachable(); }
+  });
+  error = e;
+}
+
+gc();
+
+Object.defineProperty(Array.prototype, '0', {
+  get: function() { assertUnreachable(); }
+});
+
+try {
+  throw new Error();
+} catch (e) {
+  error = e;
+}
+
+gc();
+
+String.prototype.indexOf = function() { assertUnreachable(); };
+String.prototype.lastIndexOf = function() { assertUnreachable(); };
+var obj = { method: function() { throw Error(); } };
+try {
+  obj.method();
+} catch (e) {
+  error = e;
+}
+
+gc();
diff --git a/test/mjsunit/stack-traces.js b/test/mjsunit/stack-traces.js
index 438eec9..b5d58fa 100644
--- a/test/mjsunit/stack-traces.js
+++ b/test/mjsunit/stack-traces.js
@@ -288,4 +288,42 @@
                    }, "QuickSort");
 
 // Omitted because ADD from runtime.js is non-native builtin.
-testOmittedBuiltin(function(){ thrower + 2; }, "ADD");
\ No newline at end of file
+testOmittedBuiltin(function(){ thrower + 2; }, "ADD");
+
+var error = new Error();
+error.toString = function() { assertUnreachable(); };
+error.stack;
+
+error = new Error();
+error.name = { toString: function() { assertUnreachable(); }};
+error.message = { toString: function() {  assertUnreachable(); }};
+error.stack;
+
+error = new Error();
+Array.prototype.push = function(x) { assertUnreachable(); };
+Array.prototype.join = function(x) { assertUnreachable(); };
+error.stack;
+
+var fired = false;
+error = new Error({ toString: function() { fired = true; } });
+assertTrue(fired);
+error.stack;
+assertTrue(fired);
+
+// Check that throwing exception in a custom stack trace formatting function
+// does not lead to recursion.
+Error.prepareStackTrace = function() { throw new Error("abc"); };
+var message;
+try {
+  throw new Error();
+} catch (e) {
+  message = e.message;
+}
+
+assertEquals("abc", message);
+
+// Test that modifying Error.prepareStackTrace by itself works.
+Error.prepareStackTrace = function() { Error.prepareStackTrace = "custom"; };
+new Error();
+
+assertEquals("custom", Error.prepareStackTrace);
diff --git a/test/mjsunit/testcfg.py b/test/mjsunit/testcfg.py
index c8b972c..00d4500 100644
--- a/test/mjsunit/testcfg.py
+++ b/test/mjsunit/testcfg.py
@@ -75,7 +75,7 @@
               for f in files_list ]
     testfilename = os.path.join(self.root, testcase.path + self.suffix())
     if SELF_SCRIPT_PATTERN.search(source):
-      env = ["-e", "TEST_FILE_NAME=\"%s\"" % testfilename]
+      env = ["-e", "TEST_FILE_NAME=\"%s\"" % testfilename.replace("\\", "\\\\")]
       files = env + files
     files.append(os.path.join(self.root, "mjsunit.js"))
     files.append(testfilename)
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index f915459..9878730 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -70,7 +70,7 @@
 js1_2/function/Number: SKIP
 
 # TODO(2018): Temporarily allow timeout in debug mode.
-js1_5/GC/regress-203278-2: PASS || TIMEOUT if $mode == debug
+js1_5/GC/regress-203278-2: PASS || (TIMEOUT || FAIL) if $mode == debug
 
 ##################### SLOW TESTS #####################
 
@@ -106,7 +106,6 @@
 
 js1_5/Regress/regress-280769-3: PASS || FAIL if $mode == debug
 js1_5/Regress/regress-203278-1: PASS || FAIL if $mode == debug
-js1_5/GC/regress-203278-2: PASS || FAIL if $mode == debug
 js1_5/Regress/regress-244470: PASS || FAIL if $mode == debug
 ecma_3/RegExp/regress-209067: PASS || FAIL if $mode == debug
 js1_5/GC/regress-278725: PASS || FAIL if $mode == debug
@@ -127,7 +126,6 @@
 
 # 1026139: These date tests fail on arm and mips
 ecma/Date/15.9.5.29-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
-ecma/Date/15.9.5.34-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
 ecma/Date/15.9.5.28-1: PASS || FAIL if ($arch == arm || $arch == mipsel)
 
 # 1050186: Arm/MIPS vm is broken; probably unrelated to dates
@@ -179,7 +177,6 @@
 # These tests sometimes pass (in particular on Windows). They build up
 # a lot of stuff on the stack, which normally causes a stack overflow,
 # but sometimes it makes it through?
-js1_5/Regress/regress-290575: PASS || FAIL
 js1_5/Regress/regress-98901: PASS || FAIL
 
 
@@ -398,15 +395,6 @@
 js1_5/decompilation/regress-460501: FAIL_OK
 js1_5/decompilation/regress-460116-03: FAIL_OK
 js1_5/decompilation/regress-461110: FAIL_OK
-js1_5/decompilation/regress-456964-01: FAIL_OK
-js1_5/decompilation/regress-437288-02: FAIL_OK
-js1_5/decompilation/regress-457824: FAIL_OK
-js1_5/decompilation/regress-460116-01: FAIL_OK
-js1_5/decompilation/regress-460116-02: FAIL_OK
-js1_5/decompilation/regress-460116-03: FAIL_OK
-js1_5/decompilation/regress-460501: FAIL_OK
-js1_5/decompilation/regress-461110: FAIL_OK
-
 
 
 # Tests that use uneval.  Non-ECMA.
@@ -563,7 +551,7 @@
 
 # This test requires a failure if we try to compile a function with more
 # than 65536 arguments.  This seems to be a Mozilla restriction.
-js1_5/Regress/regress-290575: FAIL_OK
+js1_5/Regress/regress-290575: PASS || FAIL_OK
 
 
 # Fails because of the way function declarations are
@@ -757,7 +745,6 @@
 
 js1_5/extensions/regress-330569: TIMEOUT
 js1_5/extensions/regress-351448: TIMEOUT
-js1_5/extensions/regress-342960: FAIL_OK || TIMEOUT if $mode == debug
 # In the 64-bit version, this test takes longer to run out of memory
 # than it does in the 32-bit version when attempting to generate a huge
 # error message in debug mode.
@@ -825,10 +812,6 @@
 
 [ $arch == arm ]
 
-# Times out and print so much output that we need to skip it to not
-# hang the builder.
-js1_5/extensions/regress-342960: SKIP
-
 # BUG(3251229): Times out when running new crankshaft test script.
 ecma_3/RegExp/regress-311414: SKIP
 ecma/Date/15.9.5.8: SKIP
@@ -848,10 +831,6 @@
 
 [ $arch == mipsel ]
 
-# Times out and print so much output that we need to skip it to not
-# hang the builder.
-js1_5/extensions/regress-342960: SKIP
-
 # BUG(3251229): Times out when running new crankshaft test script.
 ecma_3/RegExp/regress-311414: SKIP
 ecma/Date/15.9.5.8: SKIP
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 046a72c..b0b040a 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -353,8 +353,6 @@
             '../../src/ic.h',
             '../../src/incremental-marking.cc',
             '../../src/incremental-marking.h',
-            '../../src/inspector.cc',
-            '../../src/inspector.h',
             '../../src/interface.cc',
             '../../src/interface.h',
             '../../src/interpreter-irregexp.cc',
@@ -375,9 +373,6 @@
             '../../src/lithium.h',
             '../../src/liveedit.cc',
             '../../src/liveedit.h',
-            '../../src/liveobjectlist-inl.h',
-            '../../src/liveobjectlist.cc',
-            '../../src/liveobjectlist.h',
             '../../src/log-inl.h',
             '../../src/log-utils.cc',
             '../../src/log-utils.h',
@@ -991,6 +986,47 @@
               'toolsets': ['target'],
             }],
           ],
+          'variables': {
+            'shim_headers_path': '<(SHARED_INTERMEDIATE_DIR)/shim_headers/<(_target_name)/<(_toolset)',
+          },
+          'include_dirs++': [
+            '<(shim_headers_path)',
+          ],
+          'direct_dependent_settings': {
+            'include_dirs+++': [
+              '<(shim_headers_path)',
+            ],
+          },
+          'actions': [
+            {
+              'variables': {
+                'generator_path': '../../../tools/generate_shim_headers/generate_shim_headers.py',
+                'generator_args': [
+                  '--headers-root', '../../include',
+                  '--output-directory', '<(shim_headers_path)',
+                  'v8-debug.h',
+                  'v8-preparser.h',
+                  'v8-profiler.h',
+                  'v8-testing.h',
+                  'v8.h',
+                  'v8stdint.h',
+                ],
+              },
+              'action_name': 'generate_<(_target_name)_shim_headers',
+              'inputs': [
+                '<(generator_path)',
+              ],
+              'outputs': [
+                '<!@pymod_do_main(generate_shim_headers <@(generator_args) --outputs)',
+              ],
+              'action': ['python',
+                         '<(generator_path)',
+                         '<@(generator_args)',
+                         '--generate',
+              ],
+              'message': 'Generating <(_target_name) shim headers.',
+            },
+          ],
           'link_settings': {
             'libraries': [
               '-lv8',
diff --git a/tools/plot-timer-events.js b/tools/plot-timer-events.js
index 0a5e522..44ff326 100644
--- a/tools/plot-timer-events.js
+++ b/tools/plot-timer-events.js
@@ -276,13 +276,15 @@
 
   if (start_found && end_found) return;
 
-  var execution_ranges = kExecutionEvent.ranges;
-  for (var i = 0; i < execution_ranges.length; i++) {
-    if (execution_ranges[i].start < xrange_start && !start_found) {
-      xrange_start = execution_ranges[i].start;
-    }
-    if (execution_ranges[i].end > xrange_end && !end_found) {
-      xrange_end = execution_ranges[i].end;
+  for (name in TimerEvents) {
+    var ranges = TimerEvents[name].ranges;
+    for (var i = 0; i < ranges.length; i++) {
+      if (ranges[i].start < xrange_start && !start_found) {
+        xrange_start = ranges[i].start;
+      }
+      if (ranges[i].end > xrange_end && !end_found) {
+        xrange_end = ranges[i].end;
+      }
     }
   }
 
@@ -500,11 +502,25 @@
   print("set xtics out nomirror");
   print("unset key");
 
+  var percentages = {};
+  var total = 0;
+  for (var name in TimerEvents) {
+    var event = TimerEvents[name];
+    var ranges = MergeRanges(event.ranges);
+    var exclude_ranges = [new Range(-Infinity, xrange_start),
+                          new Range(xrange_end, Infinity)];
+    ranges = ExcludeRanges(ranges, exclude_ranges);
+    var sum =
+      ranges.map(function(range) { return range.duration(); })
+          .reduce(function(a, b) { return a + b; }, 0);
+    percentages[name] = (sum / (xrange_end - xrange_start) * 100).toFixed(1);
+  }
+
   // Name Y-axis.
   var ytics = [];
   for (name in TimerEvents) {
     var index = TimerEvents[name].index;
-    ytics.push('"' + name + '"' + ' ' + index);
+    ytics.push('"' + name + ' (' + percentages[name] + '%%)" ' + index);
   }
   ytics.push('"code kind being executed"' + ' ' + (kY1Offset - 1));
   ytics.push('"top ' + kStackFrames + ' js stack frames"' + ' ' +
diff --git a/tools/run-tests.py b/tools/run-tests.py
index c09ea06..f20af16 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -155,7 +155,7 @@
     options.mode = tokens[1]
   options.mode = options.mode.split(",")
   for mode in options.mode:
-    if not mode in ["debug", "release"]:
+    if not mode.lower() in ["debug", "release"]:
       print "Unknown mode %s" % mode
       return False
   if options.arch in ["auto", "native"]:
diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py
index 6004367..2e37fcb 100644
--- a/tools/testrunner/local/execution.py
+++ b/tools/testrunner/local/execution.py
@@ -90,7 +90,7 @@
     self.indicator.Starting()
     self._RunInternal(jobs)
     self.indicator.Done()
-    if self.failed:
+    if self.failed or self.remaining:
       return 1
     return 0
 
diff --git a/tools/testrunner/local/testsuite.py b/tools/testrunner/local/testsuite.py
index de5cddd..473e8b1 100644
--- a/tools/testrunner/local/testsuite.py
+++ b/tools/testrunner/local/testsuite.py
@@ -30,6 +30,7 @@
 import os
 
 from . import statusfile
+from . import utils
 
 class TestSuite(object):
 
@@ -88,6 +89,8 @@
     used_rules = set()
     for t in self.tests:
       testname = self.CommonTestName(t)
+      if utils.IsWindows():
+        testname = testname.replace("\\", "/")
       if testname in self.rules:
         used_rules.add(testname)
         outcomes = self.rules[testname]
diff --git a/tools/testrunner/server/compression.py b/tools/testrunner/server/compression.py
index ce90c4f..d5ed415 100644
--- a/tools/testrunner/server/compression.py
+++ b/tools/testrunner/server/compression.py
@@ -30,7 +30,6 @@
 try:
   import ujson as json
 except ImportError:
-  print("You should install UltraJSON, it is much faster!")
   import json
 import os
 import struct