Fixed a number of build issues.

Fixed problem with missing I-cache flusing on ARM.

Changed space layout in memory management by splitting up code space into old data space and code space.

Added utf-8 conversion support to the API (issue 57).

Optimized repeated calls to eval with the same strings.  These repeated calls are common in web applications.

Added Xcode project file.

Optimized a couple of Array operation.

Fixed parser bug by checking for end-of-string when parsing break and continue (issue 35).

Fixed problem where asian characters were not categorized as letters.

Fixed bug that disallowed calling functions fetched from an array using a string as an array index (issue 32).

Fixed bug where the internal field count on object templates were sometimes ignored (issue 54).

Added -f option to the shell sample for compatibility with other engines (issue 18).

Added source info to TryCatches in the API.

Fixed problem where the seed for the random number generator was clipped in a double to unsigned int conversion.

Fixed bug where cons string symbols were sometimes converted to non-symbol flat strings during GC.

Fixed bug in error reporting when attempting to convert null to an object.


git-svn-id: http://v8.googlecode.com/svn/trunk@267 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/SConscript b/src/SConscript
index 15ec440..cc39e22 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -1,4 +1,4 @@
-# Copyright 2008 Google Inc.  All rights reserved.
+# Copyright 2008 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -97,7 +97,7 @@
 def ConfigureObjectFiles():
   env = Environment()
   env.Replace(**context.flags['v8'])
-  env['ENV'].update(**context.env_overrides)
+  context.ApplyEnvOverrides(env)
   env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
   env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile $LOGFILE')
 
diff --git a/src/accessors.cc b/src/accessors.cc
index 4895f68..f02894b 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/accessors.h b/src/accessors.h
index da1a037..6fb3195 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/allocation.cc b/src/allocation.cc
index 6650636..d7d21aa 100644
--- a/src/allocation.cc
+++ b/src/allocation.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/allocation.h b/src/allocation.h
index 5c9ff5e..35e68bd 100644
--- a/src/allocation.h
+++ b/src/allocation.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/api.cc b/src/api.cc
index 352d4d4..8cf4b62 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -446,14 +446,12 @@
 }
 
 
-#ifdef DEBUG
 void HandleScope::ZapRange(void** start, void** end) {
   if (start == NULL) return;
   for (void** p = start; p < end; p++) {
     *p = reinterpret_cast<void*>(v8::internal::kHandleZapValue);
   }
 }
-#endif
 
 
 void** v8::HandleScope::RawClose(void** value) {
@@ -981,6 +979,12 @@
                 "Invalid internal field count")) {
     return;
   }
+  if (value > 0) {
+    // The internal field count is set by the constructor function's
+    // construct code, so we ensure that there is a constructor
+    // function to do the setting.
+    EnsureConstructor(this);
+  }
   Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
 }
 
@@ -1077,7 +1081,9 @@
 v8::TryCatch::TryCatch()
     : next_(i::Top::try_catch_handler()),
       exception_(i::Heap::the_hole_value()),
-      is_verbose_(false) {
+      message_(i::Smi::FromInt(0)),
+      is_verbose_(false),
+      capture_message_(true) {
   i::Top::RegisterTryCatchHandler(this);
 }
 
@@ -1103,8 +1109,19 @@
 }
 
 
+v8::Local<v8::Message> v8::TryCatch::Message() {
+  if (HasCaught() && message_ != i::Smi::FromInt(0)) {
+    i::Object* message = reinterpret_cast<i::Object*>(message_);
+    return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
+  } else {
+    return v8::Local<v8::Message>();
+  }
+}
+
+
 void v8::TryCatch::Reset() {
   exception_ = i::Heap::the_hole_value();
+  message_ = i::Smi::FromInt(0);
 }
 
 
@@ -1113,6 +1130,11 @@
 }
 
 
+void v8::TryCatch::SetCaptureMessage(bool value) {
+  capture_message_ = value;
+}
+
+
 // --- M e s s a g e ---
 
 
@@ -1192,15 +1214,66 @@
 }
 
 
-Local<Value> Message::GetSourceLine() {
-  ON_BAILOUT("v8::Message::GetSourceLine()", return Local<Value>());
+int Message::GetStartPosition() {
+  if (IsDeadCheck("v8::Message::GetStartPosition()")) return 0;
+  HandleScope scope;
+
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  return static_cast<int>(GetProperty(data_obj, "startPos")->Number());
+}
+
+
+int Message::GetEndPosition() {
+  if (IsDeadCheck("v8::Message::GetEndPosition()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  return static_cast<int>(GetProperty(data_obj, "endPos")->Number());
+}
+
+
+int Message::GetStartColumn() {
+  if (IsDeadCheck("v8::Message::GetStartColumn()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
+      "GetPositionInLine",
+      data_obj,
+      &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(0);
+  return static_cast<int>(start_col_obj->Number());
+}
+
+
+int Message::GetEndColumn() {
+  if (IsDeadCheck("v8::Message::GetEndColumn()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
+      "GetPositionInLine",
+      data_obj,
+      &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(0);
+  int start = static_cast<int>(GetProperty(data_obj, "startPos")->Number());
+  int end = static_cast<int>(GetProperty(data_obj, "endPos")->Number());
+  return static_cast<int>(start_col_obj->Number()) + (end - start);
+}
+
+
+Local<String> Message::GetSourceLine() {
+  ON_BAILOUT("v8::Message::GetSourceLine()", return Local<String>());
   HandleScope scope;
   EXCEPTION_PREAMBLE();
   i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
                                                    Utils::OpenHandle(this),
                                                    &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
-  return scope.Close(Utils::ToLocal(result));
+  EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
+  if (result->IsString()) {
+    return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
+  } else {
+    return Local<String>();
+  }
 }
 
 
@@ -1925,6 +1998,53 @@
 }
 
 
+int String::Utf8Length() {
+  if (IsDeadCheck("v8::String::Utf8Length()")) return 0;
+  return Utils::OpenHandle(this)->Utf8Length();
+}
+
+
+int String::WriteUtf8(char* buffer, int capacity) {
+  if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
+  LOG_API("String::WriteUtf8");
+  i::Handle<i::String> str = Utils::OpenHandle(this);
+  write_input_buffer.Reset(0, *str);
+  int len = str->length();
+  // Encode the first K - 3 bytes directly into the buffer since we
+  // know there's room for them.  If no capacity is given we copy all
+  // of them here.
+  int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
+  int i;
+  int pos = 0;
+  for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
+    i::uc32 c = write_input_buffer.GetNext();
+    int written = unibrow::Utf8::Encode(buffer + pos, c);
+    pos += written;
+  }
+  if (i < len) {
+    // For the last characters we need to check the length for each one
+    // because they may be longer than the remaining space in the
+    // buffer.
+    char intermediate[unibrow::Utf8::kMaxEncodedSize];
+    for (; i < len && pos < capacity; i++) {
+      i::uc32 c = write_input_buffer.GetNext();
+      int written = unibrow::Utf8::Encode(intermediate, c);
+      if (pos + written <= capacity) {
+        for (int j = 0; j < written; j++)
+          buffer[pos + j] = intermediate[j];
+        pos += written;
+      } else {
+        // We've reached the end of the buffer
+        break;
+      }
+    }
+  }
+  if (i == len && (capacity == -1 || pos < capacity))
+    buffer[pos++] = '\0';
+  return pos;
+}
+
+
 int String::WriteAscii(char* buffer, int start, int length) {
   if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
   LOG_API("String::WriteAscii");
@@ -2096,7 +2216,7 @@
 
 
 const char* v8::V8::GetVersion() {
-  return "0.3.0";
+  return "0.3.1";
 }
 
 
@@ -2501,13 +2621,40 @@
 }
 
 
+String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
+  EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
+  HandleScope scope;
+  TryCatch try_catch;
+  Handle<String> str = obj->ToString();
+  if (str.IsEmpty()) {
+    str_ = NULL;
+    length_ = 0;
+  } else {
+    length_ = str->Utf8Length();
+    str_ = i::NewArray<char>(length_ + 1);
+    str->WriteUtf8(str_);
+  }
+}
+
+
+String::Utf8Value::~Utf8Value() {
+  i::DeleteArray(str_);
+}
+
+
 String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
   EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
   HandleScope scope;
+  TryCatch try_catch;
   Handle<String> str = obj->ToString();
-  int length = str->Length();
-  str_ = i::NewArray<char>(length + 1);
-  str->WriteAscii(str_);
+  if (str.IsEmpty()) {
+    str_ = NULL;
+    length_ = 0;
+  } else {
+    length_ = str->Length();
+    str_ = i::NewArray<char>(length_ + 1);
+    str->WriteAscii(str_);
+  }
 }
 
 
@@ -2519,10 +2666,16 @@
 String::Value::Value(v8::Handle<v8::Value> obj) {
   EnsureInitialized("v8::String::Value::Value()");
   HandleScope scope;
+  TryCatch try_catch;
   Handle<String> str = obj->ToString();
-  int length = str->Length();
-  str_ = i::NewArray<uint16_t>(length + 1);
-  str->Write(str_);
+  if (str.IsEmpty()) {
+    str_ = NULL;
+    length_ = 0;
+  } else {
+    length_ = str->Length();
+    str_ = i::NewArray<uint16_t>(length_ + 1);
+    str->Write(str_);
+  }
 }
 
 
diff --git a/src/api.h b/src/api.h
index cd81174..18dea43 100644
--- a/src/api.h
+++ b/src/api.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/apinatives.js b/src/apinatives.js
index 9ec2090..7d40256 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/arguments.h b/src/arguments.h
index 55e9c45..2ec68ed 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/array.js b/src/array.js
index 105f41b..a62cf4d 100644
--- a/src/array.js
+++ b/src/array.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -31,15 +31,6 @@
 
 // -------------------------------------------------------------------
 
-// Determines if the array contains the element.
-function Contains(array, element) {
-  var length = array.length;
-  for (var i = 0; i < length; i++) {
-    if (array[i] === element) return true;
-  }
-  return false;
-};
-
 
 // Global list of arrays visited during toString, toLocaleString and
 // join invocations.
@@ -111,8 +102,7 @@
   if (is_array) {
     // If the array is cyclic, return the empty string for already
     // visited arrays.
-    if (Contains(visited_arrays, array)) return '';
-    visited_arrays[visited_arrays.length] = array;
+    if (!%PushIfAbsent(visited_arrays, array)) return '';
   }
 
   // Attempt to convert the elements.
@@ -121,6 +111,14 @@
       return SparseJoin(array, length, convert);
     }
 
+    // Fast case for one-element arrays.
+    if (length == 1) {
+      var e = array[0];
+      if (!IS_UNDEFINED(e) || (0 in array)) {
+        return convert(e);
+      }
+    }
+
     var builder = new StringBuilder();
 
     for (var i = 0; i < length; i++) {
@@ -219,8 +217,9 @@
         // %HasLocalProperty would be the appropriate test.  We follow
         // KJS in consulting the prototype.
         var current = array[j];
-        if (!IS_UNDEFINED(current) || j in array)
+        if (!IS_UNDEFINED(current) || j in array) {
           new_array[j] = current;
+        }
         j++;
       }
       j = start_i + del_count;
@@ -230,8 +229,9 @@
         // appropriate test.  We follow KJS in consulting the
         // prototype.
         var current = array[j];
-        if (!IS_UNDEFINED(current) || j in array)
+        if (!IS_UNDEFINED(current) || j in array) {
           new_array[j - del_count + num_additional_args] = current;
+        }
         j++;
       }
     } else {
@@ -241,16 +241,18 @@
           // %HasLocalProperty would be the appropriate test.  We follow
           // KJS in consulting the prototype.
           var current = array[key];
-          if (!IS_UNDEFINED(current) || key in array)
+          if (!IS_UNDEFINED(current) || key in array) {
             new_array[key] = current;
+          }
         } else if (key >= start_i + del_count) {
           // ECMA-262 15.4.4.12 lines 24 and 41.  The spec could also
           // be interpreted such that %HasLocalProperty would be the
           // appropriate test.  We follow KJS in consulting the
           // prototype.
           var current = array[key];
-          if (!IS_UNDEFINED(current) || key in array)
+          if (!IS_UNDEFINED(current) || key in array) {
             new_array[key - del_count + num_additional_args] = current;
+          }
         }
       }
     }
@@ -658,6 +660,9 @@
     if (IS_FUNCTION(comparefn)) {
       return comparefn.call(null, x, y);
     }
+    if (%_IsSmi(x) && %_IsSmi(y)) {
+      return %SmiLexicographicCompare(x, y);
+    }
     x = ToString(x);
     y = ToString(y);
     if (x == y) return 0;
@@ -677,7 +682,7 @@
       var parent_index = ((child_index + 1) >> 1) - 1;
       var parent_value = this[parent_index], child_value = this[child_index];
       if (Compare(parent_value, child_value) < 0) {
-        this[parent_index] = child_value; 
+        this[parent_index] = child_value;
         this[child_index] = parent_value;
       } else {
         break;
@@ -695,17 +700,17 @@
     while (true) {
       var child_index = ((parent_index + 1) << 1) - 1;
       if (child_index >= i) break;
-      var child1_value = this[child_index]; 
+      var child1_value = this[child_index];
       var child2_value = this[child_index + 1];
       var parent_value = this[parent_index];
       if (child_index + 1 >= i || Compare(child1_value, child2_value) > 0) {
         if (Compare(parent_value, child1_value) > 0) break;
-        this[child_index] = parent_value; 
+        this[child_index] = parent_value;
         this[parent_index] = child1_value;
         parent_index = child_index;
       } else {
         if (Compare(parent_value, child2_value) > 0) break;
-        this[child_index + 1] = parent_value; 
+        this[child_index + 1] = parent_value;
         this[parent_index] = child2_value;
         parent_index = child_index + 1;
       }
diff --git a/src/assembler-arm-inl.h b/src/assembler-arm-inl.h
index 6bc900a..d949811 100644
--- a/src/assembler-arm-inl.h
+++ b/src/assembler-arm-inl.h
@@ -32,7 +32,7 @@
 
 // The original source code covered by the above license above has been modified
 // significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 #ifndef V8_ASSEMBLER_ARM_INL_H_
 #define V8_ASSEMBLER_ARM_INL_H_
diff --git a/src/assembler-arm.cc b/src/assembler-arm.cc
index 6089b0f..e057fe0 100644
--- a/src/assembler-arm.cc
+++ b/src/assembler-arm.cc
@@ -32,7 +32,7 @@
 
 // The original source code covered by the above license above has been modified
 // significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 #include "v8.h"
 
diff --git a/src/assembler-arm.h b/src/assembler-arm.h
index f8cdb00..8591362 100644
--- a/src/assembler-arm.h
+++ b/src/assembler-arm.h
@@ -32,7 +32,7 @@
 
 // The original source code covered by the above license above has been modified
 // significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 // A light-weight ARM Assembler
 // Generates user mode instructions for the ARM architecture up to version 5
diff --git a/src/assembler-ia32-inl.h b/src/assembler-ia32-inl.h
index 837f295..66102e6 100644
--- a/src/assembler-ia32-inl.h
+++ b/src/assembler-ia32-inl.h
@@ -30,7 +30,7 @@
 
 // The original source code covered by the above license above has been
 // modified significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 // A light-weight IA32 Assembler.
 
diff --git a/src/assembler-ia32.cc b/src/assembler-ia32.cc
index b9e1bdb..483ae0e 100644
--- a/src/assembler-ia32.cc
+++ b/src/assembler-ia32.cc
@@ -32,7 +32,7 @@
 
 // The original source code covered by the above license above has been modified
 // significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 #include "v8.h"
 
diff --git a/src/assembler-ia32.h b/src/assembler-ia32.h
index 183ad2e..700253e 100644
--- a/src/assembler-ia32.h
+++ b/src/assembler-ia32.h
@@ -30,7 +30,7 @@
 
 // The original source code covered by the above license above has been
 // modified significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 // A light-weight IA32 Assembler.
 
diff --git a/src/assembler.cc b/src/assembler.cc
index ebe0d6a..7b4ffc7 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -30,7 +30,7 @@
 
 // The original source code covered by the above license above has been
 // modified significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 #include "v8.h"
 
diff --git a/src/assembler.h b/src/assembler.h
index 33fc056..d50de61 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -30,7 +30,7 @@
 
 // The original source code covered by the above license above has been
 // modified significantly by Google Inc.
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
 #ifndef V8_ASSEMBLER_H_
 #define V8_ASSEMBLER_H_
diff --git a/src/ast.cc b/src/ast.cc
index 6296f95..6e60078 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/ast.h b/src/ast.h
index 55dda26..ab7bc8d 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index de04d1a..1006108 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index ff905ce..6b5f987 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/builtins-arm.cc b/src/builtins-arm.cc
index ef9f093..74f157f 100644
--- a/src/builtins-arm.cc
+++ b/src/builtins-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/builtins-ia32.cc b/src/builtins-ia32.cc
index a432197..bf63464 100644
--- a/src/builtins-ia32.cc
+++ b/src/builtins-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/builtins.cc b/src/builtins.cc
index dc264b4..02f3d8a 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/builtins.h b/src/builtins.h
index 4e04bbc..13bd3d5 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/char-predicates-inl.h b/src/char-predicates-inl.h
index 32f60dd..b575bdf 100644
--- a/src/char-predicates-inl.h
+++ b/src/char-predicates-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/char-predicates.h b/src/char-predicates.h
index 2800f02..3fcaeb6 100644
--- a/src/char-predicates.h
+++ b/src/char-predicates.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/checks.cc b/src/checks.cc
index 14889f1..c01c9b2 100644
--- a/src/checks.cc
+++ b/src/checks.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -74,8 +74,8 @@
                        const char* value_source,
                        v8::Handle<v8::Value> value) {
   if (!expected->Equals(value)) {
-    v8::String::AsciiValue value_str(value);
-    v8::String::AsciiValue expected_str(expected);
+    v8::String::Utf8Value value_str(value);
+    v8::String::Utf8Value expected_str(expected);
     V8_Fatal(file, line,
              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
              expected_source, value_source, *expected_str, *value_str);
@@ -90,7 +90,7 @@
                           const char* value_source,
                           v8::Handle<v8::Value> value) {
   if (unexpected->Equals(value)) {
-    v8::String::AsciiValue value_str(value);
+    v8::String::Utf8Value value_str(value);
     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
              unexpected_source, value_source, *value_str);
   }
diff --git a/src/checks.h b/src/checks.h
index 6b3b602..9dd45ce 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index a8ee99c..ebc30ae 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/code-stubs.h b/src/code-stubs.h
index b4f7c28..6e8c024 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/code.h b/src/code.h
index 004c362..87e0794 100644
--- a/src/code.h
+++ b/src/code.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc
index c4d3f38..fa58084 100644
--- a/src/codegen-arm.cc
+++ b/src/codegen-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -295,6 +295,8 @@
   virtual void GenerateSetValueOf(ZoneList<Expression*>* args);
 
   virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
+
+  virtual void GenerateObjectEquals(ZoneList<Expression*>* args);
 };
 
 
@@ -3998,6 +4000,19 @@
 }
 
 
+void ArmCodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 2);
+
+  // Load the two objects into registers and perform the comparison.
+  Load(args->at(0));
+  Load(args->at(1));
+  __ pop(r0);
+  __ pop(r1);
+  __ cmp(r0, Operand(r1));
+  cc_reg_ = eq;
+}
+
+
 void ArmCodeGenerator::GenerateShiftDownAndTailCall(
     ZoneList<Expression*>* args) {
   // r0 = number of arguments
diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc
index 6d38136..52f5a4e 100644
--- a/src/codegen-ia32.cc
+++ b/src/codegen-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -314,6 +314,8 @@
   virtual void GenerateSetValueOf(ZoneList<Expression*>* args);
 
   virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
+
+  virtual void GenerateObjectEquals(ZoneList<Expression*>* args);
 };
 
 
@@ -4264,6 +4266,18 @@
 }
 
 
+void Ia32CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 2);
+
+  // Load the two objects into registers and perform the comparison.
+  Load(args->at(0));
+  Load(args->at(1));
+  __ pop(eax);
+  __ pop(ecx);
+  __ cmp(eax, Operand(ecx));
+  cc_reg_ = equal;
+}
+
 
 void Ia32CodeGenerator::VisitCallRuntime(CallRuntime* node) {
   if (CheckForInlineRuntimeCall(node)) return;
diff --git a/src/codegen-inl.h b/src/codegen-inl.h
index 912d205..c6abbec 100644
--- a/src/codegen-inl.h
+++ b/src/codegen-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/codegen.cc b/src/codegen.cc
index 14ab511..3631a95 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -256,7 +256,9 @@
     {&v8::internal::CodeGenerator::GenerateSetValueOf,
      "_SetValueOf"},
     {&v8::internal::CodeGenerator::GenerateFastCharCodeAt,
-     "_FastCharCodeAt"}
+     "_FastCharCodeAt"},
+    {&v8::internal::CodeGenerator::GenerateObjectEquals,
+     "_ObjectEquals"}
   };
   if (node->name()->length() > 0 && node->name()->Get(0) == '_') {
     for (unsigned i = 0;
diff --git a/src/codegen.h b/src/codegen.h
index 9833445..8f0e265 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -173,6 +173,9 @@
   // Fast support for charCodeAt(n).
   virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args) = 0;
 
+  // Fast support for object equality testing.
+  virtual void GenerateObjectEquals(ZoneList<Expression*>* args) = 0;
+
  private:
   bool is_eval_;  // Tells whether code is generated for eval.
   Handle<Script> script_;
diff --git a/src/compiler.cc b/src/compiler.cc
index 7d2e661..78772a1 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/compiler.h b/src/compiler.h
index 3ee86b1..1f37ad6 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/constants-arm.h b/src/constants-arm.h
index 41fd5ba..a388009 100644
--- a/src/constants-arm.h
+++ b/src/constants-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/contexts.cc b/src/contexts.cc
index 895fbeb..2142fac 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/contexts.h b/src/contexts.h
index 5fb3160..f0869ac 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/conversions-inl.h b/src/conversions-inl.h
index 67ea104..e3db4e9 100644
--- a/src/conversions-inl.h
+++ b/src/conversions-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/conversions.cc b/src/conversions.cc
index 45956bc..85637ee 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/conversions.h b/src/conversions.h
index 58ef7e4..605327d 100644
--- a/src/conversions.h
+++ b/src/conversions.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/counters.cc b/src/counters.cc
index bf1df7b..3baad29 100644
--- a/src/counters.cc
+++ b/src/counters.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/counters.h b/src/counters.h
index ff34b03..6dd9e94 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/cpu-arm.cc b/src/cpu-arm.cc
index c0373f9..7369661 100644
--- a/src/cpu-arm.cc
+++ b/src/cpu-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/cpu-ia32.cc b/src/cpu-ia32.cc
index 73b8e51..d61a548 100644
--- a/src/cpu-ia32.cc
+++ b/src/cpu-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/cpu.h b/src/cpu.h
index 3b8795a..d12c30c 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/date-delay.js b/src/date-delay.js
index a2e9ac4..d45883d 100644
--- a/src/date-delay.js
+++ b/src/date-delay.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/dateparser.cc b/src/dateparser.cc
index 926b852..69cf748 100644
--- a/src/dateparser.cc
+++ b/src/dateparser.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/dateparser.h b/src/dateparser.h
index a53698a..bf96852 100644
--- a/src/dateparser.h
+++ b/src/dateparser.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/debug-delay.js b/src/debug-delay.js
index 19461df..9ca5b0b 100644
--- a/src/debug-delay.js
+++ b/src/debug-delay.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/debug.cc b/src/debug.cc
index 7487cdc..f69b6b7 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -537,8 +537,10 @@
 
   // Check for caught exceptions.
   if (caught_exception) {
-    MessageHandler::ReportMessage("error_loading_debugger", NULL,
-                                  HandleVector<Object>(&result, 1));
+    Handle<Object> message = MessageHandler::MakeMessageObject(
+        "error_loading_debugger", NULL, HandleVector<Object>(&result, 1),
+        Handle<String>());
+    MessageHandler::ReportMessage(NULL, message);
     return false;
   }
 
diff --git a/src/debug.h b/src/debug.h
index a26a1bf..23b0ff2 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,8 +25,8 @@
 // (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_DEBUG_H_
-#define V8_DEBUG_H_
+#ifndef V8_V8_DEBUG_H_
+#define V8_V8_DEBUG_H_
 
 #include "../include/v8-debug.h"
 #include "assembler.h"
@@ -574,4 +574,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // V8_DEBUG_H_
+#endif  // V8_V8_DEBUG_H_
diff --git a/src/disasm-arm.cc b/src/disasm-arm.cc
index 15c93ac..0b69bdf 100644
--- a/src/disasm-arm.cc
+++ b/src/disasm-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/disasm-ia32.cc b/src/disasm-ia32.cc
index 36282c8..ac12e1f 100644
--- a/src/disasm-ia32.cc
+++ b/src/disasm-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/disasm.h b/src/disasm.h
index 18cad8b..f590b28 100644
--- a/src/disasm.h
+++ b/src/disasm.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/disassembler.cc b/src/disassembler.cc
index 51a9bf1..635440d 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/disassembler.h b/src/disassembler.h
index e61967b..5003c00 100644
--- a/src/disassembler.h
+++ b/src/disassembler.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/dtoa-config.c b/src/dtoa-config.c
index 5a4cf09..cb73c17 100644
--- a/src/dtoa-config.c
+++ b/src/dtoa-config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Google, Inc. All Rights Reserved.
+ * Copyright 2007-2008 the V8 project authors. All rights reserved.
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
diff --git a/src/execution.cc b/src/execution.cc
index 7f55c6f..ce2259e 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -130,9 +130,12 @@
                                   Object*** args,
                                   bool* caught_exception) {
   // Enter a try-block while executing the JavaScript code. To avoid
-  // duplicate error printing it must be non-verbose.
+  // duplicate error printing it must be non-verbose.  Also, to avoid
+  // creating message objects during stack overflow we shouldn't
+  // capture messages.
   v8::TryCatch catcher;
   catcher.SetVerbose(false);
+  catcher.SetCaptureMessage(false);
 
   Handle<Object> result = Invoke(false, func, receiver, argc, args,
                                  caught_exception);
@@ -656,7 +659,7 @@
 
 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
   // All allocation spaces other than NEW_SPACE have the same effect.
-  Heap::CollectGarbage(0, OLD_SPACE);
+  Heap::CollectGarbage(0, OLD_DATA_SPACE);
   return v8::Undefined();
 }
 
diff --git a/src/execution.h b/src/execution.h
index 5d408a9..2dc7540 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/factory.cc b/src/factory.cc
index 39bc763..9149cb8 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -49,7 +49,7 @@
 }
 
 
-// Symbols are created in the old generation (code space).
+// Symbols are created in the old generation (data space).
 Handle<String> Factory::LookupSymbol(Vector<const char> string) {
   CALL_HEAP_FUNCTION(Heap::LookupSymbol(string), String);
 }
diff --git a/src/factory.h b/src/factory.h
index 40e1305..9efbcd5 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/flags-inl.h b/src/flags-inl.h
index e394e3a..2bbf581 100644
--- a/src/flags-inl.h
+++ b/src/flags-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/flags.cc b/src/flags.cc
index 7ce4b8a..1f8413c 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/flags.h b/src/flags.h
index da5520f..07eb691 100644
--- a/src/flags.h
+++ b/src/flags.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames-arm.cc b/src/frames-arm.cc
index ace49b8..238eded 100644
--- a/src/frames-arm.cc
+++ b/src/frames-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames-arm.h b/src/frames-arm.h
index e08758f..463ae60 100644
--- a/src/frames-arm.h
+++ b/src/frames-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames-ia32.cc b/src/frames-ia32.cc
index 6911189..ddf4bfd 100644
--- a/src/frames-ia32.cc
+++ b/src/frames-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames-ia32.h b/src/frames-ia32.h
index 0e9176c..a39e5b9 100644
--- a/src/frames-ia32.h
+++ b/src/frames-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames-inl.h b/src/frames-inl.h
index 2bd81bb..fac1418 100644
--- a/src/frames-inl.h
+++ b/src/frames-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames.cc b/src/frames.cc
index ef976a0..3b1a921 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/frames.h b/src/frames.h
index 693cfed..9dc9319 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/global-handles.cc b/src/global-handles.cc
index de071df..bb36e35 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/global-handles.h b/src/global-handles.h
index b7783f6..78fb3a1 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/globals.h b/src/globals.h
index 7bf5802..fa7038b 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -214,17 +214,19 @@
 // NOTE: SpaceIterator depends on AllocationSpace enumeration values being
 // consecutive.
 enum AllocationSpace {
-  NEW_SPACE,
-  OLD_SPACE,
-  CODE_SPACE,
-  MAP_SPACE,
-  LO_SPACE,
+  NEW_SPACE,          // Semispaces collected with copying collector.
+  OLD_POINTER_SPACE,  // Must be first of the paged spaces - see PagedSpaces.
+  OLD_DATA_SPACE,     // May not have pointers to new space.
+  CODE_SPACE,         // Also one of the old spaces.  Marked executable.
+  MAP_SPACE,          // Only map objects.
+  LO_SPACE,           // Large objects.
   FIRST_SPACE = NEW_SPACE,
-  LAST_SPACE = LO_SPACE
+  LAST_SPACE = LO_SPACE  // <= 5 (see kSpaceBits and kLOSpacePointer)
 };
 const int kSpaceTagSize = 3;
 const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
 
+
 // A flag that indicates whether objects should be pretenured when
 // allocated (allocated directly into the old generation) or not
 // (allocated in the young generation if the object size and type
@@ -233,6 +235,8 @@
 
 enum GarbageCollector { SCAVENGER, MARK_COMPACTOR };
 
+enum Executability { NOT_EXECUTABLE, EXECUTABLE };
+
 
 // A CodeDesc describes a buffer holding instructions and relocation
 // information. The instructions start at the beginning of the buffer
diff --git a/src/handles-inl.h b/src/handles-inl.h
index ab18141..502aeab 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/handles.cc b/src/handles.cc
index 0e8826d..6c41a57 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/handles.h b/src/handles.h
index 6fea67b..229b6a4 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/hashmap.cc b/src/hashmap.cc
index 6e42d2f..126f739 100644
--- a/src/hashmap.cc
+++ b/src/hashmap.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/hashmap.h b/src/hashmap.h
index 1ea9291..7826311 100644
--- a/src/hashmap.h
+++ b/src/hashmap.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 22ef441..c03c22c 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -44,7 +44,8 @@
 }
 
 
-Object* Heap::AllocateRaw(int size_in_bytes, AllocationSpace space) {
+Object* Heap::AllocateRaw(int size_in_bytes,
+                          AllocationSpace space) {
   ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
 #ifdef DEBUG
   if (FLAG_gc_interval >= 0 &&
@@ -60,8 +61,10 @@
   }
 
   Object* result;
-  if (OLD_SPACE == space) {
-    result = old_space_->AllocateRaw(size_in_bytes);
+  if (OLD_POINTER_SPACE == space) {
+    result = old_pointer_space_->AllocateRaw(size_in_bytes);
+  } else if (OLD_DATA_SPACE == space) {
+    result = old_data_space_->AllocateRaw(size_in_bytes);
   } else if (CODE_SPACE == space) {
     result = code_space_->AllocateRaw(size_in_bytes);
   } else if (LO_SPACE == space) {
@@ -75,32 +78,6 @@
 }
 
 
-Object* Heap::AllocateForDeserialization(int size_in_bytes,
-                                         AllocationSpace space) {
-  ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
-  PagedSpace* where;
-
-  switch (space) {
-    case NEW_SPACE:
-      return new_space_->AllocateRaw(size_in_bytes);
-    case LO_SPACE:
-      return lo_space_->AllocateRaw(size_in_bytes);
-    case OLD_SPACE:
-      where = old_space_;
-      break;
-    case CODE_SPACE:
-      where = code_space_;
-      break;
-    case MAP_SPACE:
-      where = map_space_;
-      break;
-  }
-
-  // Only paged spaces fall through.
-  return where->AllocateForDeserialization(size_in_bytes);
-}
-
-
 Object* Heap::NumberFromInt32(int32_t value) {
   if (Smi::IsValid(value)) return Smi::FromInt(value);
   // Bypass NumberFromDouble to avoid various redundant checks.
@@ -160,9 +137,9 @@
 }
 
 
-AllocationSpace Heap::TargetSpace(HeapObject* object) {
-  // Heap numbers and sequential strings are promoted to code space, all
-  // other object types are promoted to old space.  We do not use
+OldSpace* Heap::TargetSpace(HeapObject* object) {
+  // Heap numbers and sequential strings are promoted to old data space, all
+  // other object types are promoted to old pointer space.  We do not use
   // object->IsHeapNumber() and object->IsSeqString() because we already
   // know that object has the heap object tag.
   InstanceType type = object->map()->instance_type();
@@ -171,7 +148,7 @@
       type != HEAP_NUMBER_TYPE &&
       (type >= FIRST_NONSTRING_TYPE ||
        String::cast(object)->representation_tag() != kSeqStringTag);
-  return has_pointers ? OLD_SPACE : CODE_SPACE;
+  return has_pointers ? old_pointer_space_ : old_data_space_;
 }
 
 
diff --git a/src/heap.cc b/src/heap.cc
index b04b4c1..5548fe9 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -83,7 +83,8 @@
 
 
 NewSpace* Heap::new_space_ = NULL;
-OldSpace* Heap::old_space_ = NULL;
+OldSpace* Heap::old_pointer_space_ = NULL;
+OldSpace* Heap::old_data_space_ = NULL;
 OldSpace* Heap::code_space_ = NULL;
 MapSpace* Heap::map_space_ = NULL;
 LargeObjectSpace* Heap::lo_space_ = NULL;
@@ -127,7 +128,8 @@
   if (!HasBeenSetup()) return 0;
 
   return new_space_->Capacity() +
-      old_space_->Capacity() +
+      old_pointer_space_->Capacity() +
+      old_data_space_->Capacity() +
       code_space_->Capacity() +
       map_space_->Capacity();
 }
@@ -137,7 +139,8 @@
   if (!HasBeenSetup()) return 0;
 
   return new_space_->Available() +
-      old_space_->Available() +
+      old_pointer_space_->Available() +
+      old_data_space_->Available() +
       code_space_->Available() +
       map_space_->Available();
 }
@@ -145,10 +148,11 @@
 
 bool Heap::HasBeenSetup() {
   return new_space_ != NULL &&
-      old_space_ != NULL &&
-      code_space_ != NULL &&
-      map_space_ != NULL &&
-      lo_space_ != NULL;
+         old_pointer_space_ != NULL &&
+         old_data_space_ != NULL &&
+         code_space_ != NULL &&
+         map_space_ != NULL &&
+         lo_space_ != NULL;
 }
 
 
@@ -175,13 +179,13 @@
   // Is there enough space left in OLD to guarantee that a scavenge can
   // succeed?
   //
-  // Note that old_space_->MaxAvailable() undercounts the memory available
+  // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
   // for object promotion. It counts only the bytes that the memory
   // allocator has not yet allocated from the OS and assigned to any space,
   // and does not count available bytes already in the old space or code
   // space.  Undercounting is safe---we may get an unrequested full GC when
   // a scavenge would have succeeded.
-  if (old_space_->MaxAvailable() <= new_space_->Size()) {
+  if (MemoryAllocator::MaxAvailable() <= new_space_->Size()) {
     Counters::gc_compactor_caused_by_oldspace_exhaustion.Increment();
     return MARK_COMPACTOR;
   }
@@ -256,9 +260,8 @@
   if (FLAG_gc_verbose) Print();
 
   if (FLAG_print_rset) {
-    // By definition, code space does not have remembered set bits that we
-    // care about.
-    old_space_->PrintRSet();
+    // Not all spaces have remembered set bits that we care about.
+    old_pointer_space_->PrintRSet();
     map_space_->PrintRSet();
     lo_space_->PrintRSet();
   }
@@ -270,11 +273,10 @@
 }
 
 int Heap::SizeOfObjects() {
-  return new_space_->Size() +
-      old_space_->Size() +
-      code_space_->Size() +
-      map_space_->Size() +
-      lo_space_->Size();
+  int total = 0;
+  AllSpaces spaces;
+  while (Space* space = spaces.next()) total += space->Size();
+  return total;
 }
 
 void Heap::GarbageCollectionEpilogue() {
@@ -303,6 +305,14 @@
 }
 
 
+void Heap::CollectAllGarbage() {
+  // Since we are ignoring the return value, the exact choice of space does
+  // not matter, so long as we do not specify NEW_SPACE, which would not
+  // cause a full GC.
+  CollectGarbage(0, OLD_POINTER_SPACE);
+}
+
+
 bool Heap::CollectGarbage(int requested_size, AllocationSpace space) {
   // The VM is in the GC state until exiting this function.
   VMState state(GC);
@@ -344,8 +354,10 @@
   switch (space) {
     case NEW_SPACE:
       return new_space_->Available() >= requested_size;
-    case OLD_SPACE:
-      return old_space_->Available() >= requested_size;
+    case OLD_POINTER_SPACE:
+      return old_pointer_space_->Available() >= requested_size;
+    case OLD_DATA_SPACE:
+      return old_data_space_->Available() >= requested_size;
     case CODE_SPACE:
       return code_space_->Available() >= requested_size;
     case MAP_SPACE:
@@ -381,7 +393,7 @@
 
     // If we have used the mark-compact collector to collect the new
     // space, and it has not compacted the new space, we force a
-    // separate scavenge collection.  THIS IS A HACK.  It covers the
+    // separate scavenge collection.  This is a hack.  It covers the
     // case where (1) a new space collection was requested, (2) the
     // collector selection policy selected the mark-compact collector,
     // and (3) the mark-compact collector policy selected not to
@@ -435,6 +447,10 @@
 
 
 void Heap::MarkCompactPrologue() {
+  // Empty eval caches
+  Heap::eval_cache_global_ = Heap::null_value();
+  Heap::eval_cache_non_global_ = Heap::null_value();
+
   RegExpImpl::OldSpaceCollectionPrologue();
   Top::MarkCompactPrologue();
   ThreadManager::MarkCompactPrologue();
@@ -483,9 +499,9 @@
 
 
 #ifdef DEBUG
-// Visitor class to verify pointers in code space do not point into
+// Visitor class to verify pointers in code or data space do not point into
 // new space.
-class VerifyCodeSpacePointersVisitor: public ObjectVisitor {
+class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor {
  public:
   void VisitPointers(Object** start, Object**end) {
     for (Object** current = start; current < end; current++) {
@@ -500,7 +516,7 @@
 void Heap::Scavenge() {
 #ifdef DEBUG
   if (FLAG_enable_slow_asserts) {
-    VerifyCodeSpacePointersVisitor v;
+    VerifyNonPointerSpacePointersVisitor v;
     HeapObjectIterator it(code_space_);
     while (it.has_next()) {
       HeapObject* object = it.next();
@@ -560,8 +576,8 @@
   IterateRoots(&copy_visitor);
 
   // Copy objects reachable from the old generation.  By definition, there
-  // are no intergenerational pointers in code space.
-  IterateRSet(old_space_, &CopyObject);
+  // are no intergenerational pointers in code or data spaces.
+  IterateRSet(old_pointer_space_, &CopyObject);
   IterateRSet(map_space_, &CopyObject);
   lo_space_->IterateRSet(&CopyObject);
 
@@ -694,12 +710,13 @@
 
 
 void Heap::RebuildRSets() {
-  // By definition, we do not care about remembered set bits in code space.
+  // By definition, we do not care about remembered set bits in code or data
+  // spaces.
   map_space_->ClearRSet();
   RebuildRSets(map_space_);
 
-  old_space_->ClearRSet();
-  RebuildRSets(old_space_);
+  old_pointer_space_->ClearRSet();
+  RebuildRSets(old_pointer_space_);
 
   Heap::lo_space_->ClearRSet();
   RebuildRSets(lo_space_);
@@ -767,7 +784,7 @@
 
   // 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 the old space, the code space, or the to space of the new
+  // point to an old space, the code space, or the to space of the new
   // generation.
   MapWord first_word = object->map_word();
 
@@ -802,26 +819,23 @@
   Object* result;
   // If the object should be promoted, we try to copy it to old space.
   if (ShouldBePromoted(object->address(), object_size)) {
-    AllocationSpace target_space = Heap::TargetSpace(object);
-    if (target_space == OLD_SPACE) {
-      result = old_space_->AllocateRaw(object_size);
-    } else {
-      ASSERT(target_space == CODE_SPACE);
-      result = code_space_->AllocateRaw(object_size);
-    }
+    OldSpace* target_space = Heap::TargetSpace(object);
+    ASSERT(target_space == Heap::old_pointer_space_ ||
+           target_space == Heap::old_data_space_);
+    result = target_space->AllocateRaw(object_size);
 
     if (!result->IsFailure()) {
       *p = MigrateObject(p, HeapObject::cast(result), object_size);
-      if (target_space == OLD_SPACE) {
+      if (target_space == Heap::old_pointer_space_) {
         // Record the object's address at the top of the to space, to allow
         // it to be swept by the scavenger.
         promoted_top -= kPointerSize;
         Memory::Object_at(promoted_top) = *p;
       } else {
 #ifdef DEBUG
-        // Objects promoted to the code space should not have pointers to
+        // Objects promoted to the data space should not have pointers to
         // new space.
-        VerifyCodeSpacePointersVisitor v;
+        VerifyNonPointerSpacePointersVisitor v;
         (*p)->Iterate(&v);
 #endif
       }
@@ -890,7 +904,7 @@
   if (obj->IsFailure()) return false;
   empty_fixed_array_ = FixedArray::cast(obj);
 
-  obj = Allocate(oddball_map(), CODE_SPACE);
+  obj = Allocate(oddball_map(), OLD_DATA_SPACE);
   if (obj->IsFailure()) return false;
   null_value_ = obj;
 
@@ -1016,7 +1030,7 @@
   // Statically ensure that it is safe to allocate heap numbers in paged
   // spaces.
   STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize);
-  AllocationSpace space = (pretenure == TENURED) ? CODE_SPACE : NEW_SPACE;
+  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
   Object* result = AllocateRaw(HeapNumber::kSize, space);
   if (result->IsFailure()) return result;
 
@@ -1042,7 +1056,7 @@
 Object* Heap::CreateOddball(Map* map,
                             const char* to_string,
                             Object* to_number) {
-  Object* result = Allocate(map, CODE_SPACE);
+  Object* result = Allocate(map, OLD_DATA_SPACE);
   if (result->IsFailure()) return result;
   return Oddball::cast(result)->Initialize(to_string, to_number);
 }
@@ -1112,7 +1126,7 @@
   if (obj->IsFailure()) return false;
   nan_value_ = obj;
 
-  obj = Allocate(oddball_map(), CODE_SPACE);
+  obj = Allocate(oddball_map(), OLD_DATA_SPACE);
   if (obj->IsFailure()) return false;
   undefined_value_ = obj;
   ASSERT(!InNewSpace(undefined_value()));
@@ -1194,6 +1208,10 @@
   if (obj->IsFailure()) return false;
   natives_source_cache_ = FixedArray::cast(obj);
 
+  // Initialized eval cache to null value.
+  eval_cache_global_ = null_value();
+  eval_cache_non_global_ = null_value();
+
   return true;
 }
 
@@ -1295,7 +1313,8 @@
 Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) {
   // Statically ensure that it is safe to allocate proxies in paged spaces.
   STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize);
-  AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
+  AllocationSpace space =
+      (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
   Object* result = Allocate(proxy_map(), space);
   if (result->IsFailure()) return result;
 
@@ -1491,9 +1510,11 @@
 
 Object* Heap::AllocateByteArray(int length) {
   int size = ByteArray::SizeFor(length);
-  AllocationSpace space = size > MaxHeapObjectSize() ? LO_SPACE : NEW_SPACE;
+  AllocationSpace space =
+      size > MaxHeapObjectSize() ? LO_SPACE : NEW_SPACE;
 
   Object* result = AllocateRaw(size, space);
+
   if (result->IsFailure()) return result;
 
   reinterpret_cast<Array*>(result)->set_map(byte_array_map());
@@ -1510,10 +1531,13 @@
   int sinfo_size = 0;
   if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL);
   int obj_size = Code::SizeFor(body_size, sinfo_size);
-  AllocationSpace space =
-      (obj_size > MaxHeapObjectSize()) ? LO_SPACE : CODE_SPACE;
+  Object* result;
+  if (obj_size > MaxHeapObjectSize()) {
+    result = lo_space_->AllocateRawCode(obj_size);
+  } else {
+    result = code_space_->AllocateRaw(obj_size);
+  }
 
-  Object* result = AllocateRaw(obj_size, space);
   if (result->IsFailure()) return result;
 
   // Initialize the object
@@ -1530,9 +1554,6 @@
 #ifdef DEBUG
   code->Verify();
 #endif
-
-  CPU::FlushICache(code->instruction_start(), code->instruction_size());
-
   return code;
 }
 
@@ -1540,9 +1561,13 @@
 Object* Heap::CopyCode(Code* code) {
   // Allocate an object the same size as the code object.
   int obj_size = code->Size();
-  AllocationSpace space =
-      (obj_size > MaxHeapObjectSize()) ? LO_SPACE : CODE_SPACE;
-  Object* result = AllocateRaw(obj_size, space);
+  Object* result;
+  if (obj_size > MaxHeapObjectSize()) {
+    result = lo_space_->AllocateRawCode(obj_size);
+  } else {
+    result = code_space_->AllocateRaw(obj_size);
+  }
+
   if (result->IsFailure()) return result;
 
   // Copy code object.
@@ -1553,9 +1578,6 @@
   // Relocate the copy.
   Code* new_code = Code::cast(result);
   new_code->Relocate(new_addr - old_addr);
-
-  CPU::FlushICache(new_code->instruction_start(), new_code->instruction_size());
-
   return new_code;
 }
 
@@ -1603,7 +1625,7 @@
 Object* Heap::AllocateFunction(Map* function_map,
                                SharedFunctionInfo* shared,
                                Object* prototype) {
-  Object* result = Allocate(function_map, OLD_SPACE);
+  Object* result = Allocate(function_map, OLD_POINTER_SPACE);
   if (result->IsFailure()) return result;
   return InitializeFunction(JSFunction::cast(result), shared, prototype);
 }
@@ -1687,7 +1709,8 @@
   if (properties->IsFailure()) return properties;
 
   // Allocate the JSObject.
-  AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
+  AllocationSpace space =
+      (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
   if (map->instance_size() > MaxHeapObjectSize()) space = LO_SPACE;
   Object* obj = Allocate(map, space);
   if (obj->IsFailure()) return obj;
@@ -1912,7 +1935,8 @@
   }
 
   // Allocate string.
-  AllocationSpace space = (size > MaxHeapObjectSize()) ? LO_SPACE : CODE_SPACE;
+  AllocationSpace space =
+      (size > MaxHeapObjectSize()) ? LO_SPACE : OLD_DATA_SPACE;
   Object* result = AllocateRaw(size, space);
   if (result->IsFailure()) return result;
 
@@ -1931,7 +1955,7 @@
 
 
 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
-  AllocationSpace space = (pretenure == TENURED) ? CODE_SPACE : NEW_SPACE;
+  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
   int size = AsciiString::SizeFor(length);
   if (size > MaxHeapObjectSize()) {
     space = LO_SPACE;
@@ -1961,7 +1985,7 @@
 
 
 Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) {
-  AllocationSpace space = (pretenure == TENURED) ? CODE_SPACE : NEW_SPACE;
+  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
   int size = TwoByteString::SizeFor(length);
   if (size > MaxHeapObjectSize()) {
     space = LO_SPACE;
@@ -1992,7 +2016,7 @@
 
 Object* Heap::AllocateEmptyFixedArray() {
   int size = FixedArray::SizeFor(0);
-  Object* result = AllocateRaw(size, CODE_SPACE);
+  Object* result = AllocateRaw(size, OLD_DATA_SPACE);
   if (result->IsFailure()) return result;
   // Initialize the object.
   reinterpret_cast<Array*>(result)->set_map(fixed_array_map());
@@ -2010,7 +2034,8 @@
   if (size > MaxHeapObjectSize()) {
     result = lo_space_->AllocateRawFixedArray(size);
   } else {
-    AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
+    AllocationSpace space =
+        (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
     result = AllocateRaw(size, space);
   }
   if (result->IsFailure()) return result;
@@ -2108,7 +2133,7 @@
   }
   int size = map->instance_size();
   AllocationSpace space =
-      (size > MaxHeapObjectSize()) ? LO_SPACE : OLD_SPACE;
+      (size > MaxHeapObjectSize()) ? LO_SPACE : OLD_POINTER_SPACE;
   Object* result = Heap::Allocate(map, space);
   if (result->IsFailure()) return result;
   Struct::cast(result)->InitializeBody(size);
@@ -2121,11 +2146,8 @@
 void Heap::Print() {
   if (!HasBeenSetup()) return;
   Top::PrintStack();
-  new_space_->Print();
-  old_space_->Print();
-  code_space_->Print();
-  map_space_->Print();
-  lo_space_->Print();
+  AllSpaces spaces;
+  while (Space* space = spaces.next()) space->Print();
 }
 
 
@@ -2159,8 +2181,10 @@
   MemoryAllocator::ReportStatistics();
   PrintF("To space : ");
   new_space_->ReportStatistics();
-  PrintF("Old space : ");
-  old_space_->ReportStatistics();
+  PrintF("Old pointer space : ");
+  old_pointer_space_->ReportStatistics();
+  PrintF("Old data space : ");
+  old_data_space_->ReportStatistics();
   PrintF("Code space : ");
   code_space_->ReportStatistics();
   PrintF("Map space : ");
@@ -2181,7 +2205,8 @@
   if (OS::IsOutsideAllocatedSpace(addr)) return false;
   return HasBeenSetup() &&
     (new_space_->ToSpaceContains(addr) ||
-     old_space_->Contains(addr) ||
+     old_pointer_space_->Contains(addr) ||
+     old_data_space_->Contains(addr) ||
      code_space_->Contains(addr) ||
      map_space_->Contains(addr) ||
      lo_space_->SlowContains(addr));
@@ -2200,8 +2225,10 @@
   switch (space) {
     case NEW_SPACE:
       return new_space_->ToSpaceContains(addr);
-    case OLD_SPACE:
-      return old_space_->Contains(addr);
+    case OLD_POINTER_SPACE:
+      return old_pointer_space_->Contains(addr);
+    case OLD_DATA_SPACE:
+      return old_data_space_->Contains(addr);
     case CODE_SPACE:
       return code_space_->Contains(addr);
     case MAP_SPACE:
@@ -2221,11 +2248,10 @@
   VerifyPointersVisitor visitor;
   Heap::IterateRoots(&visitor);
 
-  Heap::new_space_->Verify();
-  Heap::old_space_->Verify();
-  Heap::code_space_->Verify();
-  Heap::map_space_->Verify();
-  Heap::lo_space_->Verify();
+  AllSpaces spaces;
+  while (Space* space = spaces.next()) {
+    space->Verify();
+  }
 }
 #endif  // DEBUG
 
@@ -2253,6 +2279,34 @@
 }
 
 
+Object* Heap::LookupEvalCache(bool is_global_context, String* src) {
+  Object* cache = is_global_context ?
+      eval_cache_global_ : eval_cache_non_global_;
+  return cache == null_value() ?
+      null_value() : EvalCache::cast(cache)->Lookup(src);
+}
+
+
+Object* Heap::PutInEvalCache(bool is_global_context, String* src,
+                             JSFunction* value) {
+  Object** cache_ptr = is_global_context ?
+      &eval_cache_global_ : &eval_cache_non_global_;
+
+  if (*cache_ptr == null_value()) {
+    Object* obj = EvalCache::Allocate(kInitialEvalCacheSize);
+    if (obj->IsFailure()) return false;
+    *cache_ptr = obj;
+  }
+
+  Object* new_cache =
+      EvalCache::cast(*cache_ptr)->Put(src, value);
+  if (new_cache->IsFailure()) return new_cache;
+  *cache_ptr = new_cache;
+
+  return value;
+}
+
+
 #ifdef DEBUG
 void Heap::ZapFromSpace() {
   ASSERT(HAS_HEAP_OBJECT_TAG(kFromSpaceZapValue));
@@ -2314,7 +2368,7 @@
 
 void Heap::IterateRSet(PagedSpace* space, ObjectSlotCallback copy_object_func) {
   ASSERT(Page::is_rset_in_use());
-  ASSERT(space == old_space_ || space == map_space_);
+  ASSERT(space == old_pointer_space_ || space == map_space_);
 
   PageIterator it(space, PageIterator::PAGES_IN_USE);
   while (it.has_next()) {
@@ -2419,7 +2473,8 @@
 
 
 int Heap::PromotedSpaceSize() {
-  return old_space_->Size()
+  return old_pointer_space_->Size()
+      + old_data_space_->Size()
       + code_space_->Size()
       + map_space_->Size()
       + lo_space_->Size();
@@ -2466,23 +2521,33 @@
   int old_space_size = new_space_start - old_space_start;
   int code_space_size = young_generation_size_ - old_space_size;
 
-  // Initialize new space. It will not contain code.
+  // Initialize new space.
   new_space_ = new NewSpace(initial_semispace_size_,
                             semispace_size_,
-                            NEW_SPACE,
-                            false);
+                            NEW_SPACE);
   if (new_space_ == NULL) return false;
   if (!new_space_->Setup(new_space_start, young_generation_size_)) return false;
 
   // Initialize old space, set the maximum capacity to the old generation
   // size. It will not contain code.
-  old_space_ = new OldSpace(old_generation_size_, OLD_SPACE, false);
-  if (old_space_ == NULL) return false;
-  if (!old_space_->Setup(old_space_start, old_space_size)) return false;
+  old_pointer_space_ =
+      new OldSpace(old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE);
+  if (old_pointer_space_ == NULL) return false;
+  if (!old_pointer_space_->Setup(old_space_start, old_space_size >> 1)) {
+    return false;
+  }
+  old_data_space_ =
+      new OldSpace(old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE);
+  if (old_data_space_ == NULL) return false;
+  if (!old_data_space_->Setup(old_space_start + (old_space_size >> 1),
+                              old_space_size >> 1)) {
+    return false;
+  }
 
   // Initialize the code space, set its maximum capacity to the old
   // generation size. It needs executable memory.
-  code_space_ = new OldSpace(old_generation_size_, CODE_SPACE, true);
+  code_space_ =
+      new OldSpace(old_generation_size_, CODE_SPACE, EXECUTABLE);
   if (code_space_ == NULL) return false;
   if (!code_space_->Setup(code_space_start, code_space_size)) return false;
 
@@ -2493,8 +2558,10 @@
   // enough to hold at least a page will cause it to allocate.
   if (!map_space_->Setup(NULL, 0)) return false;
 
-  // The large object space may contain code, so it needs executable memory.
-  lo_space_ = new LargeObjectSpace(LO_SPACE, true);
+  // The large object code space may contain code or data.  We set the memory
+  // to be non-executable here for safety, but this means we need to enable it
+  // explicitly when allocating large code objects.
+  lo_space_ = new LargeObjectSpace(LO_SPACE);
   if (lo_space_ == NULL) return false;
   if (!lo_space_->Setup()) return false;
 
@@ -2523,10 +2590,16 @@
     new_space_ = NULL;
   }
 
-  if (old_space_ != NULL) {
-    old_space_->TearDown();
-    delete old_space_;
-    old_space_ = NULL;
+  if (old_pointer_space_ != NULL) {
+    old_pointer_space_->TearDown();
+    delete old_pointer_space_;
+    old_pointer_space_ = NULL;
+  }
+
+  if (old_data_space_ != NULL) {
+    old_data_space_->TearDown();
+    delete old_data_space_;
+    old_data_space_ = NULL;
   }
 
   if (code_space_ != NULL) {
@@ -2554,7 +2627,8 @@
 void Heap::Shrink() {
   // Try to shrink map, old, and code spaces.
   map_space_->Shrink();
-  old_space_->Shrink();
+  old_pointer_space_->Shrink();
+  old_data_space_->Shrink();
   code_space_->Shrink();
 }
 
@@ -2578,6 +2652,57 @@
 #endif
 
 
+Space* AllSpaces::next() {
+  switch (counter_++) {
+    case NEW_SPACE:
+      return Heap::new_space();
+    case OLD_POINTER_SPACE:
+      return Heap::old_pointer_space();
+    case OLD_DATA_SPACE:
+      return Heap::old_data_space();
+    case CODE_SPACE:
+      return Heap::code_space();
+    case MAP_SPACE:
+      return Heap::map_space();
+    case LO_SPACE:
+      return Heap::lo_space();
+    default:
+      return NULL;
+  }
+}
+
+
+PagedSpace* PagedSpaces::next() {
+  switch (counter_++) {
+    case OLD_POINTER_SPACE:
+      return Heap::old_pointer_space();
+    case OLD_DATA_SPACE:
+      return Heap::old_data_space();
+    case CODE_SPACE:
+      return Heap::code_space();
+    case MAP_SPACE:
+      return Heap::map_space();
+    default:
+      return NULL;
+  }
+}
+
+
+
+OldSpace* OldSpaces::next() {
+  switch (counter_++) {
+    case OLD_POINTER_SPACE:
+      return Heap::old_pointer_space();
+    case OLD_DATA_SPACE:
+      return Heap::old_data_space();
+    case CODE_SPACE:
+      return Heap::code_space();
+    default:
+      return NULL;
+  }
+}
+
+
 SpaceIterator::SpaceIterator() : current_space_(FIRST_SPACE), iterator_(NULL) {
 }
 
@@ -2618,8 +2743,11 @@
     case NEW_SPACE:
       iterator_ = new SemiSpaceIterator(Heap::new_space());
       break;
-    case OLD_SPACE:
-      iterator_ = new HeapObjectIterator(Heap::old_space());
+    case OLD_POINTER_SPACE:
+      iterator_ = new HeapObjectIterator(Heap::old_pointer_space());
+      break;
+    case OLD_DATA_SPACE:
+      iterator_ = new HeapObjectIterator(Heap::old_data_space());
       break;
     case CODE_SPACE:
       iterator_ = new HeapObjectIterator(Heap::code_space());
diff --git a/src/heap.h b/src/heap.h
index a40780c..2fdcea2 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -122,7 +122,9 @@
   V(Code, c_entry_debug_break_code)                     \
   V(FixedArray, number_string_cache)                    \
   V(FixedArray, single_character_string_cache)          \
-  V(FixedArray, natives_source_cache)
+  V(FixedArray, natives_source_cache)                   \
+  V(Object, eval_cache_global)                          \
+  V(Object, eval_cache_non_global)
 
 #define ROOT_LIST(V)                                  \
   STRONG_ROOT_LIST(V)                                 \
@@ -247,7 +249,8 @@
   static Address NewSpaceTop() { return new_space_->top(); }
 
   static NewSpace* new_space() { return new_space_; }
-  static OldSpace* old_space() { return old_space_; }
+  static OldSpace* old_pointer_space() { return old_pointer_space_; }
+  static OldSpace* old_data_space() { return old_data_space_; }
   static OldSpace* code_space() { return code_space_; }
   static MapSpace* map_space() { return map_space_; }
   static LargeObjectSpace* lo_space() { return lo_space_; }
@@ -500,18 +503,13 @@
   static Object* AllocateExternalStringFromTwoByte(
       ExternalTwoByteString::Resource* resource);
 
-  // Allocates an uninitialized object.
+  // Allocates an uninitialized object.  The memory is non-executable if the
+  // hardware and OS allow.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
   // failed.
   // Please note this function does not perform a garbage collection.
-  static inline Object* AllocateRaw(int size_in_bytes, AllocationSpace space);
-
-
-  // Allocate an unitialized object during deserialization.  Performs linear
-  // allocation (ie, guaranteed no free list allocation) and assumes the
-  // spaces are all preexpanded so allocation should not fail.
-  static inline Object* AllocateForDeserialization(int size_in_bytes,
-                                                   AllocationSpace space);
+  static inline Object* AllocateRaw(int size_in_bytes,
+                                    AllocationSpace space);
 
   // Makes a new native code object
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -533,6 +531,28 @@
   }
   static Object* LookupSymbol(String* str);
 
+  // EvalCache caches function boilerplates for compiled scripts
+  // from 'eval' function.
+  // Source string is used as the key, and compiled function
+  // boilerplate as value. Because the same source has different
+  // compiled code in global or local context, we use separate
+  // caches for global and local contexts.
+  // Caches are cleared before mark-compact/mark-sweep GC's.
+
+  // Finds the function boilerplate of a source string.
+  // It returns a JSFunction object if found in the cache.
+  // The first parameter specifies whether the code is
+  // compiled in a global context.
+  static Object* LookupEvalCache(bool is_global_context, String* src);
+
+  // Put a source string and its compiled function boilerplate
+  // in the eval cache.  The cache may expand, and returns failure
+  // if it cannot expand the cache, otherwise the value is returned.
+  // The first parameter specifies whether the boilerplate is
+  // compiled in a global context.
+  static Object* PutInEvalCache(bool is_global_context,
+                                String* src, JSFunction* value);
+
   // Compute the matching symbol map for a string if possible.
   // NULL is returned if string is in new space or not flattened.
   static Map* SymbolMapForString(String* str);
@@ -551,6 +571,9 @@
   // Returns whether required_space bytes are available after the collection.
   static bool CollectGarbage(int required_space, AllocationSpace space);
 
+  // Performs a full garbage collection.
+  static void CollectAllGarbage();
+
   // Utility to invoke the scavenger. This is needed in test code to
   // ensure correct callback for weak global handles.
   static void PerformScavenge();
@@ -609,7 +632,7 @@
   static bool InSpace(HeapObject* value, AllocationSpace space);
 
   // Finds out which space an object should get promoted to based on its type.
-  static inline AllocationSpace TargetSpace(HeapObject* object);
+  static inline OldSpace* TargetSpace(HeapObject* object);
 
   // Sets the stub_cache_ (only used when expanding the dictionary).
   static void set_code_stubs(Dictionary* value) { code_stubs_ = value; }
@@ -726,7 +749,8 @@
   static const int kMaxMapSpaceSize = 8*MB;
 
   static NewSpace* new_space_;
-  static OldSpace* old_space_;
+  static OldSpace* old_pointer_space_;
+  static OldSpace* old_data_space_;
   static OldSpace* code_space_;
   static MapSpace* map_space_;
   static LargeObjectSpace* lo_space_;
@@ -801,11 +825,10 @@
                                        bool new_object,
                                        PretenureFlag pretenure = NOT_TENURED);
 
-  // Allocate an uninitialized object in map space.  The behavior is
-  // identical to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that
-  // (a) it doesn't have to test the allocation space argument and (b) can
-  // reduce code size (since both AllocateRaw and AllocateRawMap are
-  // inlined).
+  // Allocate an uninitialized object in map space.  The behavior is identical
+  // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
+  // have to test the allocation space argument and (b) can reduce code size
+  // (since both AllocateRaw and AllocateRawMap are inlined).
   static inline Object* AllocateRawMap(int size_in_bytes);
 
 
@@ -865,6 +888,7 @@
   static void RebuildRSets(LargeObjectSpace* space);
 
   static const int kInitialSymbolTableSize = 2048;
+  static const int kInitialEvalCacheSize = 64;
 
   friend class Factory;
   friend class DisallowAllocationFailure;
@@ -913,9 +937,43 @@
 
 
 // Space iterator for iterating over all spaces of the heap.
+// Returns each space in turn, and null when it is done.
+class AllSpaces BASE_EMBEDDED {
+ public:
+  Space* next();
+  AllSpaces() { counter_ = FIRST_SPACE; }
+ private:
+  int counter_;
+};
+
+
+// Space iterator for iterating over all old spaces of the heap: Old pointer
+// space, old data space and code space.
+// Returns each space in turn, and null when it is done.
+class OldSpaces BASE_EMBEDDED {
+ public:
+  OldSpace* next();
+  OldSpaces() { counter_ = OLD_POINTER_SPACE; }
+ private:
+  int counter_;
+};
+
+
+// Space iterator for iterating over all the paged spaces of the heap:
+// Map space, old pointer space, old data space and code space.
+// Returns each space in turn, and null when it is done.
+class PagedSpaces BASE_EMBEDDED {
+ public:
+  PagedSpace* next();
+  PagedSpaces() { counter_ = OLD_POINTER_SPACE; }
+ private:
+  int counter_;
+};
+
+
+// Space iterator for iterating over all spaces of the heap.
 // For each space an object iterator is provided. The deallocation of the
 // returned object iterators is handled by the space iterator.
-
 class SpaceIterator : public Malloced {
  public:
   SpaceIterator();
@@ -1132,7 +1190,6 @@
   int previous_marked_count_;
 };
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_HEAP_H_
diff --git a/src/ic-arm.cc b/src/ic-arm.cc
index 869ffcb..61b516e 100644
--- a/src/ic-arm.cc
+++ b/src/ic-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/ic-ia32.cc b/src/ic-ia32.cc
index 56dde61..6b0f2c4 100644
--- a/src/ic-ia32.cc
+++ b/src/ic-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/ic-inl.h b/src/ic-inl.h
index 32e8df3..201048a 100644
--- a/src/ic-inl.h
+++ b/src/ic-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/ic.cc b/src/ic.cc
index 2074a76..baac44b 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -250,6 +250,26 @@
 }
 
 
+Object* CallIC::TryCallAsFunction(Object* object) {
+  HandleScope scope;
+  Handle<Object> target(object);
+  Handle<Object> delegate = Execution::GetFunctionDelegate(target);
+
+  if (delegate->IsJSFunction()) {
+    // Patch the receiver and use the delegate as the function to
+    // invoke. This is used for invoking objects as if they were
+    // functions.
+    const int argc = this->target()->arguments_count();
+    StackFrameLocator locator;
+    JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
+    int index = frame->ComputeExpressionsCount() - (argc + 1);
+    frame->SetExpression(index, *target);
+  }
+
+  return *delegate;
+}
+
+
 Object* CallIC::LoadFunction(State state,
                              Handle<Object> object,
                              Handle<String> name) {
@@ -259,12 +279,26 @@
     return TypeError("non_object_property_call", object, name);
   }
 
+  Object* result = Heap::the_hole_value();
+
+  // Check if the name is trivially convertible to an index and get
+  // the element if so.
+  uint32_t index;
+  if (name->AsArrayIndex(&index)) {
+    result = object->GetElement(index);
+    if (result->IsJSFunction()) return result;
+
+    // Try to find a suitable function delegate for the object at hand.
+    result = TryCallAsFunction(result);
+    if (result->IsJSFunction()) return result;
+
+    // Otherwise, it will fail in the lookup step.
+  }
+
   // Lookup the property in the object.
   LookupResult lookup;
   object->Lookup(*name, &lookup);
 
-  Object* result = Heap::the_hole_value();
-
   if (!lookup.IsValid()) {
     // If the object does not have the requested property, check which
     // exception we need to throw.
@@ -328,23 +362,9 @@
   }
 
   // Try to find a suitable function delegate for the object at hand.
-  HandleScope scope;
-  Handle<Object> target(result);
-  Handle<Object> delegate = Execution::GetFunctionDelegate(target);
-
-  if (delegate->IsJSFunction()) {
-    // Patch the receiver and use the delegate as the function to
-    // invoke. This is used for invoking objects as if they were
-    // functions.
-    const int argc = this->target()->arguments_count();
-    StackFrameLocator locator;
-    JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
-    int index = frame->ComputeExpressionsCount() - (argc + 1);
-    frame->SetExpression(index, *target);
-    return *delegate;
-  } else {
-    return TypeError("property_not_function", object, name);
-  }
+  result = TryCallAsFunction(result);
+  return result->IsJSFunction() ?
+      result : TypeError("property_not_function", object, name);
 }
 
 
diff --git a/src/ic.h b/src/ic.h
index b474e9f..fa45c7b 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -183,6 +183,11 @@
                     Handle<Object> object,
                     Handle<String> name);
 
+  // Returns a JSFunction if the object can be called as a function,
+  // and patches the stack to be ready for the call.
+  // Otherwise, it returns the undefined value.
+  Object* TryCallAsFunction(Object* object);
+
   static void Clear(Address address, Code* target);
   friend class IC;
 };
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 0c22a79..51bfd37 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/jsregexp.h b/src/jsregexp.h
index c6316f9..32835bf 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/list-inl.h b/src/list-inl.h
index 1a133f8..a185af3 100644
--- a/src/list-inl.h
+++ b/src/list-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/list.h b/src/list.h
index 50b66f8..34b18fb 100644
--- a/src/list.h
+++ b/src/list.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/log.cc b/src/log.cc
index a0d67b9..dbefc04 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/log.h b/src/log.h
index ec1c684..1c9d0b6 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc
index 21fcea4..9817e42 100644
--- a/src/macro-assembler-arm.cc
+++ b/src/macro-assembler-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macro-assembler-arm.h b/src/macro-assembler-arm.h
index 00cf621..4837f00 100644
--- a/src/macro-assembler-arm.h
+++ b/src/macro-assembler-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macro-assembler-ia32.cc b/src/macro-assembler-ia32.cc
index c56d334..50b43c9 100644
--- a/src/macro-assembler-ia32.cc
+++ b/src/macro-assembler-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macro-assembler-ia32.h b/src/macro-assembler-ia32.h
index b3aba9a..35fe73f 100644
--- a/src/macro-assembler-ia32.h
+++ b/src/macro-assembler-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macro-assembler.h b/src/macro-assembler.h
index 3f4b63a..f289346 100644
--- a/src/macro-assembler.h
+++ b/src/macro-assembler.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/macros.py b/src/macros.py
index 32f714c..a33df25 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -1,4 +1,4 @@
-# Copyright 2006-2008 Google Inc. All Rights Reserved.
+# Copyright 2006-2008 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index ab2bc5a..e155e77 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -73,8 +73,9 @@
 // collection.
 int MarkCompactCollector::live_bytes_ = 0;
 int MarkCompactCollector::live_young_objects_ = 0;
-int MarkCompactCollector::live_old_objects_ = 0;
-int MarkCompactCollector::live_immutable_objects_ = 0;
+int MarkCompactCollector::live_old_data_objects_ = 0;
+int MarkCompactCollector::live_old_pointer_objects_ = 0;
+int MarkCompactCollector::live_code_objects_ = 0;
 int MarkCompactCollector::live_map_objects_ = 0;
 int MarkCompactCollector::live_lo_objects_ = 0;
 #endif
@@ -131,14 +132,16 @@
   // because objects do not get promoted out of new space on non-compacting
   // GCs.
   if (!compacting_collection_) {
-    int old_gen_recoverable = Heap::old_space()->Waste()
-                            + Heap::old_space()->AvailableFree()
-                            + Heap::code_space()->Waste()
-                            + Heap::code_space()->AvailableFree();
-    int old_gen_used = old_gen_recoverable
-                     + Heap::old_space()->Size()
-                     + Heap::code_space()->Size();
-    int old_gen_fragmentation = (old_gen_recoverable * 100) / old_gen_used;
+    int old_gen_recoverable = 0;
+    int old_gen_used = 0;
+
+    OldSpaces spaces;
+    while (OldSpace* space = spaces.next()) {
+      old_gen_recoverable += space->Waste() + space->AvailableFree();
+      old_gen_used += space->Size();
+    }
+    int old_gen_fragmentation =
+      static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
     if (old_gen_fragmentation > kFragmentationLimit) {
       compacting_collection_ = true;
     }
@@ -154,17 +157,19 @@
   }
 #endif
 
-  Heap::map_space()->PrepareForMarkCompact(compacting_collection_);
-  Heap::old_space()->PrepareForMarkCompact(compacting_collection_);
-  Heap::code_space()->PrepareForMarkCompact(compacting_collection_);
+  PagedSpaces spaces;
+  while (PagedSpace* space = spaces.next()) {
+    space->PrepareForMarkCompact(compacting_collection_);
+  }
 
   Counters::global_objects.Set(0);
 
 #ifdef DEBUG
   live_bytes_ = 0;
   live_young_objects_ = 0;
-  live_old_objects_ = 0;
-  live_immutable_objects_ = 0;
+  live_old_pointer_objects_ = 0;
+  live_old_data_objects_ = 0;
+  live_code_objects_ = 0;
   live_map_objects_ = 0;
   live_lo_objects_ = 0;
 #endif
@@ -216,15 +221,15 @@
 
 
 inline HeapObject* ShortCircuitConsString(Object** p) {
-  // Optimization: If the heap object pointed to by p is a cons string whose
-  // right substring is Heap::empty_string, update it in place to its left
-  // substring.  Return the updated value.
+  // Optimization: If the heap object pointed to by p is a non-symbol
+  // cons string whose right substring is Heap::empty_string, update
+  // it in place to its left substring.  Return the updated value.
   //
   // Here we assume that if we change *p, we replace it with a heap object
   // (ie, the left substring of a cons string is always a heap object).
   //
   // The check performed is:
-  //   object->IsConsString() &&
+  //   object->IsConsString() && !object->IsSymbol() &&
   //   (ConsString::cast(object)->second() == Heap::empty_string())
   // except the maps for the object and its possible substrings might be
   // marked.
@@ -232,7 +237,9 @@
   MapWord map_word = object->map_word();
   map_word.ClearMark();
   InstanceType type = map_word.ToMap()->instance_type();
-  if (type >= FIRST_NONSTRING_TYPE) return object;
+  if (type >= FIRST_NONSTRING_TYPE || (type & kIsSymbolMask) != 0) {
+    return object;
+  }
 
   StringRepresentationTag rep =
       static_cast<StringRepresentationTag>(type & kStringRepresentationMask);
@@ -575,8 +582,13 @@
   ScanOverflowedObjects(&new_it);
   if (marking_stack.is_full()) return;
 
-  HeapObjectIterator old_it(Heap::old_space(), &OverflowObjectSize);
-  ScanOverflowedObjects(&old_it);
+  HeapObjectIterator old_pointer_it(Heap::old_pointer_space(),
+                                    &OverflowObjectSize);
+  ScanOverflowedObjects(&old_pointer_it);
+  if (marking_stack.is_full()) return;
+
+  HeapObjectIterator old_data_it(Heap::old_data_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&old_data_it);
   if (marking_stack.is_full()) return;
 
   HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize);
@@ -683,10 +695,12 @@
   } else if (Heap::map_space()->Contains(obj)) {
     ASSERT(obj->IsMap());
     live_map_objects_++;
-  } else if (Heap::old_space()->Contains(obj)) {
-    live_old_objects_++;
+  } else if (Heap::old_pointer_space()->Contains(obj)) {
+    live_old_pointer_objects_++;
+  } else if (Heap::old_data_space()->Contains(obj)) {
+    live_old_data_objects_++;
   } else if (Heap::code_space()->Contains(obj)) {
-    live_immutable_objects_++;
+    live_code_objects_++;
   } else if (Heap::lo_space()->Contains(obj)) {
     live_lo_objects_++;
   } else {
@@ -704,7 +718,8 @@
 
 void MarkCompactCollector::VerifyHeapAfterMarkingPhase() {
   Heap::new_space()->Verify();
-  Heap::old_space()->Verify();
+  Heap::old_pointer_space()->Verify();
+  Heap::old_data_space()->Verify();
   Heap::code_space()->Verify();
   Heap::map_space()->Verify();
 
@@ -721,11 +736,15 @@
   SemiSpaceIterator new_it(Heap::new_space(), &CountMarkedCallback);
   CHECK_LIVE_OBJECTS(new_it, live_young_objects_);
 
-  HeapObjectIterator old_it(Heap::old_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(old_it, live_old_objects_);
+  HeapObjectIterator old_pointer_it(Heap::old_pointer_space(),
+                                    &CountMarkedCallback);
+  CHECK_LIVE_OBJECTS(old_pointer_it, live_old_pointer_objects_);
+
+  HeapObjectIterator old_data_it(Heap::old_data_space(), &CountMarkedCallback);
+  CHECK_LIVE_OBJECTS(old_data_it, live_old_data_objects_);
 
   HeapObjectIterator code_it(Heap::code_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(code_it, live_immutable_objects_);
+  CHECK_LIVE_OBJECTS(code_it, live_code_objects_);
 
   HeapObjectIterator map_it(Heap::map_space(), &CountMarkedCallback);
   CHECK_LIVE_OBJECTS(map_it, live_map_objects_);
@@ -807,14 +826,10 @@
 // Try to promote all objects in new space.  Heap numbers and sequential
 // strings are promoted to the code space, all others to the old space.
 inline Object* MCAllocateFromNewSpace(HeapObject* object, int object_size) {
-  AllocationSpace target_space = Heap::TargetSpace(object);
-  Object* forwarded;
-  if (target_space == OLD_SPACE) {
-    forwarded = Heap::old_space()->MCAllocateRaw(object_size);
-  } else {
-    ASSERT(target_space == CODE_SPACE);
-    forwarded = Heap::code_space()->MCAllocateRaw(object_size);
-  }
+  OldSpace* target_space = Heap::TargetSpace(object);
+  ASSERT(target_space == Heap::old_pointer_space() ||
+         target_space == Heap::old_data_space());
+  Object* forwarded = target_space->MCAllocateRaw(object_size);
 
   if (forwarded->IsFailure()) {
     forwarded = Heap::new_space()->MCAllocateRaw(object_size);
@@ -824,8 +839,14 @@
 
 
 // Allocation functions for the paged spaces call the space's MCAllocateRaw.
-inline Object* MCAllocateFromOldSpace(HeapObject* object, int object_size) {
-  return Heap::old_space()->MCAllocateRaw(object_size);
+inline Object* MCAllocateFromOldPointerSpace(HeapObject* object,
+                                             int object_size) {
+  return Heap::old_pointer_space()->MCAllocateRaw(object_size);
+}
+
+
+inline Object* MCAllocateFromOldDataSpace(HeapObject* object, int object_size) {
+  return Heap::old_data_space()->MCAllocateRaw(object_size);
 }
 
 
@@ -1058,10 +1079,16 @@
 }
 
 
-void MarkCompactCollector::DeallocateOldBlock(Address start,
-                                              int size_in_bytes) {
+void MarkCompactCollector::DeallocateOldPointerBlock(Address start,
+                                                     int size_in_bytes) {
   Heap::ClearRSetRange(start, size_in_bytes);
-  Heap::old_space()->Free(start, size_in_bytes);
+  Heap::old_pointer_space()->Free(start, size_in_bytes);
+}
+
+
+void MarkCompactCollector::DeallocateOldDataBlock(Address start,
+                                                  int size_in_bytes) {
+  Heap::old_data_space()->Free(start, size_in_bytes);
 }
 
 
@@ -1093,9 +1120,13 @@
   Heap::new_space()->MCResetRelocationInfo();
 
   // Compute the forwarding pointers in each space.
-  EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldSpace,
+  EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace,
                                         IgnoreNonLiveObject>(
-      Heap::old_space());
+      Heap::old_pointer_space());
+
+  EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace,
+                                        IgnoreNonLiveObject>(
+      Heap::old_data_space());
 
   EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace,
                                         LogNonLiveCodeObject>(
@@ -1115,7 +1146,8 @@
   // Write relocation info to the top page, so we can use it later.  This is
   // done after promoting objects from the new space so we get the correct
   // allocation top.
-  Heap::old_space()->MCWriteRelocationInfoToPage();
+  Heap::old_pointer_space()->MCWriteRelocationInfoToPage();
+  Heap::old_data_space()->MCWriteRelocationInfoToPage();
   Heap::code_space()->MCWriteRelocationInfoToPage();
   Heap::map_space()->MCWriteRelocationInfoToPage();
 }
@@ -1129,7 +1161,8 @@
   // the map space last because freeing non-live maps overwrites them and
   // the other spaces rely on possibly non-live maps to get the sizes for
   // non-live objects.
-  SweepSpace(Heap::old_space(), &DeallocateOldBlock);
+  SweepSpace(Heap::old_pointer_space(), &DeallocateOldPointerBlock);
+  SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
   SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
   SweepSpace(Heap::new_space());
   SweepSpace(Heap::map_space(), &DeallocateMapBlock);
@@ -1193,19 +1226,16 @@
 
 
 void MarkCompactCollector::VerifyHeapAfterEncodingForwardingAddresses() {
-  Heap::new_space()->Verify();
-  Heap::old_space()->Verify();
-  Heap::code_space()->Verify();
-  Heap::map_space()->Verify();
+  AllSpaces spaces;
+  while (Space* space = spaces.next()) space->Verify();
 
   ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
   int live_maps = IterateLiveObjects(Heap::map_space(), &VerifyMapObject);
   ASSERT(live_maps == live_map_objects_);
 
   // Verify page headers in paged spaces.
-  VerifyPageHeaders(Heap::old_space());
-  VerifyPageHeaders(Heap::code_space());
-  VerifyPageHeaders(Heap::map_space());
+  PagedSpaces paged_spaces;
+  while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
 }
 
 
@@ -1264,7 +1294,8 @@
       new_addr = Memory::Address_at(f_addr);
 
 #ifdef DEBUG
-      ASSERT(Heap::old_space()->Contains(new_addr) ||
+      ASSERT(Heap::old_pointer_space()->Contains(new_addr) ||
+             Heap::old_data_space()->Contains(new_addr) ||
              Heap::code_space()->Contains(new_addr) ||
              Heap::new_space()->FromSpaceContains(new_addr));
 
@@ -1279,19 +1310,24 @@
       return;
 
     } else {
-      ASSERT(Heap::old_space()->Contains(obj) ||
+      ASSERT(Heap::old_pointer_space()->Contains(obj) ||
+             Heap::old_data_space()->Contains(obj) ||
              Heap::code_space()->Contains(obj) ||
              Heap::map_space()->Contains(obj));
 
       new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj);
-      ASSERT(Heap::old_space()->Contains(new_addr) ||
+      ASSERT(Heap::old_pointer_space()->Contains(new_addr) ||
+             Heap::old_data_space()->Contains(new_addr) ||
              Heap::code_space()->Contains(new_addr) ||
              Heap::map_space()->Contains(new_addr));
 
 #ifdef DEBUG
-      if (Heap::old_space()->Contains(obj)) {
-        ASSERT(Heap::old_space()->MCSpaceOffsetForAddress(new_addr) <=
-               Heap::old_space()->MCSpaceOffsetForAddress(old_addr));
+      if (Heap::old_pointer_space()->Contains(obj)) {
+        ASSERT(Heap::old_pointer_space()->MCSpaceOffsetForAddress(new_addr) <=
+               Heap::old_pointer_space()->MCSpaceOffsetForAddress(old_addr));
+      } else if (Heap::old_data_space()->Contains(obj)) {
+        ASSERT(Heap::old_data_space()->MCSpaceOffsetForAddress(new_addr) <=
+               Heap::old_data_space()->MCSpaceOffsetForAddress(old_addr));
       } else if (Heap::code_space()->Contains(obj)) {
         ASSERT(Heap::code_space()->MCSpaceOffsetForAddress(new_addr) <=
                Heap::code_space()->MCSpaceOffsetForAddress(old_addr));
@@ -1325,10 +1361,12 @@
 
   int live_maps = IterateLiveObjects(Heap::map_space(),
                                      &UpdatePointersInOldObject);
-  int live_olds = IterateLiveObjects(Heap::old_space(),
-                                     &UpdatePointersInOldObject);
-  int live_immutables = IterateLiveObjects(Heap::code_space(),
-                                           &UpdatePointersInOldObject);
+  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
+                                             &UpdatePointersInOldObject);
+  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
+                                          &UpdatePointersInOldObject);
+  int live_codes = IterateLiveObjects(Heap::code_space(),
+                                      &UpdatePointersInOldObject);
   int live_news = IterateLiveObjects(Heap::new_space(),
                                      &UpdatePointersInNewObject);
 
@@ -1337,14 +1375,16 @@
   while (it.has_next()) UpdatePointersInNewObject(it.next());
 
   USE(live_maps);
-  USE(live_olds);
-  USE(live_immutables);
+  USE(live_pointer_olds);
+  USE(live_data_olds);
+  USE(live_codes);
   USE(live_news);
 
 #ifdef DEBUG
   ASSERT(live_maps == live_map_objects_);
-  ASSERT(live_olds == live_old_objects_);
-  ASSERT(live_immutables == live_immutable_objects_);
+  ASSERT(live_data_olds == live_old_data_objects_);
+  ASSERT(live_pointer_olds == live_old_pointer_objects_);
+  ASSERT(live_codes == live_code_objects_);
   ASSERT(live_news == live_young_objects_);
 
   if (FLAG_verify_global_gc) VerifyHeapAfterUpdatingPointers();
@@ -1457,16 +1497,10 @@
 void MarkCompactCollector::VerifyHeapAfterUpdatingPointers() {
   ASSERT(state_ == UPDATE_POINTERS);
 
-  Heap::new_space()->Verify();
-  Heap::old_space()->Verify();
-  Heap::code_space()->Verify();
-  Heap::map_space()->Verify();
-
-  // We don't have object size info after updating pointers, not much we can
-  // do here.
-  VerifyPageHeaders(Heap::old_space());
-  VerifyPageHeaders(Heap::code_space());
-  VerifyPageHeaders(Heap::map_space());
+  AllSpaces spaces;
+  while (Space* space = spaces.next()) space->Verify();
+  PagedSpaces paged_spaces;
+  while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
 }
 #endif
 
@@ -1482,19 +1516,23 @@
   // Relocates objects, always relocate map objects first. Relocating
   // objects in other space relies on map objects to get object size.
   int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject);
-  int live_olds = IterateLiveObjects(Heap::old_space(), &RelocateOldObject);
-  int live_immutables =
-      IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
+  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
+                                             &RelocateOldPointerObject);
+  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
+                                          &RelocateOldDataObject);
+  int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
   int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);
 
   USE(live_maps);
-  USE(live_olds);
-  USE(live_immutables);
+  USE(live_data_olds);
+  USE(live_pointer_olds);
+  USE(live_codes);
   USE(live_news);
 #ifdef DEBUG
   ASSERT(live_maps == live_map_objects_);
-  ASSERT(live_olds == live_old_objects_);
-  ASSERT(live_immutables == live_immutable_objects_);
+  ASSERT(live_data_olds == live_old_data_objects_);
+  ASSERT(live_pointer_olds == live_old_pointer_objects_);
+  ASSERT(live_codes == live_code_objects_);
   ASSERT(live_news == live_young_objects_);
 #endif
 
@@ -1516,9 +1554,8 @@
   // page-by-page basis after committing the m-c forwarding pointer.
   Page::set_rset_state(Page::IN_USE);
 #endif
-  Heap::map_space()->MCCommitRelocationInfo();
-  Heap::old_space()->MCCommitRelocationInfo();
-  Heap::code_space()->MCCommitRelocationInfo();
+  PagedSpaces spaces;
+  while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo();
 
 #ifdef DEBUG
   if (FLAG_verify_global_gc) VerifyHeapAfterRelocatingObjects();
@@ -1563,15 +1600,10 @@
 }
 
 
-int MarkCompactCollector::RelocateOldObject(HeapObject* obj) {
-  // decode map pointer (forwarded address)
-  MapWord encoding = obj->map_word();
-  Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
-  ASSERT(Heap::map_space()->Contains(map_addr));
-
-  // Get forwarding address before resetting map pointer
-  Address new_addr = GetForwardingAddressInOldSpace(obj);
-
+static inline int RelocateOldObject(HeapObject* obj,
+                                    OldSpace* space,
+                                    Address new_addr,
+                                    Address map_addr) {
   // recover map pointer
   obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)));
 
@@ -1580,35 +1612,55 @@
   int obj_size = obj->Size();
   ASSERT_OBJECT_SIZE(obj_size);
 
+  ASSERT(space->MCSpaceOffsetForAddress(new_addr) <=
+         space->MCSpaceOffsetForAddress(obj->address()));
+
+  space->MCAdjustRelocationEnd(new_addr, obj_size);
+
+#ifdef DEBUG
+  if (FLAG_gc_verbose) {
+    PrintF("relocate %p -> %p\n", obj->address(), new_addr);
+  }
+#endif
+
+  return obj_size;
+}
+
+
+int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj,
+                                                   OldSpace* space) {
+  // decode map pointer (forwarded address)
+  MapWord encoding = obj->map_word();
+  Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
+  ASSERT(Heap::map_space()->Contains(map_addr));
+
+  // Get forwarding address before resetting map pointer
+  Address new_addr = GetForwardingAddressInOldSpace(obj);
+
+  int obj_size = RelocateOldObject(obj, space, new_addr, map_addr);
+
   Address old_addr = obj->address();
 
-  ASSERT(Heap::old_space()->MCSpaceOffsetForAddress(new_addr) <=
-         Heap::old_space()->MCSpaceOffsetForAddress(old_addr));
-
-  Heap::old_space()->MCAdjustRelocationEnd(new_addr, obj_size);
-
   if (new_addr != old_addr) {
     memmove(new_addr, old_addr, obj_size);  // copy contents
   }
 
-  HeapObject* copied_to = HeapObject::FromAddress(new_addr);
-  if (copied_to->IsCode()) {
-    // may also update inline cache target.
-    Code::cast(copied_to)->Relocate(new_addr - old_addr);
-    // Notify the logger that compile code has moved.
-    LOG(CodeMoveEvent(old_addr, new_addr));
-  }
-
-#ifdef DEBUG
-  if (FLAG_gc_verbose) {
-    PrintF("relocate %p -> %p\n", old_addr, new_addr);
-  }
-#endif
+  ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
 
   return obj_size;
 }
 
 
+int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) {
+  return RelocateOldNonCodeObject(obj, Heap::old_pointer_space());
+}
+
+
+int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) {
+  return RelocateOldNonCodeObject(obj, Heap::old_data_space());
+}
+
+
 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
   // decode map pointer (forwarded address)
   MapWord encoding = obj->map_word();
@@ -1618,20 +1670,7 @@
   // Get forwarding address before resetting map pointer
   Address new_addr = GetForwardingAddressInOldSpace(obj);
 
-  // recover map pointer
-  obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)));
-
-  // This is a non-map object, it relies on the assumption that the Map space
-  // is compacted before the other spaces (see RelocateObjects).
-  int obj_size = obj->Size();
-  ASSERT_OBJECT_SIZE(obj_size);
-
-  Address old_addr = obj->address();
-
-  ASSERT(Heap::code_space()->MCSpaceOffsetForAddress(new_addr) <=
-         Heap::code_space()->MCSpaceOffsetForAddress(old_addr));
-
-  Heap::code_space()->MCAdjustRelocationEnd(new_addr, obj_size);
+  int obj_size = RelocateOldObject(obj, Heap::code_space(), new_addr, map_addr);
 
   // convert inline cache target to address using old address
   if (obj->IsCode()) {
@@ -1639,6 +1678,8 @@
     Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
   }
 
+  Address old_addr = obj->address();
+
   if (new_addr != old_addr) {
     memmove(new_addr, old_addr, obj_size);  // copy contents
   }
@@ -1651,12 +1692,6 @@
     LOG(CodeMoveEvent(old_addr, new_addr));
   }
 
-#ifdef DEBUG
-  if (FLAG_gc_verbose) {
-    PrintF("relocate %p -> %p\n", old_addr, new_addr);
-  }
-#endif
-
   return obj_size;
 }
 
@@ -1687,13 +1722,10 @@
     ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <=
            Heap::new_space()->ToSpaceOffsetForAddress(old_addr));
   } else {
-    AllocationSpace target_space = Heap::TargetSpace(obj);
-    if (target_space == OLD_SPACE) {
-      Heap::old_space()->MCAdjustRelocationEnd(new_addr, obj_size);
-    } else {
-      ASSERT(target_space == CODE_SPACE);
-      Heap::code_space()->MCAdjustRelocationEnd(new_addr, obj_size);
-    }
+    OldSpace* target_space = Heap::TargetSpace(obj);
+    ASSERT(target_space == Heap::old_pointer_space() ||
+           target_space == Heap::old_data_space());
+    target_space->MCAdjustRelocationEnd(new_addr, obj_size);
   }
 
   // New and old addresses cannot overlap.
@@ -1721,26 +1753,14 @@
   ASSERT(state_ == RELOCATE_OBJECTS);
 
   Heap::new_space()->Verify();
-  Heap::old_space()->Verify();
-  Heap::code_space()->Verify();
-  Heap::map_space()->Verify();
-
-  PageIterator old_it(Heap::old_space(), PageIterator::PAGES_IN_USE);
-  while (old_it.has_next()) {
-    Page* p = old_it.next();
-    ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
-  }
-
-  PageIterator code_it(Heap::code_space(), PageIterator::PAGES_IN_USE);
-  while (code_it.has_next()) {
-    Page* p = code_it.next();
-    ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
-  }
-
-  PageIterator map_it(Heap::map_space(), PageIterator::PAGES_IN_USE);
-  while (map_it.has_next()) {
-    Page* p = map_it.next();
-    ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
+  PagedSpaces spaces;
+  while (PagedSpace* space = spaces.next()) {
+    space->Verify();
+    PageIterator it(space, PageIterator::PAGES_IN_USE);
+    while (it.has_next()) {
+      Page* p = it.next();
+      ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
+    }
   }
 }
 #endif
diff --git a/src/mark-compact.h b/src/mark-compact.h
index 7fe0fb5..f3b4e2a 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -241,7 +241,8 @@
 
   // Callback functions for deallocating non-live blocks in the old
   // generation.
-  static void DeallocateOldBlock(Address start, int size_in_bytes);
+  static void DeallocateOldPointerBlock(Address start, int size_in_bytes);
+  static void DeallocateOldDataBlock(Address start, int size_in_bytes);
   static void DeallocateCodeBlock(Address start, int size_in_bytes);
   static void DeallocateMapBlock(Address start, int size_in_bytes);
 
@@ -295,9 +296,13 @@
   static int RelocateMapObject(HeapObject* obj);
 
   // Relocates an old object.
-  static int RelocateOldObject(HeapObject* obj);
+  static int RelocateOldPointerObject(HeapObject* obj);
+  static int RelocateOldDataObject(HeapObject* obj);
 
-  // Relocates an immutable object in the code space.
+  // Helper function.
+  static inline int RelocateOldNonCodeObject(HeapObject* obj, OldSpace* space);
+
+  // Relocates an object in the code space.
   static int RelocateCodeObject(HeapObject* obj);
 
   // Copy a new object.
@@ -322,11 +327,14 @@
   // Number of live objects in Heap::to_space_.
   static int live_young_objects_;
 
-  // Number of live objects in Heap::old_space_.
-  static int live_old_objects_;
+  // Number of live objects in Heap::old_pointer_space_.
+  static int live_old_pointer_objects_;
+
+  // Number of live objects in Heap::old_data_space_.
+  static int live_old_data_objects_;
 
   // Number of live objects in Heap::code_space_.
-  static int live_immutable_objects_;
+  static int live_code_objects_;
 
   // Number of live objects in Heap::map_space_.
   static int live_map_objects_;
diff --git a/src/math.js b/src/math.js
index 12bf70d..cb5cfb9 100644
--- a/src/math.js
+++ b/src/math.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/memory.h b/src/memory.h
index 61e13fb..2397bc6 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/messages.cc b/src/messages.cc
index a50bf61..6e8a371 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -1,5 +1,5 @@
 
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -60,8 +60,11 @@
 }
 
 
-void MessageHandler::ReportMessage(const char* type, MessageLocation* loc,
-                                   Vector< Handle<Object> > args) {
+Handle<Object> MessageHandler::MakeMessageObject(
+    const char* type,
+    MessageLocation* loc,
+    Vector< Handle<Object> > args,
+    Handle<String> stack_trace) {
   // Build error message object
   HandleScope scope;
   Handle<Object> type_str = Factory::LookupAsciiSymbol(type);
@@ -82,12 +85,16 @@
   }
   Handle<Object> start_handle(Smi::FromInt(start));
   Handle<Object> end_handle(Smi::FromInt(end));
-  const int argc = 5;
+  Handle<Object> stack_trace_val = stack_trace.is_null()
+    ? Factory::undefined_value()
+    : Handle<Object>::cast(stack_trace);
+  const int argc = 6;
   Object** argv[argc] = { type_str.location(),
                           array.location(),
                           start_handle.location(),
                           end_handle.location(),
-                          script.location() };
+                          script.location(),
+                          stack_trace_val.location() };
 
   bool caught_exception = false;
   Handle<Object> message =
@@ -97,8 +104,13 @@
   // skip doing the callback. This usually only happens in case of
   // stack overflow exceptions being thrown by the parser when the
   // stack is almost full.
-  if (caught_exception) return;
+  if (caught_exception) return Handle<Object>();
+  return message.EscapeFrom(&scope);
+}
 
+
+void MessageHandler::ReportMessage(MessageLocation* loc,
+                                   Handle<Object> message) {
   v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
 
   v8::NeanderArray global_listeners(Factory::message_listeners());
diff --git a/src/messages.h b/src/messages.h
index 2e1dda4..1ff10aa 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -70,6 +70,7 @@
       : script_(script),
         start_pos_(start_pos),
         end_pos_(end_pos) { }
+  MessageLocation() : start_pos_(-1), end_pos_(-1) { }
 
   Handle<Script> script() const { return script_; }
   int start_pos() const { return start_pos_; }
@@ -89,10 +90,14 @@
   // Report a message (w/o JS heap allocation).
   static void ReportMessage(const char* msg);
 
+  // Returns a message object for the API to use.
+  static Handle<Object> MakeMessageObject(const char* type,
+                                          MessageLocation* loc,
+                                          Vector< Handle<Object> > args,
+                                          Handle<String> stack_trace);
+
   // Report a formatted message (needs JS allocation).
-  static void ReportMessage(const char* type,
-                            MessageLocation* loc,
-                            Vector< Handle<Object> > args);
+  static void ReportMessage(MessageLocation* loc, Handle<Object> message);
 
   static void DefaultMessageReport(const MessageLocation* loc,
                                    Handle<Object> message_obj);
diff --git a/src/messages.js b/src/messages.js
index 49b0241..d27502d 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -148,6 +148,8 @@
         args[i] = elem.slice(0,20).concat("...");
       }
     }
+  } else if (IS_UNDEFINED(args)) {
+    args = [];
   }
 
   var e = new constructor();
@@ -555,17 +557,18 @@
 };
 
 
-function ErrorMessage(type, args, startPos, endPos, script) {
+function ErrorMessage(type, args, startPos, endPos, script, stackTrace) {
   this.startPos = startPos;
   this.endPos = endPos;
   this.type = type;
   this.args = args;
   this.script = script;
+  this.stackTrace = stackTrace;
 };
 
 
-function MakeMessage(type, args, startPos, endPos, script) {
-  return new ErrorMessage(type, args, startPos, endPos, script);
+function MakeMessage(type, args, startPos, endPos, script, stackTrace) {
+  return new ErrorMessage(type, args, startPos, endPos, script, stackTrace);
 };
 
 
diff --git a/src/mirror-delay.js b/src/mirror-delay.js
index c1ffed1..5f7ab03 100644
--- a/src/mirror-delay.js
+++ b/src/mirror-delay.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -708,7 +708,7 @@
     // Skip properties which are defined through assessors.
     var property = properties[i];
     if (property.propertyType() != PropertyType.Callbacks) {
-      if (%ObjectEquals(property.value_, value.value_) == 0) {
+      if (%_ObjectEquals(property.value_, value.value_)) {
         return property;
       }
     }
@@ -728,12 +728,12 @@
 ObjectMirror.prototype.referencedBy = function(opt_max_instances) {
   // Find all objects constructed from this function.
   var result = %DebugReferencedBy(this.value_, Mirror.prototype, opt_max_instances || 0);
-    
+
   // Make mirrors for all the instances found.
   for (var i = 0; i < result.length; i++) {
     result[i] = MakeMirror(result[i]);
   }
-    
+
   return result;
 };
 
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index d0a67ce..5ee9511 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -182,8 +182,8 @@
       i::Bootstrapper::NativesSourceLookup(i);
     }
   }
-  // Get rid of unreferenced scripts.
-  i::Heap::CollectGarbage(0, i::OLD_SPACE);
+  // Get rid of unreferenced scripts with a global GC.
+  i::Heap::CollectAllGarbage();
   i::Serializer ser;
   ser.Serialize();
   char* str;
diff --git a/src/natives.h b/src/natives.h
index 2e2e507..0bb879f 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 00b086e..dd656e0 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 37919f1..e690327 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -314,6 +314,13 @@
 }
 
 
+bool Object::IsEvalCache() {
+  return IsHashTable() &&
+      (this == Heap::eval_cache_global() ||
+       this == Heap::eval_cache_non_global());
+}
+
+
 bool Object::IsPrimitive() {
   return IsOddball() || IsNumber() || IsString();
 }
@@ -1089,6 +1096,7 @@
 CAST_ACCESSOR(DescriptorArray)
 CAST_ACCESSOR(Dictionary)
 CAST_ACCESSOR(SymbolTable)
+CAST_ACCESSOR(EvalCache)
 CAST_ACCESSOR(String)
 CAST_ACCESSOR(SeqString)
 CAST_ACCESSOR(AsciiString)
diff --git a/src/objects.cc b/src/objects.cc
index 2be4ccd..3f29c71 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -931,7 +931,7 @@
   // Make the clone.
   Object* clone = (pretenure == NOT_TENURED) ?
       Heap::Allocate(map(), NEW_SPACE) :
-      Heap::Allocate(map(), OLD_SPACE);
+      Heap::Allocate(map(), OLD_POINTER_SPACE);
   if (clone->IsFailure()) return clone;
   JSObject::cast(clone)->CopyBody(this);
 
@@ -1124,8 +1124,7 @@
   if (value->IsJSFunction()) {
     JSFunction* function = JSFunction::cast(value);
 
-    Object* new_map =
-      map()->CopyDropTransitions();
+    Object* new_map = map()->CopyDropTransitions();
     if (new_map->IsFailure()) return new_map;
     set_map(Map::cast(new_map));
 
@@ -2646,7 +2645,7 @@
   int new_size = number_of_descriptors() - transitions - null_descriptors;
 
   // If key is in descriptor, we replace it in-place when filtering.
-  int index = Search(descriptor->key());
+  int index = Search(descriptor->GetKey());
   const bool inserting = (index == kNotFound);
   const bool replacing = !inserting;
   bool keep_enumeration_index = false;
@@ -2689,7 +2688,7 @@
   // and inserting or replacing a descriptor.
   DescriptorWriter w(new_descriptors);
   DescriptorReader r(this);
-  uint32_t descriptor_hash = descriptor->key()->Hash();
+  uint32_t descriptor_hash = descriptor->GetKey()->Hash();
 
   for (; !r.eos(); r.advance()) {
     if (r.GetKey()->Hash() > descriptor_hash ||
@@ -2915,6 +2914,22 @@
 }
 
 
+int String::Utf8Length() {
+  if (is_ascii()) return length();
+  // Attempt to flatten before accessing the string.  It probably
+  // doesn't make Utf8Length faster, but it is very likely that
+  // the string will be accessed later (for example by WriteUtf8)
+  // so it's still a good idea.
+  TryFlatten();
+  Access<StringInputBuffer> buffer(&string_input_buffer);
+  buffer->Reset(0, this);
+  int result = 0;
+  while (buffer->has_more())
+    result += unibrow::Utf8::Length(buffer->GetNext());
+  return result;
+}
+
+
 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
                                      RobustnessFlag robust_flag,
                                      int offset,
@@ -4072,6 +4087,7 @@
   for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
     it.rinfo()->apply(delta);
   }
+  CPU::FlushICache(instruction_start(), instruction_size());
 }
 
 
@@ -4112,6 +4128,7 @@
       it.rinfo()->apply(delta);
     }
   }
+  CPU::FlushICache(instruction_start(), instruction_size());
 }
 
 
@@ -5233,7 +5250,7 @@
 
 // The NumberKey uses carries the uint32_t as key.
 // This avoids allocation in HasProperty.
-class Dictionary::NumberKey : public Dictionary::Key {
+class NumberKey : public HashTableKey {
  public:
   explicit NumberKey(uint32_t number) {
     number_ = number;
@@ -5279,14 +5296,14 @@
   uint32_t number_;
 };
 
+
 // StringKey simply carries a string object as key.
-class Dictionary::StringKey : public Dictionary::Key {
+class StringKey : public HashTableKey {
  public:
   explicit StringKey(String* string) {
     string_ = string;
   }
 
- private:
   bool IsMatch(Object* other) {
     if (!other->IsString()) return false;
     return string_->Equals(String::cast(other));
@@ -5307,10 +5324,10 @@
   String* string_;
 };
 
-// Utf8Key carries a vector of chars as key.
-class SymbolTable::Utf8Key : public SymbolTable::Key {
+// Utf8SymbolKey carries a vector of chars as key.
+class Utf8SymbolKey : public HashTableKey {
  public:
-  explicit Utf8Key(Vector<const char> string)
+  explicit Utf8SymbolKey(Vector<const char> string)
       : string_(string), hash_(0) { }
 
   bool IsMatch(Object* other) {
@@ -5350,10 +5367,10 @@
 };
 
 
-// StringKey carries a string object as key.
-class SymbolTable::StringKey : public SymbolTable::Key {
+// SymbolKey carries a string/symbol object as key.
+class SymbolKey : public HashTableKey {
  public:
-  explicit StringKey(String* string) : string_(string) { }
+  explicit SymbolKey(String* string) : string_(string) { }
 
   HashFunction GetHashFunction() {
     return StringHash;
@@ -5367,6 +5384,15 @@
   uint32_t Hash() { return string_->Hash(); }
 
   Object* GetObject() {
+    // If the string is a cons string, attempt to flatten it so that
+    // symbols will most often be flat strings.
+    if (string_->IsConsString()) {
+      ConsString* cons_string = ConsString::cast(string_);
+      cons_string->TryFlatten();
+      if (cons_string->second() == Heap::empty_string()) {
+        string_ = String::cast(cons_string->first());
+      }
+    }
     // Transform string to symbol if possible.
     Map* map = Heap::SymbolMapForString(string_);
     if (map != NULL) {
@@ -5417,7 +5443,7 @@
 
 // Find entry for key otherwise return -1.
 template <int prefix_size, int element_size>
-int HashTable<prefix_size, element_size>::FindEntry(Key* key) {
+int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) {
   uint32_t nof = NumberOfElements();
   if (nof == 0) return -1;  // Bail out if empty.
 
@@ -5444,7 +5470,8 @@
 
 
 template<int prefix_size, int element_size>
-Object* HashTable<prefix_size, element_size>::EnsureCapacity(int n, Key* key) {
+Object* HashTable<prefix_size, element_size>::EnsureCapacity(
+    int n, HashTableKey* key) {
   int capacity = Capacity();
   int nof = NumberOfElements() + n;
   // Make sure 20% is free
@@ -5502,19 +5529,23 @@
 template class HashTable<2, 3>;
 
 
+// Force instantiation of EvalCache's base class
+template class HashTable<0, 2>;
+
+
 Object* SymbolTable::LookupString(String* string, Object** s) {
-  StringKey key(string);
+  SymbolKey key(string);
   return LookupKey(&key, s);
 }
 
 
 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
-  Utf8Key key(str);
+  Utf8SymbolKey key(str);
   return LookupKey(&key, s);
 }
 
 
-Object* SymbolTable::LookupKey(Key* key, Object** s) {
+Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
   int entry = FindEntry(key);
 
   // Symbol already in table.
@@ -5545,6 +5576,31 @@
 }
 
 
+Object* EvalCache::Lookup(String* src) {
+  StringKey key(src);
+  int entry = FindEntry(&key);
+  if (entry != -1) {
+    return get(EntryToIndex(entry) + 1);
+  } else {
+    return Heap::undefined_value();
+  }
+}
+
+
+Object* EvalCache::Put(String* src, Object* value) {
+  StringKey key(src);
+  Object* obj = EnsureCapacity(1, &key);
+  if (obj->IsFailure()) return obj;
+
+  EvalCache* cache = reinterpret_cast<EvalCache*>(obj);
+  int entry = cache->FindInsertionEntry(src, key.Hash());
+  cache->set(EntryToIndex(entry), src);
+  cache->set(EntryToIndex(entry) + 1, value);
+  cache->ElementAdded();
+  return cache;
+}
+
+
 Object* Dictionary::Allocate(int at_least_space_for) {
   Object* obj = DictionaryBase::Allocate(at_least_space_for);
   // Initialize the next enumeration index.
@@ -5607,7 +5663,7 @@
 }
 
 
-Object* Dictionary::EnsureCapacity(int n, Key* key) {
+Object* Dictionary::EnsureCapacity(int n, HashTableKey* key) {
   // Check whether there are enough enumeration indices to add n elements.
   if (key->IsStringKey() &&
       !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) {
@@ -5663,7 +5719,7 @@
 }
 
 
-Object* Dictionary::AtPut(Key* key, Object* value) {
+Object* Dictionary::AtPut(HashTableKey* key, Object* value) {
   int entry = FindEntry(key);
 
   // If the entry is present set the value;
@@ -5683,7 +5739,8 @@
 }
 
 
-Object* Dictionary::Add(Key* key, Object* value, PropertyDetails details) {
+Object* Dictionary::Add(HashTableKey* key, Object* value,
+                        PropertyDetails details) {
   // Check whether the dictionary should be extended.
   Object* obj = EnsureCapacity(1, key);
   if (obj->IsFailure()) return obj;
diff --git a/src/objects.h b/src/objects.h
index 1f1a805..ba9de24 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -614,6 +614,7 @@
   inline bool IsHashTable();
   inline bool IsDictionary();
   inline bool IsSymbolTable();
+  inline bool IsEvalCache();
   inline bool IsPrimitive();
   inline bool IsGlobalObject();
   inline bool IsJSGlobalObject();
@@ -1681,6 +1682,26 @@
 // table.  The prefix size indicates an amount of memory in the
 // beginning of the backing storage that can be used for non-element
 // information by subclasses.
+
+// HashTableKey is an abstract superclass keys.
+class HashTableKey {
+ public:
+  // Returns whether the other object matches this key.
+  virtual bool IsMatch(Object* other) = 0;
+  typedef uint32_t (*HashFunction)(Object* obj);
+  // Returns the hash function used for this key.
+  virtual HashFunction GetHashFunction() = 0;
+  // Returns the hash value for this key.
+  virtual uint32_t Hash() = 0;
+  // Returns the key object for storing into the dictionary.
+  // If allocations fails a failure object is returned.
+  virtual Object* GetObject() = 0;
+  virtual bool IsStringKey() = 0;
+  // Required.
+  virtual ~HashTableKey() {}
+};
+
+
 template<int prefix_size, int element_size>
 class HashTable: public FixedArray {
  public:
@@ -1722,24 +1743,6 @@
   // Casting.
   static inline HashTable* cast(Object* obj);
 
-  // Key is an abstract superclass keys.
-  class Key {
-   public:
-    // Returns whether the other object matches this key.
-    virtual bool IsMatch(Object* other) = 0;
-    typedef uint32_t (*HashFunction)(Object* obj);
-    // Returns the hash function used for this key.
-    virtual HashFunction GetHashFunction() = 0;
-    // Returns the hash value for this key.
-    virtual uint32_t Hash() = 0;
-    // Returns the key object for storing into the dictionary.
-    // If allocations fails a failure object is returned.
-    virtual Object* GetObject() = 0;
-    virtual bool IsStringKey() = 0;
-    // Required.
-    virtual ~Key() {}
-  };
-
   // Compute the probe offset (quadratic probing).
   INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
     return (n + n * n) >> 1;
@@ -1755,7 +1758,7 @@
 
  protected:
   // Find entry for key otherwise return -1.
-  int FindEntry(Key* key);
+  int FindEntry(HashTableKey* key);
 
   // Find the entry at which to insert element with the given key that
   // has the given hash value.
@@ -1788,7 +1791,7 @@
   }
 
   // Ensure enough space for n additional elements.
-  Object* EnsureCapacity(int n, Key* key);
+  Object* EnsureCapacity(int n, HashTableKey* key);
 };
 
 
@@ -1809,14 +1812,28 @@
   static inline SymbolTable* cast(Object* obj);
 
  private:
-  Object* LookupKey(Key* key, Object** s);
-  class Utf8Key;   // Key based on utf8 string.
-  class StringKey;  // Key based on String*.
+  Object* LookupKey(HashTableKey* key, Object** s);
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
 };
 
 
+// EvalCache for caching eval'ed string and function.
+//
+// The cache is cleaned up during a mark-compact GC.
+class EvalCache: public HashTable<0, 2> {
+ public:
+  // Find cached value for a string key, otherwise return null.
+  Object* Lookup(String* src);
+  Object* Put(String* src, Object* value);
+
+  static inline EvalCache* cast(Object* obj);
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(EvalCache);
+};
+
+
 // Dictionary for keeping properties and elements in slow case.
 //
 // One element in the prefix is used for storing non-element
@@ -1924,7 +1941,7 @@
   static Object* Allocate(int at_least_space_for);
 
   // Ensure enough space for n additional elements.
-  Object* EnsureCapacity(int n, Key* key);
+  Object* EnsureCapacity(int n, HashTableKey* key);
 
 #ifdef DEBUG
   void Print();
@@ -1939,9 +1956,9 @@
 
  private:
   // Generic at put operation.
-  Object* AtPut(Key* key, Object* value);
+  Object* AtPut(HashTableKey* key, Object* value);
 
-  Object* Add(Key* key, Object* value, PropertyDetails details);
+  Object* Add(HashTableKey* key, Object* value, PropertyDetails details);
 
   // Add entry to dictionary.
   void AddEntry(Object* key,
@@ -1963,9 +1980,6 @@
   static const int kMaxNumberKeyIndex = kPrefixStartIndex;
   static const int kNextEnumnerationIndexIndex = kMaxNumberKeyIndex + 1;
 
-  class NumberKey;  // Key containing uint32_t.
-  class StringKey;  // Key containing String*.
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
 };
 
@@ -2842,6 +2856,8 @@
       RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
       int* length_output = 0);
 
+  int Utf8Length();
+
   // Return a 16 bit Unicode representation of the string.
   // The string should be nearly flat, otherwise the performance of
   // of this method may be very bad.  Setting robustness_flag to
@@ -3327,6 +3343,8 @@
 
 
 // Proxy describes objects pointing from JavaScript to C structures.
+// Since they cannot contain references to JS HeapObjects they can be
+// placed in old_data_space.
 class Proxy: public HeapObject {
  public:
   // [proxy]: field containing the address.
diff --git a/src/parser.cc b/src/parser.cc
index d9a65f3..5d7ed0f 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -151,6 +151,13 @@
   Expression* ParseObjectLiteral(bool* ok);
   Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
 
+  // Decide if a property should be the object boilerplate.
+  bool IsBoilerplateProperty(ObjectLiteral::Property* property);
+  // If the property is CONSTANT type, it returns the literal value,
+  // otherwise, it return undefined literal as the placeholder
+  // in the object literal boilerplate.
+  Literal* GetBoilerplateValue(ObjectLiteral::Property* property);
+
   enum FunctionLiteralType {
     EXPRESSION,
     DECLARATION,
@@ -1477,7 +1484,7 @@
   Handle<String> label(static_cast<String**>(NULL));
   Token::Value tok = peek();
   if (!scanner_.has_line_terminator_before_next() &&
-      tok != Token::SEMICOLON && tok != Token::RBRACE) {
+      tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
     label = ParseIdentifier(CHECK_OK);
   }
   IterationStatement* target = NULL;
@@ -1505,7 +1512,7 @@
   Handle<String> label;
   Token::Value tok = peek();
   if (!scanner_.has_line_terminator_before_next() &&
-      tok != Token::SEMICOLON && tok != Token::RBRACE) {
+      tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
     label = ParseIdentifier(CHECK_OK);
   }
   // Parse labelled break statements that target themselves into
@@ -2549,7 +2556,7 @@
       Consume(Token::STRING);
       Handle<String> symbol =
           factory()->LookupSymbol(scanner_.literal_string(),
-                                scanner_.literal_length());
+                                  scanner_.literal_length());
       result = NEW(Literal(symbol));
       break;
     }
@@ -2643,6 +2650,19 @@
 }
 
 
+bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
+  return property != NULL &&
+         property->kind() != ObjectLiteral::Property::PROTOTYPE;
+}
+
+
+Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) {
+  if (property->kind() == ObjectLiteral::Property::CONSTANT)
+    return property->value()->AsLiteral();
+  return GetLiteralUndefined();
+}
+
+
 Expression* Parser::ParseObjectLiteral(bool* ok) {
   // ObjectLiteral ::
   //   '{' (
@@ -2652,7 +2672,7 @@
 
   ZoneListWrapper<ObjectLiteral::Property> properties =
       factory()->NewList<ObjectLiteral::Property>(4);
-  int number_of_constant_properties = 0;
+  int number_of_boilerplate_properties = 0;
 
   Expect(Token::LBRACE, CHECK_OK);
   while (peek() != Token::RBRACE) {
@@ -2674,6 +2694,8 @@
                 ParseFunctionLiteral(name, kNoPosition, DECLARATION, CHECK_OK);
             ObjectLiteral::Property* property =
                 NEW(ObjectLiteral::Property(is_getter, value));
+            if (IsBoilerplateProperty(property))
+              number_of_boilerplate_properties++;
             properties.Add(property);
             if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
             continue;  // restart the while
@@ -2686,8 +2708,8 @@
       case Token::STRING: {
         Consume(Token::STRING);
         Handle<String> string =
-          factory()->LookupSymbol(scanner_.literal_string(),
-                                  scanner_.literal_length());
+            factory()->LookupSymbol(scanner_.literal_string(),
+                                    scanner_.literal_length());
         uint32_t index;
         if (!string.is_null() && string->AsArrayIndex(&index)) {
           key = NewNumberLiteral(index);
@@ -2715,10 +2737,10 @@
 
     ObjectLiteral::Property* property =
         NEW(ObjectLiteral::Property(key, value));
-    if ((property != NULL) &&
-        property->kind() == ObjectLiteral::Property::CONSTANT) {
-      number_of_constant_properties++;
-    }
+
+    // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
+    if (IsBoilerplateProperty(property))
+      number_of_boilerplate_properties++;
     properties.Add(property);
 
     // TODO(1240767): Consider allowing trailing comma.
@@ -2730,17 +2752,21 @@
   if (is_pre_parsing_) return NULL;
 
   Handle<FixedArray> constant_properties =
-      Factory::NewFixedArray(number_of_constant_properties * 2, TENURED);
+      Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
   int position = 0;
   for (int i = 0; i < properties.length(); i++) {
     ObjectLiteral::Property* property = properties.at(i);
-    if (property->kind() == ObjectLiteral::Property::CONSTANT) {
-      Handle<Object> key = property->key()->handle();
-      Literal* literal = property->value()->AsLiteral();
-      // Add name, value pair to the fixed array.
-      constant_properties->set(position++, *key);
-      constant_properties->set(position++, *literal->handle());
-    }
+    if (!IsBoilerplateProperty(property)) continue;
+
+    // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
+    // value for COMPUTED properties, the real value is filled in at
+    // runtime. The enumeration order is maintained.
+    Handle<Object> key = property->key()->handle();
+    Literal* literal = GetBoilerplateValue(property);
+
+    // Add name, value pair to the fixed array.
+    constant_properties->set(position++, *key);
+    constant_properties->set(position++, *literal->handle());
   }
 
   // Construct the expression for calling Runtime::CreateObjectLiteral
@@ -3006,7 +3032,7 @@
   Expect(Token::IDENTIFIER, ok);
   if (!*ok) return Handle<String>();
   return factory()->LookupSymbol(scanner_.literal_string(),
-                               scanner_.literal_length());
+                                 scanner_.literal_length());
 }
 
 // This function reads an identifier and determines whether or not it
diff --git a/src/parser.h b/src/parser.h
index 6c1753d..d331d73 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index e19faad..ba72768 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -67,7 +67,12 @@
 
 void OS::Setup() {
   // Seed the random number generator.
-  srandom(static_cast<unsigned int>(TimeCurrentMillis()));
+  // Convert the current time to a 64-bit integer first, before converting it
+  // to an unsigned. Going directly can cause an overflow and the seed to be
+  // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
 }
 
 
@@ -256,7 +261,11 @@
     void* initial) {
   FILE* file = fopen(name, "w+");
   if (file == NULL) return NULL;
-  fwrite(initial, size, 1, file);
+  int result = fwrite(initial, size, 1, file);
+  if (result < 1) {
+    fclose(file);
+    return NULL;
+  }
   void* memory =
       mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
   return new PosixMemoryMappedFile(file, memory, size);
@@ -285,11 +294,14 @@
     addr_buffer[0] = '0';
     addr_buffer[1] = 'x';
     addr_buffer[10] = 0;
-    read(fd, addr_buffer + 2, 8);
+    int result = read(fd, addr_buffer + 2, 8);
+    if (result < 8) break;
     unsigned start = StringToLongLong(addr_buffer);
-    read(fd, addr_buffer + 2, 1);
-    if (addr_buffer[2] != '-') return;
-    read(fd, addr_buffer + 2, 8);
+    result = read(fd, addr_buffer + 2, 1);
+    if (result < 1) break;
+    if (addr_buffer[2] != '-') break;
+    result = read(fd, addr_buffer + 2, 8);
+    if (result < 8) break;
     unsigned end = StringToLongLong(addr_buffer);
     char buffer[MAP_LENGTH];
     int bytes_read = -1;
@@ -297,9 +309,8 @@
       bytes_read++;
       if (bytes_read >= MAP_LENGTH - 1)
         break;
-      int result = read(fd, buffer + bytes_read, 1);
-      // A read error means that -1 is returned.
-      if (result < 1) return;
+      result = read(fd, buffer + bytes_read, 1);
+      if (result < 1) break;
     } while (buffer[bytes_read] != '\n');
     buffer[bytes_read] = 0;
     // There are 56 chars to ignore at this point in the line.
@@ -309,6 +320,7 @@
     buffer[bytes_read] = 0;
     LOG(SharedLibraryEvent(buffer + 56, start, end));
   }
+  close(fd);
 #endif
 }
 
@@ -346,8 +358,8 @@
 static const int kMmapFdOffset = 0;
 
 
-VirtualMemory::VirtualMemory(size_t size, void* address_hint) {
-  address_ = mmap(address_hint, size, PROT_NONE,
+VirtualMemory::VirtualMemory(size_t size) {
+  address_ = mmap(NULL, size, PROT_NONE,
                   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
                   kMmapFd, kMmapFdOffset);
   size_ = size;
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 58e16a8..7573125 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -73,7 +73,12 @@
 
 void OS::Setup() {
   // Seed the random number generator.
-  srandom(static_cast<unsigned int>(TimeCurrentMillis()));
+  // Convert the current time to a 64-bit integer first, before converting it
+  // to an unsigned. Going directly will cause an overflow and the seed to be
+  // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
 }
 
 
@@ -312,8 +317,8 @@
 static const int kMmapFdOffset = 0;
 
 
-VirtualMemory::VirtualMemory(size_t size, void* address_hint) {
-  address_ = mmap(address_hint, size, PROT_NONE,
+VirtualMemory::VirtualMemory(size_t size) {
+  address_ = mmap(NULL, size, PROT_NONE,
                   MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
                   kMmapFd, kMmapFdOffset);
   size_ = size;
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 214ee94..98cb230 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index c697028..6035465 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -493,7 +493,12 @@
 
 void OS::Setup() {
   // Seed the random number generator.
-  srand(static_cast<unsigned int>(TimeCurrentMillis()));
+  // Convert the current time to a 64-bit integer first, before converting it
+  // to an unsigned. Going directly can cause an overflow and the seed to be
+  // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srand(static_cast<unsigned int>(seed));
 }
 
 
@@ -1171,9 +1176,8 @@
 }
 
 
-VirtualMemory::VirtualMemory(size_t size, void* address_hint) {
-  address_ =
-      VirtualAlloc(address_hint, size, MEM_RESERVE, PAGE_NOACCESS);
+VirtualMemory::VirtualMemory(size_t size) {
+  address_ = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
   size_ = size;
 }
 
diff --git a/src/platform.h b/src/platform.h
index 50fc411..1cb42d2 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -222,7 +222,7 @@
 class VirtualMemory {
  public:
   // Reserves virtual memory with size.
-  VirtualMemory(size_t size, void* address_hint = 0);
+  explicit VirtualMemory(size_t size);
   ~VirtualMemory();
 
   // Returns whether the memory has been reserved.
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 2160cb6..2f377d8 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/prettyprinter.h b/src/prettyprinter.h
index 4d683f1..e10b357 100644
--- a/src/prettyprinter.h
+++ b/src/prettyprinter.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/property.cc b/src/property.cc
index 7546195..6c21530 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/property.h b/src/property.h
index deaedd1..4b6de3a 100644
--- a/src/property.h
+++ b/src/property.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -44,8 +44,6 @@
     return Smi::cast(value)->value();
   }
 
-  String* key() { return key_; }
-
   Object* KeyToSymbol() {
     if (!key_->IsSymbol()) {
       Object* result = Heap::LookupSymbol(key_);
diff --git a/src/regexp-delay.js b/src/regexp-delay.js
index 320e65b..716ad9b 100644
--- a/src/regexp-delay.js
+++ b/src/regexp-delay.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/rewriter.cc b/src/rewriter.cc
index a417b42..6954b23 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/rewriter.h b/src/rewriter.h
index dd2845b..aa1cd2a 100644
--- a/src/rewriter.h
+++ b/src/rewriter.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/runtime.cc b/src/runtime.cc
index 310611c..5bab875 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -2309,14 +2309,6 @@
 }
 
 
-static Object* Runtime_ObjectEquals(Arguments args) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 2);
-
-  return Smi::FromInt(args[0] == args[1] ? EQUAL : NOT_EQUAL);
-}
-
-
 static Object* Runtime_NumberEquals(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
@@ -2387,6 +2379,66 @@
 }
 
 
+// Compare two Smis as if they were converted to strings and then
+// compared lexicographically.
+static Object* Runtime_SmiLexicographicCompare(Arguments args) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 2);
+
+  // Arrays for the individual characters of the two Smis.  Smis are
+  // 31 bit integers and 10 decimal digits are therefore enough.
+  static int x_elms[10];
+  static int y_elms[10];
+
+  // Extract the integer values from the Smis.
+  CONVERT_CHECKED(Smi, x, args[0]);
+  CONVERT_CHECKED(Smi, y, args[1]);
+  int x_value = x->value();
+  int y_value = y->value();
+
+  // If the integers are equal so are the string representations.
+  if (x_value == y_value) return Smi::FromInt(EQUAL);
+
+  // If one of the integers are zero the normal integer order is the
+  // same as the lexicographic order of the string representations.
+  if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
+
+  // If only one of the intergers is negative the negative number is
+  // smallest because the char code of '-' is less than the char code
+  // of any digit.  Otherwise, we make both values positive.
+  if (x_value < 0 || y_value < 0) {
+    if (y_value >= 0) return Smi::FromInt(LESS);
+    if (x_value >= 0) return Smi::FromInt(GREATER);
+    x_value = -x_value;
+    y_value = -y_value;
+  }
+
+  // Convert the integers to arrays of their decimal digits.
+  int x_index = 0;
+  int y_index = 0;
+  while (x_value > 0) {
+    x_elms[x_index++] = x_value % 10;
+    x_value /= 10;
+  }
+  while (y_value > 0) {
+    y_elms[y_index++] = y_value % 10;
+    y_value /= 10;
+  }
+
+  // Loop through the arrays of decimal digits finding the first place
+  // where they differ.
+  while (--x_index >= 0 && --y_index >= 0) {
+    int diff = x_elms[x_index] - y_elms[y_index];
+    if (diff != 0) return Smi::FromInt(diff);
+  }
+
+  // If one array is a suffix of the other array, the longest array is
+  // the representation of the largest of the Smis in the
+  // lexicographic ordering.
+  return Smi::FromInt(x_index - y_index);
+}
+
+
 static Object* Runtime_StringCompare(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
@@ -3169,7 +3221,8 @@
   }
   args[0]->Print();
 #else
-  PrintF("DebugPrint: %p", args[0]);
+  // ShortPrint is available in release mode. Print is not.
+  args[0]->ShortPrint();
 #endif
   PrintF("\n");
 
@@ -3328,10 +3381,26 @@
   }
 
   // Compile eval() source.
+  bool is_global_context = context->IsGlobalContext();
   Handle<String> source(String::cast(args[0]));
-  Handle<JSFunction> boilerplate =
-      Compiler::CompileEval(context->IsGlobalContext(), source);
-  if (boilerplate.is_null()) return Failure::Exception();
+  Object* obj = Heap::LookupEvalCache(is_global_context, *source);
+  if (obj->IsFailure()) return obj;
+
+  Handle<JSFunction> boilerplate;
+  if (!obj->IsJSFunction()) {
+    Counters::eval_cache_misses.Increment();
+    boilerplate = Compiler::CompileEval(is_global_context, source);
+    if (boilerplate.is_null()) return Failure::Exception();
+
+    Object* obj =
+        Heap::PutInEvalCache(is_global_context, *source, *boilerplate);
+    if (obj->IsFailure()) return obj;
+
+  } else {
+    Counters::eval_cache_hits.Increment();
+    boilerplate = Handle<JSFunction>(JSFunction::cast(obj));
+  }
+
   Handle<JSFunction> fun =
       Factory::NewFunctionFromBoilerplate(boilerplate, context);
   return *fun;
@@ -3375,6 +3444,25 @@
 }
 
 
+// Push an array unto an array of arrays if it is not already in the
+// array.  Returns true if the element was pushed on the stack and
+// false otherwise.
+static Object* Runtime_PushIfAbsent(Arguments args) {
+  ASSERT(args.length() == 2);
+  CONVERT_CHECKED(JSArray, array, args[0]);
+  CONVERT_CHECKED(JSArray, element, args[1]);
+  RUNTIME_ASSERT(array->HasFastElements());
+  int length = Smi::cast(array->length())->value();
+  FixedArray* elements = FixedArray::cast(array->elements());
+  for (int i = 0; i < length; i++) {
+    if (elements->get(i) == element) return Heap::false_value();
+  }
+  Object* obj = array->SetFastElement(length, element);
+  if (obj->IsFailure()) return obj;
+  return Heap::true_value();
+}
+
+
 // This will not allocate (flatten the string), but it may run
 // very slowly for very deeply nested ConsStrings.  For debugging use only.
 static Object* Runtime_GlobalPrint(Arguments args) {
@@ -4536,8 +4624,8 @@
   // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
   // rid of all the cached script wrappes and the second gets rid of the
   // scripts which is no longer referenced.
-  Heap::CollectGarbage(0, OLD_SPACE);
-  Heap::CollectGarbage(0, OLD_SPACE);
+  Heap::CollectAllGarbage();
+  Heap::CollectAllGarbage();
 
   // Get the number of scripts.
   int count;
@@ -4641,7 +4729,7 @@
   ASSERT(args.length() == 3);
 
   // First perform a full GC in order to avoid references from dead objects.
-  Heap::CollectGarbage(0, OLD_SPACE);
+  Heap::CollectAllGarbage();
 
   // Check parameters.
   CONVERT_CHECKED(JSObject, target, args[0]);
@@ -4721,7 +4809,7 @@
   ASSERT(args.length() == 2);
 
   // First perform a full GC in order to avoid dead objects.
-  Heap::CollectGarbage(0, OLD_SPACE);
+  Heap::CollectAllGarbage();
 
   // Check parameters.
   CONVERT_CHECKED(JSFunction, constructor, args[0]);
diff --git a/src/runtime.h b/src/runtime.h
index d56e0b3..794a5ca 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -61,6 +61,9 @@
   F(LazyCompile, 1) \
   F(SetNewFunctionAttributes, 1) \
   \
+  /* Array join support */ \
+  F(PushIfAbsent, 2) \
+  \
   /* ConsStrings */ \
   F(ConsStringFst, 1) \
   F(ConsStringSnd, 1) \
@@ -106,11 +109,11 @@
   F(NumberSar, 2) \
   \
   /* Comparisons */ \
-  F(ObjectEquals, 2) \
   F(NumberEquals, 2) \
   F(StringEquals, 2) \
   \
   F(NumberCompare, 3) \
+  F(SmiLexicographicCompare, 2) \
   F(StringCompare, 2) \
   \
   /* Math */ \
diff --git a/src/runtime.js b/src/runtime.js
index 78c20c1..46a61d8 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -57,13 +57,13 @@
   // NOTE: We use iteration instead of recursion, because it is
   // difficult to call EQUALS with the correct setting of 'this' in
   // an efficient way.
-  
+
   while (true) {
-    
+
     if (IS_NUMBER(x)) {
       if (y == null) return 1;  // not equal
       return %NumberEquals(x, %ToNumber(y));
-      
+
     } else if (IS_STRING(x)) {
       if (IS_STRING(y)) return %StringEquals(x, y);
       if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
@@ -72,19 +72,25 @@
       y = %ToPrimitive(y, NO_HINT);
 
     } else if (IS_BOOLEAN(x)) {
-      if (IS_BOOLEAN(y)) return %ObjectEquals(x, y);
+      if (IS_BOOLEAN(y)) {
+        return %_ObjectEquals(x, y) ? 0 : 1;
+      }
       if (y == null) return 1;  // not equal
       return %NumberEquals(%ToNumber(x), %ToNumber(y));
-      
+
     } else if (x == null) {
       // NOTE: This checks for both null and undefined.
       return (y == null) ? 0 : 1;
-      
+
     } else {
-      if (IS_OBJECT(y)) return %ObjectEquals(x, y);
-      if (IS_FUNCTION(y)) return %ObjectEquals(x, y);
+      if (IS_OBJECT(y)) {
+        return %_ObjectEquals(x, y) ? 0 : 1;
+      }
+      if (IS_FUNCTION(y)) {
+        return %_ObjectEquals(x, y) ? 0 : 1;
+      }
       x = %ToPrimitive(x, NO_HINT);
-      
+
     }
   }
 };
@@ -96,23 +102,23 @@
     if (!IS_NUMBER(x)) return 1;  // not equal
     return %NumberEquals(this, x);
   }
-  
+
   if (IS_STRING(this)) {
     if (!IS_STRING(x)) return 1;  // not equal
     return %StringEquals(this, x);
   }
-  
+
   if (IS_BOOLEAN(this)) {
     if (!IS_BOOLEAN(x)) return 1;  // not equal
     if (this) return x ? 0 : 1;
     else return x ? 1 : 0;
   }
-  
+
   if (IS_UNDEFINED(this)) {  // both undefined and undetectable
     return IS_UNDEFINED(x) ? 0 : 1;
   }
-  
-  return %ObjectEquals(this, x);
+
+  return %_ObjectEquals(this, x) ? 0 : 1;
 };
 
 
@@ -123,7 +129,7 @@
   if (IS_NUMBER(this) && IS_NUMBER(x)) {
     return %NumberCompare(this, x, ncr);
   }
-  
+
   var a = %ToPrimitive(this, NUMBER_HINT);
   var b = %ToPrimitive(x, NUMBER_HINT);
   if (IS_STRING(a) && IS_STRING(b)) {
@@ -433,7 +439,7 @@
   if (IS_STRING(x)) return new $String(x);
   if (IS_NUMBER(x)) return new $Number(x);
   if (IS_BOOLEAN(x)) return new $Boolean(x);
-  if (x == null) throw %MakeTypeError('null_to_object');
+  if (x == null) throw %MakeTypeError('null_to_object', []);
   return x;
 };
 
diff --git a/src/scanner.cc b/src/scanner.cc
index b3e0015..a6cc74a 100644
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/scanner.h b/src/scanner.h
index 5a89afd..79a4a4c 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index a6a3f97..b51cb98 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/scopeinfo.h b/src/scopeinfo.h
index c172014..285280c 100644
--- a/src/scopeinfo.h
+++ b/src/scopeinfo.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/scopes.cc b/src/scopes.cc
index b2b8f65..96f0c60 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/scopes.h b/src/scopes.h
index 1cad762..05e462b 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/serialize.cc b/src/serialize.cc
index d1501e0..ba18ce8 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -53,13 +53,23 @@
 // - MAP and OLD spaces: 16 bits of page number, 11 bits of word offset in page
 // - NEW space:          27 bits of word offset
 // - LO space:           27 bits of page number
-// 3 bits to encode the AllocationSpace
+// 3 bits to encode the AllocationSpace (special values for code in LO space)
 // 2 bits identifying this as a HeapObject
 
 const int kSpaceShift = kHeapObjectTagSize;
 const int kSpaceBits = kSpaceTagSize;
 const int kSpaceMask = kSpaceTagMask;
 
+// These value are used instead of space numbers when serializing/
+// deserializing.  They indicate an object that is in large object space, but
+// should be treated specially.
+// Make the pages executable on platforms that support it:
+const int kLOSpaceExecutable = LAST_SPACE + 1;
+// Reserve space for write barrier bits (for objects that can contain
+// references to new space):
+const int kLOSpacePointer = LAST_SPACE + 2;
+
+
 const int kOffsetShift = kSpaceShift + kSpaceBits;
 const int kOffsetBits = 11;
 const int kOffsetMask = (1 << kOffsetBits) - 1;
@@ -73,9 +83,28 @@
 const int kPageAndOffsetMask = (1 << kPageAndOffsetBits) - 1;
 
 
-static inline AllocationSpace Space(Address addr) {
+static inline AllocationSpace GetSpace(Address addr) {
   const int encoded = reinterpret_cast<int>(addr);
-  return static_cast<AllocationSpace>((encoded >> kSpaceShift) & kSpaceMask);
+  int space_number = ((encoded >> kSpaceShift) & kSpaceMask);
+  if (space_number == kLOSpaceExecutable) space_number = LO_SPACE;
+  else if (space_number == kLOSpacePointer) space_number = LO_SPACE;
+  return static_cast<AllocationSpace>(space_number);
+}
+
+
+static inline bool IsLargeExecutableObject(Address addr) {
+  const int encoded = reinterpret_cast<int>(addr);
+  const int space_number = ((encoded >> kSpaceShift) & kSpaceMask);
+  if (space_number == kLOSpaceExecutable) return true;
+  return false;
+}
+
+
+static inline bool IsLargeFixedArray(Address addr) {
+  const int encoded = reinterpret_cast<int>(addr);
+  const int space_number = ((encoded >> kSpaceShift) & kSpaceMask);
+  if (space_number == kLOSpacePointer) return true;
+  return false;
 }
 
 
@@ -117,18 +146,29 @@
 
 class RelativeAddress {
  public:
-  RelativeAddress(AllocationSpace space, int page_index, int page_offset)
-  : space_(space), page_index_(page_index), page_offset_(page_offset) {}
+  RelativeAddress(AllocationSpace space,
+                  int page_index,
+                  int page_offset)
+  : space_(space), page_index_(page_index), page_offset_(page_offset)  {
+    ASSERT(space <= LAST_SPACE && space >= 0);
+  }
 
   // Return the encoding of 'this' as an Address. Decode with constructor.
   Address Encode() const;
 
-  AllocationSpace space() const { return space_; }
+  AllocationSpace space() const {
+    if (space_ == kLOSpaceExecutable) return LO_SPACE;
+    if (space_ == kLOSpacePointer) return LO_SPACE;
+    return static_cast<AllocationSpace>(space_);
+  }
   int page_index() const { return page_index_; }
   int page_offset() const { return page_offset_; }
 
   bool in_paged_space() const {
-    return space_ == CODE_SPACE || space_ == OLD_SPACE || space_ == MAP_SPACE;
+    return space_ == CODE_SPACE ||
+           space_ == OLD_POINTER_SPACE ||
+           space_ == OLD_DATA_SPACE ||
+           space_ == MAP_SPACE;
   }
 
   void next_address(int offset) { page_offset_ += offset; }
@@ -141,8 +181,18 @@
   void Verify();
 #endif
 
+  void set_to_large_code_object() {
+    ASSERT(space_ == LO_SPACE);
+    space_ = kLOSpaceExecutable;
+  }
+  void set_to_large_fixed_array() {
+    ASSERT(space_ == LO_SPACE);
+    space_ = kLOSpacePointer;
+  }
+
+
  private:
-  AllocationSpace space_;
+  int space_;
   int page_index_;
   int page_offset_;
 };
@@ -154,7 +204,8 @@
   int result = 0;
   switch (space_) {
     case MAP_SPACE:
-    case OLD_SPACE:
+    case OLD_POINTER_SPACE:
+    case OLD_DATA_SPACE:
     case CODE_SPACE:
       ASSERT_EQ(0, page_index_ & ~kPageMask);
       word_offset = page_offset_ >> kObjectAlignmentBits;
@@ -168,6 +219,8 @@
       result = word_offset << kPageAndOffsetShift;
       break;
     case LO_SPACE:
+    case kLOSpaceExecutable:
+    case kLOSpacePointer:
       ASSERT_EQ(0, page_offset_);
       ASSERT_EQ(0, page_index_ & ~kPageAndOffsetMask);
       result = page_index_ << kPageAndOffsetShift;
@@ -185,7 +238,8 @@
   ASSERT(page_offset_ >= 0 && page_index_ >= 0);
   switch (space_) {
     case MAP_SPACE:
-    case OLD_SPACE:
+    case OLD_POINTER_SPACE:
+    case OLD_DATA_SPACE:
     case CODE_SPACE:
       ASSERT(Page::kObjectStartOffset <= page_offset_ &&
              page_offset_ <= Page::kPageSize);
@@ -194,12 +248,20 @@
       ASSERT(page_index_ == 0);
       break;
     case LO_SPACE:
+    case kLOSpaceExecutable:
+    case kLOSpacePointer:
       ASSERT(page_offset_ == 0);
       break;
   }
 }
 #endif
 
+enum GCTreatment {
+  DataObject,     // Object that cannot contain a reference to new space.
+  PointerObject,  // Object that can contain a reference to new space.
+  CodeObject      // Object that contains executable code.
+};
+
 // A SimulatedHeapSpace simulates the allocation of objects in a page in
 // the heap. It uses linear allocation - that is, it doesn't simulate the
 // use of a free list. This simulated
@@ -222,7 +284,7 @@
   // Returns the RelativeAddress where the next
   // object of 'size' bytes will be allocated, and updates 'this' to
   // point to the next free address beyond that object.
-  RelativeAddress Allocate(int size);
+  RelativeAddress Allocate(int size, GCTreatment special_gc_treatment);
 
  private:
   RelativeAddress current_;
@@ -232,7 +294,8 @@
 void SimulatedHeapSpace::InitEmptyHeap(AllocationSpace space) {
   switch (space) {
     case MAP_SPACE:
-    case OLD_SPACE:
+    case OLD_POINTER_SPACE:
+    case OLD_DATA_SPACE:
     case CODE_SPACE:
       current_ = RelativeAddress(space, 0, Page::kObjectStartOffset);
       break;
@@ -247,13 +310,16 @@
 void SimulatedHeapSpace::InitCurrentHeap(AllocationSpace space) {
   switch (space) {
     case MAP_SPACE:
-    case OLD_SPACE:
+    case OLD_POINTER_SPACE:
+    case OLD_DATA_SPACE:
     case CODE_SPACE: {
       PagedSpace* ps;
       if (space == MAP_SPACE) {
         ps = Heap::map_space();
-      } else if (space == OLD_SPACE) {
-        ps = Heap::old_space();
+      } else if (space == OLD_POINTER_SPACE) {
+        ps = Heap::old_pointer_space();
+      } else if (space == OLD_DATA_SPACE) {
+        ps = Heap::old_data_space();
       } else {
         ASSERT(space == CODE_SPACE);
         ps = Heap::code_space();
@@ -266,12 +332,15 @@
         if (it.next() == top_page) break;
         page_index++;
       }
-      current_ = RelativeAddress(space, page_index, top_page->Offset(top));
+      current_ = RelativeAddress(space,
+                                 page_index,
+                                 top_page->Offset(top));
       break;
     }
     case NEW_SPACE:
-      current_ =
-        RelativeAddress(space, 0, Heap::NewSpaceTop() - Heap::NewSpaceStart());
+      current_ = RelativeAddress(space,
+                                 0,
+                                 Heap::NewSpaceTop() - Heap::NewSpaceStart());
       break;
     case LO_SPACE:
       int page_index = 0;
@@ -284,7 +353,8 @@
 }
 
 
-RelativeAddress SimulatedHeapSpace::Allocate(int size) {
+RelativeAddress SimulatedHeapSpace::Allocate(int size,
+                                             GCTreatment special_gc_treatment) {
 #ifdef DEBUG
   current_.Verify();
 #endif
@@ -297,6 +367,11 @@
   RelativeAddress result = current_;
   if (current_.space() == LO_SPACE) {
     current_.next_page();
+    if (special_gc_treatment == CodeObject) {
+      result.set_to_large_code_object();
+    } else if (special_gc_treatment == PointerObject) {
+      result.set_to_large_fixed_array();
+    }
   } else {
     current_.next_address(alloc_size);
   }
@@ -924,7 +999,10 @@
   // and code spaces, because objects in new space will be promoted to them.
   writer_->PutC('S');
   writer_->PutC('[');
-  writer_->PutInt(Heap::old_space()->Size() + Heap::new_space()->Size());
+  writer_->PutInt(Heap::old_pointer_space()->Size() +
+                  Heap::new_space()->Size());
+  writer_->PutC('|');
+  writer_->PutInt(Heap::old_data_space()->Size() + Heap::new_space()->Size());
   writer_->PutC('|');
   writer_->PutInt(Heap::code_space()->Size() + Heap::new_space()->Size());
   writer_->PutC('|');
@@ -1094,16 +1172,24 @@
   // Find out which AllocationSpace 'obj' is in.
   AllocationSpace s;
   bool found = false;
-  for (int i = 0; !found && i <= LAST_SPACE; i++) {
+  for (int i = FIRST_SPACE; !found && i <= LAST_SPACE; i++) {
     s = static_cast<AllocationSpace>(i);
     found = Heap::InSpace(obj, s);
   }
   CHECK(found);
   if (s == NEW_SPACE) {
-    s = Heap::TargetSpace(obj);
+    Space* space = Heap::TargetSpace(obj);
+    ASSERT(space == Heap::old_pointer_space() ||
+           space == Heap::old_data_space());
+    s = (space == Heap::old_pointer_space()) ?
+        OLD_POINTER_SPACE :
+        OLD_DATA_SPACE;
   }
   int size = obj->Size();
-  return allocator_[s]->Allocate(size);
+  GCTreatment gc_treatment = DataObject;
+  if (obj->IsFixedArray()) gc_treatment = PointerObject;
+  else if (obj->IsCode()) gc_treatment = CodeObject;
+  return allocator_[s]->Allocate(size, gc_treatment);
 }
 
 
@@ -1116,8 +1202,11 @@
 
 Deserializer::Deserializer(const char* str, int len)
   : reader_(str, len),
-    map_pages_(kInitArraySize), old_pages_(kInitArraySize),
-    code_pages_(kInitArraySize), large_objects_(kInitArraySize),
+    map_pages_(kInitArraySize),
+    old_pointer_pages_(kInitArraySize),
+    old_data_pages_(kInitArraySize),
+    code_pages_(kInitArraySize),
+    large_objects_(kInitArraySize),
     global_handles_(4) {
   root_ = true;
   roots_ = 0;
@@ -1281,7 +1370,11 @@
   // during deserialization.
   reader_.ExpectC('S');
   reader_.ExpectC('[');
-  InitPagedSpace(Heap::old_space(), reader_.GetInt(), &old_pages_);
+  InitPagedSpace(Heap::old_pointer_space(),
+                 reader_.GetInt(),
+                 &old_pointer_pages_);
+  reader_.ExpectC('|');
+  InitPagedSpace(Heap::old_data_space(), reader_.GetInt(), &old_data_pages_);
   reader_.ExpectC('|');
   InitPagedSpace(Heap::code_space(), reader_.GetInt(), &code_pages_);
   reader_.ExpectC('|');
@@ -1340,7 +1433,15 @@
   Address a = GetEncodedAddress();
 
   // Get a raw object of the right size in the right space.
-  Object* o = Heap::AllocateRaw(size, Space(a));
+  AllocationSpace space = GetSpace(a);
+  Object *o;
+  if (IsLargeExecutableObject(a)) {
+    o = Heap::lo_space()->AllocateRawCode(size);
+  } else if (IsLargeFixedArray(a)) {
+    o = Heap::lo_space()->AllocateRawFixedArray(size);
+  } else {
+    o = Heap::AllocateRaw(size, space);
+  }
   ASSERT(!o->IsFailure());
   // Check that the simulation of heap allocation was correct.
   ASSERT(o == Resolve(a));
@@ -1405,18 +1506,20 @@
   // Encoded addresses of HeapObjects always have 'HeapObject' tags.
   ASSERT(o->IsHeapObject());
 
-  switch (Space(encoded)) {
-    // For Map space and Old space, we cache the known Pages in
-    // map_pages and old_pages respectively. Even though MapSpace
-    // keeps a list of page addresses, we don't rely on it since
-    // GetObject uses AllocateRaw, and that appears not to update
-    // the page list.
+  switch (GetSpace(encoded)) {
+    // For Map space and Old space, we cache the known Pages in map_pages,
+    // old_pointer_pages and old_data_pages. Even though MapSpace keeps a list
+    // of page addresses, we don't rely on it since GetObject uses AllocateRaw,
+    // and that appears not to update the page list.
     case MAP_SPACE:
       return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
                           Heap::map_space(), &map_pages_);
-    case OLD_SPACE:
+    case OLD_POINTER_SPACE:
       return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::old_space(), &old_pages_);
+                          Heap::old_pointer_space(), &old_pointer_pages_);
+    case OLD_DATA_SPACE:
+      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
+                          Heap::old_data_space(), &old_data_pages_);
     case CODE_SPACE:
       return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
                           Heap::code_space(), &code_pages_);
diff --git a/src/serialize.h b/src/serialize.h
index be0be83..5c65daf 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -312,10 +312,11 @@
   bool has_log_;  // The file has log information.
 
   // Resolve caches the following:
-  List<Page*> map_pages_;       // All pages in the map space.
-  List<Page*> old_pages_;       // All pages in the old space.
+  List<Page*> map_pages_;          // All pages in the map space.
+  List<Page*> old_pointer_pages_;  // All pages in the old pointer space.
+  List<Page*> old_data_pages_;     // All pages in the old data space.
   List<Page*> code_pages_;
-  List<Object*> large_objects_;  // All known large objects.
+  List<Object*> large_objects_;    // All known large objects.
   // A list of global handles at deserialization time.
   List<Object**> global_handles_;
 
diff --git a/src/shell.h b/src/shell.h
index 85b5863..4042c07 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/simulator-arm.cc b/src/simulator-arm.cc
index 71e3a43..b11ffb1 100644
--- a/src/simulator-arm.cc
+++ b/src/simulator-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/simulator-arm.h b/src/simulator-arm.h
index c949593..1ccd856 100644
--- a/src/simulator-arm.h
+++ b/src/simulator-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/simulator-ia32.cc b/src/simulator-ia32.cc
index bb3ce0d..ab81693 100644
--- a/src/simulator-ia32.cc
+++ b/src/simulator-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/simulator-ia32.h b/src/simulator-ia32.h
index bf4072b..2267721 100644
--- a/src/simulator-ia32.h
+++ b/src/simulator-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/smart-pointer.h b/src/smart-pointer.h
index 7ff35c2..accbe03 100644
--- a/src/smart-pointer.h
+++ b/src/smart-pointer.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/snapshot-common.cc b/src/snapshot-common.cc
index 314a5f0..b0e9323 100644
--- a/src/snapshot-common.cc
+++ b/src/snapshot-common.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/snapshot-empty.cc b/src/snapshot-empty.cc
index 909a223..1c8ec5f 100644
--- a/src/snapshot-empty.cc
+++ b/src/snapshot-empty.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/snapshot.h b/src/snapshot.h
index bb40c2e..2d8b9ac 100644
--- a/src/snapshot.h
+++ b/src/snapshot.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -37,8 +37,8 @@
   // could be found.
   static bool Initialize(const char* snapshot_file = NULL);
 
-  // Disable the use of the internal snapshot.
-  static void DisableInternal() { size_ = 0; }
+  // Returns whether or not the snapshot is enabled.
+  static bool IsEnabled() { return size_ != 0; }
 
   // Write snapshot to the given file. Returns true if snapshot was written
   // successfully.
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index 38aa7e1..86369b9 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -86,14 +86,7 @@
 
 Address Page::AllocationTop() {
   PagedSpace* owner = MemoryAllocator::PageOwner(this);
-  if (Heap::old_space() == owner) {
-    return Heap::old_space()->PageAllocationTop(this);
-  } else if (Heap::code_space() == owner) {
-    return Heap::code_space()->PageAllocationTop(this);
-  } else {
-    ASSERT(Heap::map_space() == owner);
-    return Heap::map_space()->PageAllocationTop(this);
-  }
+  return owner->PageAllocationTop(this);
 }
 
 
@@ -282,24 +275,6 @@
 }
 
 
-// Allocating during deserialization.  Always roll to the next page in the
-// space, which should be suitably expanded.
-Object* PagedSpace::AllocateForDeserialization(int size_in_bytes) {
-  ASSERT(HasBeenSetup());
-  ASSERT_OBJECT_SIZE(size_in_bytes);
-  HeapObject* object = AllocateLinearly(&allocation_info_, size_in_bytes);
-  if (object != NULL) return object;
-
-  // The space should be pre-expanded.
-  Page* current_page = Page::FromAllocationTop(allocation_info_.top);
-  ASSERT(current_page->next_page()->is_valid());
-  object = AllocateInNextPage(current_page, size_in_bytes);
-
-  ASSERT(object != NULL);
-  return object;
-}
-
-
 // -----------------------------------------------------------------------------
 // LargeObjectChunk
 
diff --git a/src/spaces.cc b/src/spaces.cc
index 279e10a..7920187 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -227,10 +227,10 @@
 
 void* MemoryAllocator::AllocateRawMemory(const size_t requested,
                                          size_t* allocated,
-                                         bool executable) {
+                                         Executability executable) {
   if (size_ + static_cast<int>(requested) > capacity_) return NULL;
 
-  void* mem = OS::Allocate(requested, allocated, executable);
+  void* mem = OS::Allocate(requested, allocated, executable == EXECUTABLE);
   int alloced = *allocated;
   size_ += alloced;
   Counters::memory_allocated.Increment(alloced);
@@ -316,7 +316,7 @@
   ASSERT(initial_chunk_->address() <= start);
   ASSERT(start + size <= reinterpret_cast<Address>(initial_chunk_->address())
                              + initial_chunk_->size());
-  if (!initial_chunk_->Commit(start, size, owner->executable())) {
+  if (!initial_chunk_->Commit(start, size, owner->executable() == EXECUTABLE)) {
     return Page::FromAddress(NULL);
   }
   Counters::memory_allocated.Increment(size);
@@ -332,7 +332,7 @@
 
 bool MemoryAllocator::CommitBlock(Address start,
                                   size_t size,
-                                  bool executable) {
+                                  Executability executable) {
   ASSERT(start != NULL);
   ASSERT(size > 0);
   ASSERT(initial_chunk_ != NULL);
@@ -474,7 +474,9 @@
 // -----------------------------------------------------------------------------
 // PagedSpace implementation
 
-PagedSpace::PagedSpace(int max_capacity, AllocationSpace id, bool executable)
+PagedSpace::PagedSpace(int max_capacity,
+                       AllocationSpace id,
+                       Executability executable)
     : Space(id, executable) {
   max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize)
                   * Page::kObjectAreaSize;
@@ -494,8 +496,11 @@
   int num_pages = 0;
   // Try to use the virtual memory range passed to us.  If it is too small to
   // contain at least one page, ignore it and allocate instead.
-  if (PagesInChunk(start, size) > 0) {
-    first_page_ = MemoryAllocator::CommitPages(start, size, this, &num_pages);
+  int pages_in_chunk = PagesInChunk(start, size);
+  if (pages_in_chunk > 0) {
+    first_page_ = MemoryAllocator::CommitPages(RoundUp(start, Page::kPageSize),
+                                               Page::kPageSize * pages_in_chunk,
+                                               this, &num_pages);
   } else {
     int requested_pages = Min(MemoryAllocator::kPagesPerChunk,
                               max_capacity_ / Page::kObjectAreaSize);
@@ -768,15 +773,14 @@
 
 NewSpace::NewSpace(int initial_semispace_capacity,
                    int maximum_semispace_capacity,
-                   AllocationSpace id,
-                   bool executable)
-    : Space(id, executable) {
+                   AllocationSpace id)
+    : Space(id, NOT_EXECUTABLE) {
   ASSERT(initial_semispace_capacity <= maximum_semispace_capacity);
   ASSERT(IsPowerOf2(maximum_semispace_capacity));
   maximum_capacity_ = maximum_semispace_capacity;
   capacity_ = initial_semispace_capacity;
-  to_space_ = new SemiSpace(capacity_, maximum_capacity_, id, executable);
-  from_space_ = new SemiSpace(capacity_, maximum_capacity_, id, executable);
+  to_space_ = new SemiSpace(capacity_, maximum_capacity_, id);
+  from_space_ = new SemiSpace(capacity_, maximum_capacity_, id);
 
   // Allocate and setup the histogram arrays if necessary.
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
@@ -940,9 +944,8 @@
 
 SemiSpace::SemiSpace(int initial_capacity,
                      int maximum_capacity,
-                     AllocationSpace id,
-                     bool executable)
-    : Space(id, executable), capacity_(initial_capacity),
+                     AllocationSpace id)
+    : Space(id, NOT_EXECUTABLE), capacity_(initial_capacity),
       maximum_capacity_(maximum_capacity), start_(NULL), age_mark_(NULL) {
 }
 
@@ -980,6 +983,9 @@
 
 #ifdef DEBUG
 void SemiSpace::Print() { }
+
+
+void SemiSpace::Verify() { }
 #endif
 
 
@@ -2190,7 +2196,7 @@
 
 LargeObjectChunk* LargeObjectChunk::New(int size_in_bytes,
                                         size_t* chunk_size,
-                                        bool executable) {
+                                        Executability executable) {
   size_t requested = ChunkSizeFor(size_in_bytes);
   void* mem = MemoryAllocator::AllocateRawMemory(requested,
                                                  chunk_size,
@@ -2216,8 +2222,8 @@
 // -----------------------------------------------------------------------------
 // LargeObjectSpace
 
-LargeObjectSpace::LargeObjectSpace(AllocationSpace id, bool executable)
-    : Space(id, executable),
+LargeObjectSpace::LargeObjectSpace(AllocationSpace id)
+    : Space(id, NOT_EXECUTABLE),  // Managed on a per-allocation basis
       first_chunk_(NULL),
       size_(0),
       page_count_(0) {}
@@ -2245,11 +2251,12 @@
 
 
 Object* LargeObjectSpace::AllocateRawInternal(int requested_size,
-                                              int object_size) {
+                                              int object_size,
+                                              Executability executable) {
   ASSERT(0 < object_size && object_size <= requested_size);
   size_t chunk_size;
   LargeObjectChunk* chunk =
-      LargeObjectChunk::New(requested_size, &chunk_size, executable());
+      LargeObjectChunk::New(requested_size, &chunk_size, executable);
   if (chunk == NULL) {
     return Failure::RetryAfterGC(requested_size, identity());
   }
@@ -2280,15 +2287,28 @@
 }
 
 
-Object* LargeObjectSpace::AllocateRaw(int size_in_bytes) {
+Object* LargeObjectSpace::AllocateRawCode(int size_in_bytes) {
   ASSERT(0 < size_in_bytes);
-  return AllocateRawInternal(size_in_bytes, size_in_bytes);
+  return AllocateRawInternal(size_in_bytes,
+                             size_in_bytes,
+                             EXECUTABLE);
 }
 
 
 Object* LargeObjectSpace::AllocateRawFixedArray(int size_in_bytes) {
+  ASSERT(0 < size_in_bytes);
   int extra_rset_bytes = ExtraRSetBytesFor(size_in_bytes);
-  return AllocateRawInternal(size_in_bytes + extra_rset_bytes, size_in_bytes);
+  return AllocateRawInternal(size_in_bytes + extra_rset_bytes,
+                             size_in_bytes,
+                             NOT_EXECUTABLE);
+}
+
+
+Object* LargeObjectSpace::AllocateRaw(int size_in_bytes) {
+  ASSERT(0 < size_in_bytes);
+  return AllocateRawInternal(size_in_bytes,
+                             size_in_bytes,
+                             NOT_EXECUTABLE);
 }
 
 
diff --git a/src/spaces.h b/src/spaces.h
index cfa43e9..04bf01e 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -209,7 +209,7 @@
   // 8K bytes per page.
   static const int kPageSizeBits = 13;
 
-  // Page size in bytes.
+  // Page size in bytes.  This must be a multiple of the OS page size.
   static const int kPageSize = 1 << kPageSizeBits;
 
   // Page size mask.
@@ -234,7 +234,7 @@
   //---------------------------------------------------------------------------
   // Page header description.
   //
-  // If a page is not in a large object space, the first word,
+  // If a page is not in the large object space, the first word,
   // opaque_header, encodes the next page address (aligned to kPageSize 8K)
   // and the chunk number (0 ~ 8K-1).  Only MemoryAllocator should use
   // opaque_header. The value range of the opaque_header is [0..kPageSize[,
@@ -275,15 +275,21 @@
 // Space is the abstract superclass for all allocation spaces.
 class Space : public Malloced {
  public:
-  Space(AllocationSpace id, bool executable)
+  Space(AllocationSpace id, Executability executable)
       : id_(id), executable_(executable) {}
+  virtual ~Space() {}
   // Does the space need executable memory?
-  bool executable() { return executable_; }
+  Executability executable() { return executable_; }
   // Identity used in error reporting.
   AllocationSpace identity() { return id_; }
+  virtual int Size() = 0;
+#ifdef DEBUG
+  virtual void Verify() = 0;
+  virtual void Print() = 0;
+#endif
  private:
   AllocationSpace id_;
-  bool executable_;
+  Executability executable_;
 };
 
 
@@ -338,7 +344,7 @@
   // the address is not NULL, the size is greater than zero, and that the
   // block is contained in the initial chunk.  Returns true if it succeeded
   // and false otherwise.
-  static bool CommitBlock(Address start, size_t size, bool executable);
+  static bool CommitBlock(Address start, size_t size, Executability executable);
 
   // Attempts to allocate the requested (non-zero) number of pages from the
   // OS.  Fewer pages might be allocated than requested. If it fails to
@@ -363,12 +369,17 @@
   // but keep track of allocated bytes as part of heap.
   static void* AllocateRawMemory(const size_t requested,
                                  size_t* allocated,
-                                 bool executable);
+                                 Executability executable);
   static void FreeRawMemory(void* buf, size_t length);
 
   // Returns the maximum available bytes of heaps.
   static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; }
 
+  // Returns maximum available bytes that the old space can have.
+  static int MaxAvailable() {
+    return (Available() / Page::kPageSize) * Page::kObjectAreaSize;
+  }
+
   // Links two pages.
   static inline void SetNextPage(Page* prev, Page* next);
 
@@ -661,7 +672,7 @@
   friend class PageIterator;
  public:
   // Creates a space with a maximum capacity, and an id.
-  PagedSpace(int max_capacity, AllocationSpace id, bool executable);
+  PagedSpace(int max_capacity, AllocationSpace id, Executability executable);
 
   virtual ~PagedSpace() {}
 
@@ -695,6 +706,11 @@
   // Clears remembered sets of pages in this space.
   void ClearRSet();
 
+  // Prepares for a mark-compact GC.
+  virtual void PrepareForMarkCompact(bool will_compact) = 0;
+
+  virtual Address PageAllocationTop(Page* page) = 0;
+
   // Current capacity without growing (Size() + Available() + Waste()).
   int Capacity() { return accounting_stats_.Capacity(); }
 
@@ -702,7 +718,7 @@
   int Available() { return accounting_stats_.Available(); }
 
   // Allocated bytes in this space.
-  int Size() { return accounting_stats_.Size(); }
+  virtual int Size() { return accounting_stats_.Size(); }
 
   // Wasted bytes due to fragmentation and not recoverable until the
   // next GC of this space.
@@ -723,9 +739,6 @@
   inline Object* MCAllocateRaw(int size_in_bytes);
 
 
-  // Allocate the requested number of bytes during deserialization.
-  inline Object* AllocateForDeserialization(int size_in_bytes);
-
   // ---------------------------------------------------------------------------
   // Mark-compact collection support functions
 
@@ -741,6 +754,10 @@
   // of the space.
   int MCSpaceOffsetForAddress(Address addr);
 
+  // Updates the allocation pointer to the relocation top after a mark-compact
+  // collection.
+  virtual void MCCommitRelocationInfo() = 0;
+
   // Releases half of unused pages.
   void Shrink();
 
@@ -749,7 +766,7 @@
 
 #ifdef DEBUG
   // Print meta info and objects in this space.
-  void Print();
+  virtual void Print();
 
   // Report code object related statistics
   void CollectCodeStatistics();
@@ -869,8 +886,8 @@
   // addresses.
   SemiSpace(int initial_capacity,
             int maximum_capacity,
-            AllocationSpace id,
-            bool executable);
+            AllocationSpace id);
+  virtual ~SemiSpace() {}
 
   // Sets up the semispace using the given chunk.
   bool Setup(Address start, int size);
@@ -913,8 +930,16 @@
   // The offset of an address from the begining of the space.
   int SpaceOffsetForAddress(Address addr) { return addr - low(); }
 
+  // If we don't have this here then SemiSpace will be abstract.  However
+  // it should never be called.
+  virtual int Size() {
+    UNREACHABLE();
+    return 0;
+  }
+
 #ifdef DEBUG
-  void Print();
+  virtual void Print();
+  virtual void Verify();
 #endif
 
  private:
@@ -999,8 +1024,8 @@
   // and it must be aligned to its size.
   NewSpace(int initial_semispace_capacity,
            int maximum_semispace_capacity,
-           AllocationSpace id,
-           bool executable);
+           AllocationSpace id);
+  virtual ~NewSpace() {}
 
   // Sets up the new space using the given chunk.
   bool Setup(Address start, int size);
@@ -1032,7 +1057,7 @@
   }
 
   // Return the allocated bytes in the active semispace.
-  int Size() { return top() - bottom(); }
+  virtual int Size() { return top() - bottom(); }
   // Return the current capacity of a semispace.
   int Capacity() { return capacity_; }
   // Return the available bytes without growing in the active semispace.
@@ -1107,9 +1132,9 @@
 
 #ifdef DEBUG
   // Verify the active semispace.
-  void Verify();
+  virtual void Verify();
   // Print the active semispace.
-  void Print() { to_space_->Print(); }
+  virtual void Print() { to_space_->Print(); }
 #endif
 
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
@@ -1341,22 +1366,18 @@
  public:
   // Creates an old space object with a given maximum capacity.
   // The constructor does not allocate pages from OS.
-  explicit OldSpace(int max_capacity, AllocationSpace id, bool executable)
+  explicit OldSpace(int max_capacity,
+                    AllocationSpace id,
+                    Executability executable)
       : PagedSpace(max_capacity, id, executable), free_list_(id) {
   }
 
-  // Returns maximum available bytes that the old space can have.
-  int MaxAvailable() {
-    return (MemoryAllocator::Available() / Page::kPageSize)
-           * Page::kObjectAreaSize;
-  }
-
   // The bytes available on the free list (ie, not above the linear allocation
   // pointer).
   int AvailableFree() { return free_list_.available(); }
 
   // The top of allocation in a page in this space. Undefined if page is unused.
-  Address PageAllocationTop(Page* page) {
+  virtual Address PageAllocationTop(Page* page) {
     return page == TopPageOf(allocation_info_) ? top() : page->ObjectAreaEnd();
   }
 
@@ -1370,7 +1391,7 @@
 
   // Prepare for full garbage collection.  Resets the relocation pointer and
   // clears the free list.
-  void PrepareForMarkCompact(bool will_compact);
+  virtual void PrepareForMarkCompact(bool will_compact);
 
   // Adjust the top of relocation pointer to point to the end of the object
   // given by 'address' and 'size_in_bytes'.  Move it to the next page if
@@ -1380,11 +1401,11 @@
 
   // Updates the allocation pointer to the relocation top after a mark-compact
   // collection.
-  void MCCommitRelocationInfo();
+  virtual void MCCommitRelocationInfo();
 
 #ifdef DEBUG
   // Verify integrity of this space.
-  void Verify();
+  virtual void Verify();
 
   // Reports statistics for the space
   void ReportStatistics();
@@ -1420,14 +1441,10 @@
  public:
   // Creates a map space object with a maximum capacity.
   explicit MapSpace(int max_capacity, AllocationSpace id)
-      : PagedSpace(max_capacity, id, false), free_list_(id) { }
-
-  // The bytes available on the free list (ie, not above the linear allocation
-  // pointer).
-  int AvailableFree() { return free_list_.available(); }
+      : PagedSpace(max_capacity, id, NOT_EXECUTABLE), free_list_(id) { }
 
   // The top of allocation in a page in this space. Undefined if page is unused.
-  Address PageAllocationTop(Page* page) {
+  virtual Address PageAllocationTop(Page* page) {
     return page == TopPageOf(allocation_info_) ? top()
         : page->ObjectAreaEnd() - kPageExtra;
   }
@@ -1442,15 +1459,15 @@
   Address PageAddress(int page_index) { return page_addresses_[page_index]; }
 
   // Prepares for a mark-compact GC.
-  void PrepareForMarkCompact(bool will_compact);
+  virtual void PrepareForMarkCompact(bool will_compact);
 
   // Updates the allocation pointer to the relocation top after a mark-compact
   // collection.
-  void MCCommitRelocationInfo();
+  virtual void MCCommitRelocationInfo();
 
 #ifdef DEBUG
   // Verify integrity of this space.
-  void Verify();
+  virtual void Verify();
 
   // Reports statistic info of the space
   void ReportStatistics();
@@ -1490,7 +1507,6 @@
 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset).
 // A large object always starts at Page::kObjectStartOffset to a page.
 // Large objects do not move during garbage collections.
-//
 
 // A LargeObjectChunk holds exactly one large object page with exactly one
 // large object.
@@ -1503,7 +1519,7 @@
   // parameter chunk_size.
   static LargeObjectChunk* New(int size_in_bytes,
                                size_t* chunk_size,
-                               bool executable);
+                               Executability executable);
 
   // Interpret a raw address as a large object chunk.
   static LargeObjectChunk* FromAddress(Address address) {
@@ -1553,7 +1569,8 @@
 class LargeObjectSpace : public Space {
   friend class LargeObjectIterator;
  public:
-  explicit LargeObjectSpace(AllocationSpace id, bool executable);
+  explicit LargeObjectSpace(AllocationSpace id);
+  virtual ~LargeObjectSpace() {}
 
   // Initializes internal data structures.
   bool Setup();
@@ -1561,8 +1578,10 @@
   // Releases internal resources, frees objects in this space.
   void TearDown();
 
-  // Allocates a (non-FixedArray) large object.
+  // Allocates a (non-FixedArray, non-Code) large object.
   Object* AllocateRaw(int size_in_bytes);
+  // Allocates a large Code object.
+  Object* AllocateRawCode(int size_in_bytes);
   // Allocates a large FixedArray.
   Object* AllocateRawFixedArray(int size_in_bytes);
 
@@ -1572,7 +1591,7 @@
     return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available());
   }
 
-  int Size() {
+  virtual int Size() {
     return size_;
   }
 
@@ -1601,8 +1620,8 @@
   bool IsEmpty() { return first_chunk_ == NULL; }
 
 #ifdef DEBUG
-  void Verify();
-  void Print();
+  virtual void Verify();
+  virtual void Print();
   void ReportStatistics();
   void CollectCodeStatistics();
   // Dump the remembered sets in the space to stdout.
@@ -1619,8 +1638,11 @@
   int page_count_;  // number of chunks
 
 
-  // Shared implementation of AllocateRaw and AllocateRawFixedArray.
-  Object* AllocateRawInternal(int requested_size, int object_size);
+  // Shared implementation of AllocateRaw, AllocateRawCode and
+  // AllocateRawFixedArray.
+  Object* AllocateRawInternal(int requested_size,
+                              int object_size,
+                              Executability executable);
 
   // Returns the number of extra bytes (rounded up to the nearest full word)
   // required for extra_object_bytes of extra pointers (in bytes).
diff --git a/src/string-stream.cc b/src/string-stream.cc
index 84011db..55dc402 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/string-stream.h b/src/string-stream.h
index b00c7cc..9cff319 100644
--- a/src/string-stream.h
+++ b/src/string-stream.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/string.js b/src/string.js
index 7e5cf6e..da9ba6a 100644
--- a/src/string.js
+++ b/src/string.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/stub-cache-arm.cc b/src/stub-cache-arm.cc
index 91d9140..f911f4b 100644
--- a/src/stub-cache-arm.cc
+++ b/src/stub-cache-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/stub-cache-ia32.cc b/src/stub-cache-ia32.cc
index 4c84160..89dccbe 100644
--- a/src/stub-cache-ia32.cc
+++ b/src/stub-cache-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 6c5625b..84272a2 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 0f48310..1b47f85 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/token.cc b/src/token.cc
index a737848..3f92707 100644
--- a/src/token.cc
+++ b/src/token.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/token.h b/src/token.h
index d053dec..0f194a3 100644
--- a/src/token.h
+++ b/src/token.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/top.cc b/src/top.cc
index 94e4cc8..061b300 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -79,6 +79,7 @@
        block != NULL;
        block = block->next_) {
     VISIT(reinterpret_cast<Object*&>(block->exception_));
+    VISIT(reinterpret_cast<Object*&>(block->message_));
   }
 
   // Iterate over pointers on native execution stack.
@@ -671,39 +672,35 @@
 }
 
 
+void Top::ComputeLocation(MessageLocation* target) {
+  *target = MessageLocation(empty_script(), -1, -1);
+  StackTraceFrameIterator it;
+  if (!it.done()) {
+    JavaScriptFrame* frame = it.frame();
+    JSFunction* fun = JSFunction::cast(frame->function());
+    Object* script = fun->shared()->script();
+    if (script->IsScript() &&
+        !(Script::cast(script)->source()->IsUndefined())) {
+      int pos = frame->FindCode()->SourcePosition(frame->pc());
+      // Compute the location from the function and the reloc info.
+      Handle<Script> casted_script(Script::cast(script));
+      *target = MessageLocation(casted_script, pos, pos + 1);
+    }
+  }
+}
+
+
 void Top::ReportUncaughtException(Handle<Object> exception,
                                   MessageLocation* location,
                                   Handle<String> stack_trace) {
-  MessageLocation computed_location(empty_script(), -1, -1);
-  if (location == NULL) {
-    location = &computed_location;
-
-    StackTraceFrameIterator it;
-    if (!it.done()) {
-      JavaScriptFrame* frame = it.frame();
-      JSFunction* fun = JSFunction::cast(frame->function());
-      Object* script = fun->shared()->script();
-      if (script->IsScript() &&
-          !(Script::cast(script)->source()->IsUndefined())) {
-        int pos = frame->FindCode()->SourcePosition(frame->pc());
-        // Compute the location from the function and the reloc info.
-        Handle<Script> casted_script(Script::cast(script));
-        computed_location = MessageLocation(casted_script, pos, pos + 1);
-      }
-    }
-  }
+  Handle<Object> message =
+    MessageHandler::MakeMessageObject("uncaught_exception",
+                                      location,
+                                      HandleVector<Object>(&exception, 1),
+                                      stack_trace);
 
   // Report the uncaught exception.
-  MessageHandler::ReportMessage("uncaught_exception",
-                                location,
-                                HandleVector<Object>(&exception, 1));
-
-  // Optionally, report the stack trace separately.
-  if (!stack_trace.is_null()) {
-    MessageHandler::ReportMessage("stack_trace",
-                                  location,
-                                  HandleVector<String>(&stack_trace, 1));
-  }
+  MessageHandler::ReportMessage(location, message);
 }
 
 
@@ -771,12 +768,32 @@
     ShouldReportException(&is_caught_externally);
   if (is_rethrow) report_exception = false;
 
+  Handle<Object> message_obj;
+  MessageLocation potential_computed_location;
+  bool try_catch_needs_message =
+    is_caught_externally && thread_local_.try_catch_handler_->capture_message_;
+  if (report_exception || try_catch_needs_message) {
+    if (location == NULL) {
+      // If no location was specified we use a computed one instead
+      ComputeLocation(&potential_computed_location);
+      location = &potential_computed_location;
+    }
+    Handle<String> stack_trace;
+    if (FLAG_trace_exception) stack_trace = StackTrace();
+    message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
+        location, HandleVector<Object>(&exception_handle, 1), stack_trace);
+  }
+
   // If the exception is caught externally, we store it in the
   // try/catch handler. The C code can find it later and process it if
   // necessary.
   if (is_caught_externally) {
     thread_local_.try_catch_handler_->exception_ =
       reinterpret_cast<void*>(*exception_handle);
+    if (!message_obj.is_null()) {
+      thread_local_.try_catch_handler_->message_ =
+        reinterpret_cast<void*>(*message_obj);
+    }
   }
 
   // Notify debugger of exception.
@@ -786,9 +803,7 @@
     if (message != NULL) {
       MessageHandler::ReportMessage(message);
     } else {
-      Handle<String> stack_trace;
-      if (FLAG_trace_exception) stack_trace = StackTrace();
-      ReportUncaughtException(exception_handle, location, stack_trace);
+      MessageHandler::ReportMessage(location, message_obj);
     }
   }
   thread_local_.external_caught_exception_ = is_caught_externally;
diff --git a/src/top.h b/src/top.h
index fffdb8a..1937493 100644
--- a/src/top.h
+++ b/src/top.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -226,6 +226,10 @@
                                       MessageLocation* location,
                                       Handle<String> stack_trace);
 
+  // Attempts to compute the current source location, storing the
+  // result in the target out parameter.
+  static void ComputeLocation(MessageLocation* target);
+
   // Override command line flag.
   static void TraceException(bool flag);
 
diff --git a/src/unicode-inl.h b/src/unicode-inl.h
index 7f843d0..9737c27 100644
--- a/src/unicode-inl.h
+++ b/src/unicode-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/unicode.cc b/src/unicode.cc
index ffe43ad..50dc92f 100644
--- a/src/unicode.cc
+++ b/src/unicode.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// This file was generated at 2008-06-12 16:11:05.556081
+// This file was generated at 2008-09-08 11:13:45.862026
 
 #include "unicode-inl.h"
 #include <cstdlib>
@@ -380,18 +380,18 @@
 
 // Letter:               point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo' ]
 
-static const uint16_t kLetterTable0Size = 475;
-static const uint16_t kLetterTable0[475] = { 32833, 90, 32865, 122, 170, 181, 186, 32960, 214, 32984, 246, 33016, 705, 33478, 721, 33504, 740, 750, 33658, 893, 902, 33672, 906, 908, 33678, 929, 33699, 974, 33744, 1013, 33783, 1153, 33930, 1299, 34097, 1366, 1369, 34145, 1415, 34256, 1514, 34288, 1522, 34337, 1594, 34368, 1610, 34414, 1647, 34417, 1747, 1749, 34533, 1766, 34542, 1775, 34554, 1788, 1791, 1808, 34578, 1839, 34637, 1901, 34688, 1957, 1969, 34762, 2026, 34804, 2037, 2042, 35076, 2361, 2365, 2384, 35160, 2401, 35195, 2431, 35205, 2444, 35215, 2448, 35219, 2472, 35242, 2480, 2482, 35254, 2489, 2493, 2510, 35292, 2525, 35295, 2529, 35312, 2545, 35333, 2570, 35343, 2576, 35347, 2600, 35370, 2608, 35378, 2611, 35381, 2614, 35384, 2617, 35417, 2652, 2654, 35442, 2676, 35461, 2701, 35471, 2705, 35475, 2728, 35498, 2736, 35506, 2739, 35509, 2745, 2749, 2768, 35552, 2785, 35589, 2828, 35599, 2832, 35603, 2856, 35626, 2864, 35634, 2867, 35637, 2873, 2877, 35676, 2909, 35679, 2913, 2929, 2947, 35717, 2954, 35726, 2960, 35730, 2965, 35737, 2970, 2972, 35742, 2975, 35747, 2980, 35752, 2986, 35758, 3001, 35845, 3084, 35854, 3088, 35858, 3112, 35882, 3123, 35893, 3129, 35936, 3169, 35973, 3212, 35982, 3216, 35986, 3240, 36010, 3251, 36021, 3257, 3261, 3294, 36064, 3297, 36101, 3340, 36110, 3344, 36114, 3368, 36138, 3385, 36192, 3425, 36229, 3478, 36250, 3505, 36275, 3515, 3517, 36288, 3526, 36353, 3632, 36402, 3635, 36416, 3654, 36481, 3714, 3716, 36487, 3720, 3722, 3725, 36500, 3735, 36505, 3743, 36513, 3747, 3749, 3751, 36522, 3755, 36525, 3760, 36530, 3763, 3773, 36544, 3780, 3782, 36572, 3805, 3840, 36672, 3911, 36681, 3946, 36744, 3979, 36864, 4129, 36899, 4135, 36905, 4138, 36944, 4181, 37024, 4293, 37072, 4346, 4348, 37120, 4441, 37215, 4514, 37288, 4601, 37376, 4680, 37450, 4685, 37456, 4694, 4696, 37466, 4701, 37472, 4744, 37514, 4749, 37520, 4784, 37554, 4789, 37560, 4798, 4800, 37570, 4805, 37576, 4822, 37592, 4880, 37650, 4885, 37656, 4954, 37760, 5007, 37792, 5108, 37889, 5740, 38511, 5750, 38529, 5786, 38560, 5866, 38656, 5900, 38670, 5905, 38688, 5937, 38720, 5969, 38752, 5996, 38766, 6000, 38784, 6067, 6103, 6108, 38944, 6263, 39040, 6312, 39168, 6428, 39248, 6509, 39280, 6516, 39296, 6569, 39361, 6599, 39424, 6678, 39685, 6963, 39749, 6987, 40192, 7615, 40448, 7835, 40608, 7929, 40704, 7957, 40728, 7965, 40736, 8005, 40776, 8013, 40784, 8023, 8025, 8027, 8029, 40799, 8061, 40832, 8116, 40886, 8124, 8126, 40898, 8132, 40902, 8140, 40912, 8147, 40918, 8155, 40928, 8172, 40946, 8180, 40950, 8188, 8305, 8319, 41104, 8340, 8450, 8455, 41226, 8467, 8469, 41241, 8477, 8484, 8486, 8488, 41258, 8493, 41263, 8505, 41276, 8511, 41285, 8521, 8526, 41347, 8580, 44032, 11310, 44080, 11358, 44128, 11372, 44148, 11383, 44160, 11492, 44288, 11557, 44336, 11621, 11631, 44416, 11670, 44448, 11686, 44456, 11694, 44464, 11702, 44472, 11710, 44480, 11718, 44488, 11726, 44496, 11734, 44504, 11742, 45061, 12294, 45105, 12341, 45115, 12348, 45121, 12438, 45213, 12447, 45217, 12538, 45308, 12543, 45317, 12588, 45361, 12686, 45472, 12727, 45552, 12799, 13312, 19893, 19968 }; // NOLINT
-static const uint16_t kLetterTable1Size = 67;
-static const uint16_t kLetterTable1[67] = { 8123, 40960, 9356, 42775, 10010, 43008, 10241, 43011, 10245, 43015, 10250, 43020, 10274, 43072, 10355, 11264, 22435, 63744, 31277, 64048, 31338, 64112, 31449, 64256, 31494, 64275, 31511, 31517, 64287, 31528, 64298, 31542, 64312, 31548, 31550, 64320, 31553, 64323, 31556, 64326, 31665, 64467, 32061, 64848, 32143, 64914, 32199, 65008, 32251, 65136, 32372, 65142, 32508, 65313, 32570, 65345, 32602, 65382, 32702, 65474, 32711, 65482, 32719, 65490, 32727, 65498, 32732 }; // NOLINT
+static const uint16_t kLetterTable0Size = 476;
+static const uint16_t kLetterTable0[476] = { 32833, 90, 32865, 122, 170, 181, 186, 32960, 214, 32984, 246, 33016, 705, 33478, 721, 33504, 740, 750, 33658, 893, 902, 33672, 906, 908, 33678, 929, 33699, 974, 33744, 1013, 33783, 1153, 33930, 1299, 34097, 1366, 1369, 34145, 1415, 34256, 1514, 34288, 1522, 34337, 1594, 34368, 1610, 34414, 1647, 34417, 1747, 1749, 34533, 1766, 34542, 1775, 34554, 1788, 1791, 1808, 34578, 1839, 34637, 1901, 34688, 1957, 1969, 34762, 2026, 34804, 2037, 2042, 35076, 2361, 2365, 2384, 35160, 2401, 35195, 2431, 35205, 2444, 35215, 2448, 35219, 2472, 35242, 2480, 2482, 35254, 2489, 2493, 2510, 35292, 2525, 35295, 2529, 35312, 2545, 35333, 2570, 35343, 2576, 35347, 2600, 35370, 2608, 35378, 2611, 35381, 2614, 35384, 2617, 35417, 2652, 2654, 35442, 2676, 35461, 2701, 35471, 2705, 35475, 2728, 35498, 2736, 35506, 2739, 35509, 2745, 2749, 2768, 35552, 2785, 35589, 2828, 35599, 2832, 35603, 2856, 35626, 2864, 35634, 2867, 35637, 2873, 2877, 35676, 2909, 35679, 2913, 2929, 2947, 35717, 2954, 35726, 2960, 35730, 2965, 35737, 2970, 2972, 35742, 2975, 35747, 2980, 35752, 2986, 35758, 3001, 35845, 3084, 35854, 3088, 35858, 3112, 35882, 3123, 35893, 3129, 35936, 3169, 35973, 3212, 35982, 3216, 35986, 3240, 36010, 3251, 36021, 3257, 3261, 3294, 36064, 3297, 36101, 3340, 36110, 3344, 36114, 3368, 36138, 3385, 36192, 3425, 36229, 3478, 36250, 3505, 36275, 3515, 3517, 36288, 3526, 36353, 3632, 36402, 3635, 36416, 3654, 36481, 3714, 3716, 36487, 3720, 3722, 3725, 36500, 3735, 36505, 3743, 36513, 3747, 3749, 3751, 36522, 3755, 36525, 3760, 36530, 3763, 3773, 36544, 3780, 3782, 36572, 3805, 3840, 36672, 3911, 36681, 3946, 36744, 3979, 36864, 4129, 36899, 4135, 36905, 4138, 36944, 4181, 37024, 4293, 37072, 4346, 4348, 37120, 4441, 37215, 4514, 37288, 4601, 37376, 4680, 37450, 4685, 37456, 4694, 4696, 37466, 4701, 37472, 4744, 37514, 4749, 37520, 4784, 37554, 4789, 37560, 4798, 4800, 37570, 4805, 37576, 4822, 37592, 4880, 37650, 4885, 37656, 4954, 37760, 5007, 37792, 5108, 37889, 5740, 38511, 5750, 38529, 5786, 38560, 5866, 38656, 5900, 38670, 5905, 38688, 5937, 38720, 5969, 38752, 5996, 38766, 6000, 38784, 6067, 6103, 6108, 38944, 6263, 39040, 6312, 39168, 6428, 39248, 6509, 39280, 6516, 39296, 6569, 39361, 6599, 39424, 6678, 39685, 6963, 39749, 6987, 40192, 7615, 40448, 7835, 40608, 7929, 40704, 7957, 40728, 7965, 40736, 8005, 40776, 8013, 40784, 8023, 8025, 8027, 8029, 40799, 8061, 40832, 8116, 40886, 8124, 8126, 40898, 8132, 40902, 8140, 40912, 8147, 40918, 8155, 40928, 8172, 40946, 8180, 40950, 8188, 8305, 8319, 41104, 8340, 8450, 8455, 41226, 8467, 8469, 41241, 8477, 8484, 8486, 8488, 41258, 8493, 41263, 8505, 41276, 8511, 41285, 8521, 8526, 41347, 8580, 44032, 11310, 44080, 11358, 44128, 11372, 44148, 11383, 44160, 11492, 44288, 11557, 44336, 11621, 11631, 44416, 11670, 44448, 11686, 44456, 11694, 44464, 11702, 44472, 11710, 44480, 11718, 44488, 11726, 44496, 11734, 44504, 11742, 45061, 12294, 45105, 12341, 45115, 12348, 45121, 12438, 45213, 12447, 45217, 12538, 45308, 12543, 45317, 12588, 45361, 12686, 45472, 12727, 45552, 12799, 46080, 19893, 52736, 32767 }; // NOLINT
+static const uint16_t kLetterTable1Size = 68;
+static const uint16_t kLetterTable1[68] = { 32768, 8123, 40960, 9356, 42775, 10010, 43008, 10241, 43011, 10245, 43015, 10250, 43020, 10274, 43072, 10355, 44032, 22435, 63744, 31277, 64048, 31338, 64112, 31449, 64256, 31494, 64275, 31511, 31517, 64287, 31528, 64298, 31542, 64312, 31548, 31550, 64320, 31553, 64323, 31556, 64326, 31665, 64467, 32061, 64848, 32143, 64914, 32199, 65008, 32251, 65136, 32372, 65142, 32508, 65313, 32570, 65345, 32602, 65382, 32702, 65474, 32711, 65482, 32719, 65490, 32727, 65498, 32732 }; // NOLINT
 static const uint16_t kLetterTable2Size = 48;
 static const uint16_t kLetterTable2[48] = { 32768, 11, 32781, 38, 32808, 58, 32828, 61, 32831, 77, 32848, 93, 32896, 250, 33536, 798, 33584, 832, 33602, 841, 33664, 925, 33696, 963, 33736, 975, 33792, 1181, 34816, 2053, 2056, 34826, 2101, 34871, 2104, 2108, 2111, 35072, 2325, 2560, 35344, 2579, 35349, 2583, 35353, 2611, 40960, 9070 }; // NOLINT
 static const uint16_t kLetterTable3Size = 57;
 static const uint16_t kLetterTable3[57] = { 54272, 21588, 54358, 21660, 54430, 21663, 21666, 54437, 21670, 54441, 21676, 54446, 21689, 21691, 54461, 21699, 54469, 21765, 54535, 21770, 54541, 21780, 54550, 21788, 54558, 21817, 54587, 21822, 54592, 21828, 21830, 54602, 21840, 54610, 22181, 54952, 22208, 54978, 22234, 55004, 22266, 55036, 22292, 55062, 22324, 55094, 22350, 55120, 22382, 55152, 22408, 55178, 22440, 55210, 22466, 55236, 22475 }; // NOLINT
-static const uint16_t kLetterTable4Size = 1;
-static const uint16_t kLetterTable4[1] = { 0 }; // NOLINT
-static const uint16_t kLetterTable5Size = 3;
-static const uint16_t kLetterTable5[3] = { 9942, 63488, 31261 }; // NOLINT
+static const uint16_t kLetterTable4Size = 2;
+static const uint16_t kLetterTable4[2] = { 32768, 32767 }; // NOLINT
+static const uint16_t kLetterTable5Size = 4;
+static const uint16_t kLetterTable5[4] = { 32768, 9942, 63488, 31261 }; // NOLINT
 bool Letter::Is(uchar c) {
   int chunk_index = c >> 15;
   switch (chunk_index) {
@@ -505,14 +505,14 @@
 
 // Ideographic:          'Id' in point.properties
 
-static const uint16_t kIdeographicTable0Size = 9;
-static const uint16_t kIdeographicTable0[9] = { 45062, 12295, 45089, 12329, 45112, 12346, 13312, 19893, 19968 }; // NOLINT
-static const uint16_t kIdeographicTable1Size = 5;
-static const uint16_t kIdeographicTable1[5] = { 8123, 63744, 31277, 64112, 31449 }; // NOLINT
-static const uint16_t kIdeographicTable4Size = 1;
-static const uint16_t kIdeographicTable4[1] = { 0 }; // NOLINT
-static const uint16_t kIdeographicTable5Size = 3;
-static const uint16_t kIdeographicTable5[3] = { 9942, 63488, 31261 }; // NOLINT
+static const uint16_t kIdeographicTable0Size = 10;
+static const uint16_t kIdeographicTable0[10] = { 45062, 12295, 45089, 12329, 45112, 12346, 46080, 19893, 52736, 32767 }; // NOLINT
+static const uint16_t kIdeographicTable1Size = 6;
+static const uint16_t kIdeographicTable1[6] = { 32768, 8123, 63744, 31277, 64112, 31449 }; // NOLINT
+static const uint16_t kIdeographicTable4Size = 2;
+static const uint16_t kIdeographicTable4[2] = { 32768, 32767 }; // NOLINT
+static const uint16_t kIdeographicTable5Size = 4;
+static const uint16_t kIdeographicTable5[4] = { 32768, 9942, 63488, 31261 }; // NOLINT
 bool Ideographic::Is(uchar c) {
   int chunk_index = c >> 15;
   switch (chunk_index) {
diff --git a/src/unicode.h b/src/unicode.h
index cc120b6..804671b 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/uri.js b/src/uri.js
index 270a0f8..147110e 100644
--- a/src/uri.js
+++ b/src/uri.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/usage-analyzer.cc b/src/usage-analyzer.cc
index 231a8e4..0f234d8 100644
--- a/src/usage-analyzer.cc
+++ b/src/usage-analyzer.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/usage-analyzer.h b/src/usage-analyzer.h
index de7e4f9..2732dd5 100644
--- a/src/usage-analyzer.h
+++ b/src/usage-analyzer.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/utils.cc b/src/utils.cc
index 48ccc31..8cfa237 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -104,7 +104,7 @@
   char line_buf[256];
   int offset = 0;
   bool keep_going = true;
-  fprintf(stdout, prompt);
+  fprintf(stdout, "%s", prompt);
   fflush(stdout);
   while (keep_going) {
     if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
diff --git a/src/utils.h b/src/utils.h
index e7d5633..1c07ba4 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/v8-counters.cc b/src/v8-counters.cc
index e350d90..f6b1c3d 100644
--- a/src/v8-counters.cc
+++ b/src/v8-counters.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 566ed54..76c2ec8 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Google Inc. All Rights Reserved.
+// Copyright 2007-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -71,6 +71,8 @@
   SC(call_normal_stubs, V8.CallNormalStubs)                      \
   SC(call_megamorphic_stubs, V8.CallMegamorphicStubs)            \
   SC(arguments_adaptors, V8.ArgumentsAdaptors)                   \
+  SC(eval_cache_hits, V8.EvalCacheHits)                          \
+  SC(eval_cache_misses, V8.EvalCacheMisses)                      \
   /* Amount of evaled source code. */                            \
   SC(total_eval_size, V8.TotalEvalSize)                          \
   /* Amount of loaded source code. */                            \
diff --git a/src/v8.cc b/src/v8.cc
index 7a631fe..4a7dc6f 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/v8.h b/src/v8.h
index c439006..acdb119 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google, Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/v8natives.js b/src/v8natives.js
index 5ead3ad..d59cc4b 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2007 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/v8threads.cc b/src/v8threads.cc
index 89c7918..2b4a027 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -54,11 +54,9 @@
 }
 
 
-#ifdef DEBUG
-void Locker::AssertIsLocked() {
-  ASSERT(internal::ThreadManager::IsLockedByCurrentThread());
+bool Locker::IsLocked() {
+  return internal::ThreadManager::IsLockedByCurrentThread();
 }
-#endif
 
 
 Locker::~Locker() {
@@ -282,7 +280,7 @@
 
 
 void ContextSwitcher::StartPreemption(int every_n_ms) {
-  Locker::AssertIsLocked();
+  ASSERT(Locker::IsLocked());
   if (switcher == NULL) {
     switcher = new ContextSwitcher(every_n_ms);
     switcher->Start();
@@ -293,7 +291,7 @@
 
 
 void ContextSwitcher::StopPreemption() {
-  Locker::AssertIsLocked();
+  ASSERT(Locker::IsLocked());
   if (switcher != NULL) {
     switcher->Stop();
     delete(switcher);
@@ -312,7 +310,7 @@
 
 
 void ContextSwitcher::Stop() {
-  Locker::AssertIsLocked();
+  ASSERT(Locker::IsLocked());
   keep_going_ = false;
   preemption_semaphore_->Signal();
   Join();
@@ -325,7 +323,7 @@
 
 
 void ContextSwitcher::PreemptionReceived() {
-  Locker::AssertIsLocked();
+  ASSERT(Locker::IsLocked());
   switcher->preemption_semaphore_->Signal();
 }
 
diff --git a/src/v8threads.h b/src/v8threads.h
index f481d9d..f5c844d 100644
--- a/src/v8threads.h
+++ b/src/v8threads.h
@@ -1,4 +1,4 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/variables.cc b/src/variables.cc
index 1784800..d57ec1b 100644
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/variables.h b/src/variables.h
index bdc6934..6a4b3c5 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/zone-inl.h b/src/zone-inl.h
index fadbbc5..7ed4e6b 100644
--- a/src/zone-inl.h
+++ b/src/zone-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/zone.cc b/src/zone.cc
index ed443d8..d37f4f7 100644
--- a/src/zone.cc
+++ b/src/zone.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
diff --git a/src/zone.h b/src/zone.h
index 336fd34..c7129ec 100644
--- a/src/zone.h
+++ b/src/zone.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met: