Update V8 to r4730 as required by WebKit r60469
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 2cf0b12..876c104 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -71,6 +71,7 @@
     'test-strings.cc',
     'test-threads.cc',
     'test-thread-termination.cc',
+    'test-unbound-queue.cc',
     'test-utils.cc',
     'test-version.cc'
   ],
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index ea9e6e1..46eaccd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -76,6 +76,11 @@
 }
 
 
+static void ExpectTrue(const char* code) {
+  ExpectBoolean(code, true);
+}
+
+
 static void ExpectObject(const char* code, Local<Value> expected) {
   Local<Value> result = CompileRun(code);
   CHECK(result->Equals(expected));
@@ -2506,7 +2511,7 @@
 
   // Uses getOwnPropertyDescriptor to check the configurable status
   Local<Script> script_desc
-    = Script::Compile(v8_str("var prop =Object.getOwnPropertyDescriptor( "
+    = Script::Compile(v8_str("var prop = Object.getOwnPropertyDescriptor( "
                              "obj, 'x');"
                              "prop.configurable;"));
   Local<Value> result = script_desc->Run();
@@ -2592,8 +2597,167 @@
 }
 
 
+static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context,
+                                                char const* name) {
+  return v8::Handle<v8::Object>::Cast((*context)->Global()->Get(v8_str(name)));
+}
 
 
+THREADED_TEST(DefineAPIAccessorOnObject) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  LocalContext context;
+
+  context->Global()->Set(v8_str("obj1"), templ->NewInstance());
+  CompileRun("var obj2 = {};");
+
+  CHECK(CompileRun("obj1.x")->IsUndefined());
+  CHECK(CompileRun("obj2.x")->IsUndefined());
+
+  CHECK(GetGlobalProperty(&context, "obj1")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+
+  ExpectString("obj1.x", "x");
+  CHECK(CompileRun("obj2.x")->IsUndefined());
+
+  CHECK(GetGlobalProperty(&context, "obj2")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+
+  ExpectString("obj1.x", "x");
+  ExpectString("obj2.x", "x");
+
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
+
+  CompileRun("Object.defineProperty(obj1, 'x',"
+             "{ get: function() { return 'y'; }, configurable: true })");
+
+  ExpectString("obj1.x", "y");
+  ExpectString("obj2.x", "x");
+
+  CompileRun("Object.defineProperty(obj2, 'x',"
+             "{ get: function() { return 'y'; }, configurable: true })");
+
+  ExpectString("obj1.x", "y");
+  ExpectString("obj2.x", "y");
+
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
+
+  CHECK(GetGlobalProperty(&context, "obj1")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+  CHECK(GetGlobalProperty(&context, "obj2")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+
+  ExpectString("obj1.x", "x");
+  ExpectString("obj2.x", "x");
+
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
+  ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
+
+  // Define getters/setters, but now make them not configurable.
+  CompileRun("Object.defineProperty(obj1, 'x',"
+             "{ get: function() { return 'z'; }, configurable: false })");
+  CompileRun("Object.defineProperty(obj2, 'x',"
+             "{ get: function() { return 'z'; }, configurable: false })");
+
+  ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
+  ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
+
+  ExpectString("obj1.x", "z");
+  ExpectString("obj2.x", "z");
+
+  CHECK(!GetGlobalProperty(&context, "obj1")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+  CHECK(!GetGlobalProperty(&context, "obj2")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+
+  ExpectString("obj1.x", "z");
+  ExpectString("obj2.x", "z");
+}
+
+
+THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  LocalContext context;
+
+  context->Global()->Set(v8_str("obj1"), templ->NewInstance());
+  CompileRun("var obj2 = {};");
+
+  CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor(
+        v8_str("x"),
+        GetXValue, NULL,
+        v8_str("donut"), v8::DEFAULT, v8::DontDelete));
+  CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor(
+        v8_str("x"),
+        GetXValue, NULL,
+        v8_str("donut"), v8::DEFAULT, v8::DontDelete));
+
+  ExpectString("obj1.x", "x");
+  ExpectString("obj2.x", "x");
+
+  ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
+  ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
+
+  CHECK(!GetGlobalProperty(&context, "obj1")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+  CHECK(!GetGlobalProperty(&context, "obj2")->
+      SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
+
+  {
+    v8::TryCatch try_catch;
+    CompileRun("Object.defineProperty(obj1, 'x',"
+        "{get: function() { return 'func'; }})");
+    CHECK(try_catch.HasCaught());
+    String::AsciiValue exception_value(try_catch.Exception());
+    CHECK_EQ(*exception_value,
+            "TypeError: Cannot redefine property: defineProperty");
+  }
+  {
+    v8::TryCatch try_catch;
+    CompileRun("Object.defineProperty(obj2, 'x',"
+        "{get: function() { return 'func'; }})");
+    CHECK(try_catch.HasCaught());
+    String::AsciiValue exception_value(try_catch.Exception());
+    CHECK_EQ(*exception_value,
+            "TypeError: Cannot redefine property: defineProperty");
+  }
+}
+
+
+static v8::Handle<Value> Get239Value(Local<String> name,
+                                     const AccessorInfo& info) {
+  ApiTestFuzzer::Fuzz();
+  CHECK_EQ(info.Data(), v8_str("donut"));
+  CHECK_EQ(name, v8_str("239"));
+  return name;
+}
+
+
+THREADED_TEST(ElementAPIAccessor) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  LocalContext context;
+
+  context->Global()->Set(v8_str("obj1"), templ->NewInstance());
+  CompileRun("var obj2 = {};");
+
+  CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor(
+        v8_str("239"),
+        Get239Value, NULL,
+        v8_str("donut")));
+  CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor(
+        v8_str("239"),
+        Get239Value, NULL,
+        v8_str("donut")));
+
+  ExpectString("obj1[239]", "239");
+  ExpectString("obj2[239]", "239");
+  ExpectString("obj1['239']", "239");
+  ExpectString("obj2['239']", "239");
+}
+
 
 v8::Persistent<Value> xValue;
 
@@ -8003,8 +8167,8 @@
   // TODO(155): This test would break without the initialization of V8. This is
   // a workaround for now to make this test not fail.
   v8::V8::Initialize();
-  const char *script = "function foo(a) { return a+1; }";
-  v8::ScriptData *sd =
+  const char* script = "function foo(a) { return a+1; }";
+  v8::ScriptData* sd =
       v8::ScriptData::PreCompile(script, i::StrLength(script));
   CHECK_NE(sd->Length(), 0);
   CHECK_NE(sd->Data(), NULL);
@@ -8015,8 +8179,8 @@
 
 TEST(PreCompileWithError) {
   v8::V8::Initialize();
-  const char *script = "function foo(a) { return 1 * * 2; }";
-  v8::ScriptData *sd =
+  const char* script = "function foo(a) { return 1 * * 2; }";
+  v8::ScriptData* sd =
       v8::ScriptData::PreCompile(script, i::StrLength(script));
   CHECK(sd->HasError());
   delete sd;
@@ -8025,14 +8189,53 @@
 
 TEST(Regress31661) {
   v8::V8::Initialize();
-  const char *script = " The Definintive Guide";
-  v8::ScriptData *sd =
+  const char* script = " The Definintive Guide";
+  v8::ScriptData* sd =
       v8::ScriptData::PreCompile(script, i::StrLength(script));
   CHECK(sd->HasError());
   delete sd;
 }
 
 
+// Tests that ScriptData can be serialized and deserialized.
+TEST(PreCompileSerialization) {
+  v8::V8::Initialize();
+  const char* script = "function foo(a) { return a+1; }";
+  v8::ScriptData* sd =
+      v8::ScriptData::PreCompile(script, i::StrLength(script));
+
+  // Serialize.
+  int serialized_data_length = sd->Length();
+  char* serialized_data = i::NewArray<char>(serialized_data_length);
+  memcpy(serialized_data, sd->Data(), serialized_data_length);
+
+  // Deserialize.
+  v8::ScriptData* deserialized_sd =
+      v8::ScriptData::New(serialized_data, serialized_data_length);
+
+  // Verify that the original is the same as the deserialized.
+  CHECK_EQ(sd->Length(), deserialized_sd->Length());
+  CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length()));
+  CHECK_EQ(sd->HasError(), deserialized_sd->HasError());
+
+  delete sd;
+  delete deserialized_sd;
+}
+
+
+// Attempts to deserialize bad data.
+TEST(PreCompileDeserializationError) {
+  v8::V8::Initialize();
+  const char* data = "DONT CARE";
+  int invalid_size = 3;
+  v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size);
+
+  CHECK_EQ(0, sd->Length());
+
+  delete sd;
+}
+
+
 // This tests that we do not allow dictionary load/call inline caches
 // to use functions that have not yet been compiled.  The potential
 // problem of loading a function that has not yet been compiled can
diff --git a/test/cctest/test-circular-queue.cc b/test/cctest/test-circular-queue.cc
index 3fa49bf..ce9a42e 100644
--- a/test/cctest/test-circular-queue.cc
+++ b/test/cctest/test-circular-queue.cc
@@ -1,6 +1,6 @@
 // Copyright 2010 the V8 project authors. All rights reserved.
 //
-// Tests of circular queues.
+// Tests of the circular queue.
 
 #include "v8.h"
 #include "circular-queue-inl.h"
@@ -8,53 +8,9 @@
 
 namespace i = v8::internal;
 
-using i::CircularQueue;
 using i::SamplingCircularQueue;
 
 
-TEST(SingleRecordCircularQueue) {
-  typedef int Record;
-  CircularQueue<Record> cq(sizeof(Record) * 2);
-  CHECK(cq.IsEmpty());
-  cq.Enqueue(1);
-  CHECK(!cq.IsEmpty());
-  Record rec = 0;
-  cq.Dequeue(&rec);
-  CHECK_EQ(1, rec);
-  CHECK(cq.IsEmpty());
-}
-
-
-TEST(MultipleRecordsCircularQueue) {
-  typedef int Record;
-  const int kQueueSize = 10;
-  CircularQueue<Record> cq(sizeof(Record) * (kQueueSize + 1));
-  CHECK(cq.IsEmpty());
-  cq.Enqueue(1);
-  CHECK(!cq.IsEmpty());
-  for (int i = 2; i <= 5; ++i) {
-    cq.Enqueue(i);
-    CHECK(!cq.IsEmpty());
-  }
-  Record rec = 0;
-  for (int i = 1; i <= 4; ++i) {
-    CHECK(!cq.IsEmpty());
-    cq.Dequeue(&rec);
-    CHECK_EQ(i, rec);
-  }
-  for (int i = 6; i <= 12; ++i) {
-    cq.Enqueue(i);
-    CHECK(!cq.IsEmpty());
-  }
-  for (int i = 5; i <= 12; ++i) {
-    CHECK(!cq.IsEmpty());
-    cq.Dequeue(&rec);
-    CHECK_EQ(i, rec);
-  }
-  CHECK(cq.IsEmpty());
-}
-
-
 TEST(SamplingCircularQueue) {
   typedef SamplingCircularQueue::Cell Record;
   const int kRecordsPerChunk = 4;
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 6133cdb..f587fc8 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -114,7 +114,8 @@
   processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
   processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
   processor.CodeDeleteEvent(ToAddress(0x1600));
-  processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000));
+  processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000),
+                                CodeEntry::kNoSecurityToken);
   // Enqueue a tick event to enable code events processing.
   EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
 
@@ -176,7 +177,8 @@
 
   processor.Stop();
   processor.Join();
-  CpuProfile* profile = profiles.StopProfiling("", 1);
+  CpuProfile* profile =
+      profiles.StopProfiling(CodeEntry::kNoSecurityToken, "", 1);
   CHECK_NE(NULL, profile);
 
   // Check call trees.
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d90be8e..4b4c950 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -6196,7 +6196,28 @@
   v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
   v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
   CHECK_EQ(*context1, *context2);
-  // Make sure debugger is unloaded before running other tests.
-  v8::internal::ForceUnloadDebugger();
+}
+
+
+static v8::Handle<v8::Value> expected_callback_data;
+static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
+  CHECK(details.GetEventContext() == expected_context);
+  CHECK_EQ(expected_callback_data, details.GetCallbackData());
+}
+
+// Check that event details contain context where debug event occured.
+TEST(DebugEventContext) {
+  v8::HandleScope scope;
+  expected_callback_data = v8::Int32::New(2010);
+  v8::Debug::SetDebugEventListener2(DebugEventContextChecker,
+                                    expected_callback_data);
+  expected_context = v8::Context::New();
+  v8::Context::Scope context_scope(expected_context);
+  v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
+  expected_context.Dispose();
+  expected_context.Clear();
+  v8::Debug::SetDebugEventListener(NULL);
+  expected_context_data = v8::Handle<v8::Value>();
   CheckDebuggerUnloaded();
 }
+
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index 02e64b4..f94cd45 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -237,6 +237,7 @@
   __ cld();
   __ rep_movs();
   __ rep_stos();
+  __ stos();
 
   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
   __ sub(edx, Operand(ebx));
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index 4d9d759..6da1a75 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -66,28 +66,6 @@
 }
 
 
-static void CheckRetAddrIsInFunction(const char* func_name,
-                                     Address ret_addr,
-                                     Address func_start_addr,
-                                     unsigned int func_len) {
-  printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n",
-         func_name, func_start_addr, ret_addr, func_start_addr + func_len);
-  CHECK_GE(ret_addr, func_start_addr);
-  CHECK_GE(func_start_addr + func_len, ret_addr);
-}
-
-
-static void CheckRetAddrIsInJSFunction(const char* func_name,
-                                       Address ret_addr,
-                                       Handle<JSFunction> func) {
-  v8::internal::Code* func_code = func->code();
-  CheckRetAddrIsInFunction(
-      func_name, ret_addr,
-      func_code->instruction_start(),
-      func_code->ExecutableSize());
-}
-
-
 // --- T r a c e   E x t e n s i o n ---
 
 class TraceExtension : public v8::Extension {
@@ -209,11 +187,16 @@
 }
 
 
-static void CheckRetAddrIsInJSFunction(const char* func_name,
-                                               Address ret_addr) {
-  CheckRetAddrIsInJSFunction(func_name,
-                             ret_addr,
-                             GetGlobalJSFunction(func_name));
+static void CheckObjectIsJSFunction(const char* func_name,
+                                    Address addr) {
+  i::Object* obj = reinterpret_cast<i::Object*>(addr);
+  CHECK(obj->IsJSFunction());
+  CHECK(JSFunction::cast(obj)->shared()->name()->IsString());
+  i::SmartPointer<char> found_name =
+      i::String::cast(
+          JSFunction::cast(
+              obj)->shared()->name())->ToCString();
+  CHECK_EQ(func_name, *found_name);
 }
 
 
@@ -272,6 +255,7 @@
   Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
   CHECK(!func.is_null());
   i::FLAG_allow_natives_syntax = allow_natives_syntax;
+  func->shared()->set_name(*NewString(func_name));
 
 #ifdef DEBUG
   v8::internal::Code* func_code = func->code();
@@ -289,6 +273,11 @@
 // StackTracer uses Top::c_entry_fp as a starting point for stack
 // walking.
 TEST(CFromJSStackTrace) {
+  // TODO(711) The hack of replacing the inline runtime function
+  // RandomHeapNumber with GetFrameNumber does not work with the way the full
+  // compiler generates inline runtime calls.
+  i::FLAG_always_full_compiler = false;
+
   TickSample sample;
   InitTraceEnv(&sample);
 
@@ -313,10 +302,8 @@
   //           StackTracer::Trace
   CHECK_GT(sample.frames_count, 1);
   // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
-  CheckRetAddrIsInJSFunction("JSFuncDoTrace",
-                             sample.stack[0]);
-  CheckRetAddrIsInJSFunction("JSTrace",
-                             sample.stack[1]);
+  CheckObjectIsJSFunction("JSFuncDoTrace", sample.stack[0]);
+  CheckObjectIsJSFunction("JSTrace", sample.stack[1]);
 }
 
 
@@ -326,6 +313,11 @@
 // Top::c_entry_fp value. In this case, StackTracer uses passed frame
 // pointer value as a starting point for stack walking.
 TEST(PureJSStackTrace) {
+  // TODO(711) The hack of replacing the inline runtime function
+  // RandomHeapNumber with GetFrameNumber does not work with the way the full
+  // compiler generates inline runtime calls.
+  i::FLAG_always_full_compiler = false;
+
   TickSample sample;
   InitTraceEnv(&sample);
 
@@ -359,10 +351,8 @@
            sample.function);
   CHECK_GT(sample.frames_count, 1);
   // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
-  CheckRetAddrIsInJSFunction("JSTrace",
-                             sample.stack[0]);
-  CheckRetAddrIsInJSFunction("OuterJSTrace",
-                             sample.stack[1]);
+  CheckObjectIsJSFunction("JSTrace", sample.stack[0]);
+  CheckObjectIsJSFunction("OuterJSTrace", sample.stack[1]);
 }
 
 
diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc
index 8924ba7..dd97498 100755
--- a/test/cctest/test-macro-assembler-x64.cc
+++ b/test/cctest/test-macro-assembler-x64.cc
@@ -61,6 +61,7 @@
 using v8::internal::r13;
 using v8::internal::r14;
 using v8::internal::r15;
+using v8::internal::times_pointer_size;
 using v8::internal::FUNCTION_CAST;
 using v8::internal::CodeDesc;
 using v8::internal::less_equal;
@@ -75,6 +76,8 @@
 using v8::internal::Smi;
 using v8::internal::kSmiTagMask;
 using v8::internal::kSmiValueSize;
+using v8::internal::kPointerSize;
+using v8::internal::kIntSize;
 
 // Test the x64 assembler by compiling some simple functions into
 // a buffer and executing them.  These tests do not initialize the
@@ -2053,4 +2056,358 @@
 }
 
 
+TEST(OperandOffset) {
+  int data[256];
+  for (int i = 0; i < 256; i++) { data[i] = i * 0x01010101; }
+
+  // Allocate an executable page of memory.
+  size_t actual_size;
+  byte* buffer =
+      static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
+                                      &actual_size,
+                                      true));
+  CHECK(buffer);
+  HandleScope handles;
+  MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+
+  MacroAssembler* masm = &assembler;
+  masm->set_allow_stub_calls(false);
+  Label exit;
+
+  __ push(r12);
+  __ push(r13);
+  __ push(rbx);
+  __ push(rbp);
+  __ push(Immediate(0x100));  // <-- rbp
+  __ movq(rbp, rsp);
+  __ push(Immediate(0x101));
+  __ push(Immediate(0x102));
+  __ push(Immediate(0x103));
+  __ push(Immediate(0x104));
+  __ push(Immediate(0x105));  // <-- rbx
+  __ push(Immediate(0x106));
+  __ push(Immediate(0x107));
+  __ push(Immediate(0x108));
+  __ push(Immediate(0x109));  // <-- rsp
+  // rbp = rsp[9]
+  // r12 = rsp[3]
+  // rbx = rsp[5]
+  // r13 = rsp[7]
+  __ lea(r12, Operand(rsp, 3 * kPointerSize));
+  __ lea(r13, Operand(rbp, -3 * kPointerSize));
+  __ lea(rbx, Operand(rbp, -5 * kPointerSize));
+  __ movl(rcx, Immediate(2));
+  __ movq(r8, reinterpret_cast<uintptr_t>(&data[128]), RelocInfo::NONE);
+  __ movl(rax, Immediate(1));
+
+  Operand sp0 = Operand(rsp, 0);
+
+  // Test 1.
+  __ movl(rdx, sp0);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x109));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Test 2.
+  // Zero to non-zero displacement.
+  __ movl(rdx, Operand(sp0, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x107));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand sp2 = Operand(rsp, 2 * kPointerSize);
+
+  // Test 3.
+  __ movl(rdx, sp2);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x107));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(sp2, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x105));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Non-zero to zero displacement.
+  __ movl(rdx, Operand(sp2, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x109));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand sp2c2 = Operand(rsp, rcx, times_pointer_size, 2 * kPointerSize);
+
+  // Test 6.
+  __ movl(rdx, sp2c2);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x105));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(sp2c2, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x103));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Non-zero to zero displacement.
+  __ movl(rdx, Operand(sp2c2, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x107));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+
+  Operand bp0 = Operand(rbp, 0);
+
+  // Test 9.
+  __ movl(rdx, bp0);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x100));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Zero to non-zero displacement.
+  __ movl(rdx, Operand(bp0, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x102));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand bp2 = Operand(rbp, -2 * kPointerSize);
+
+  // Test 11.
+  __ movl(rdx, bp2);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x102));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Non-zero to zero displacement.
+  __ movl(rdx, Operand(bp2, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x100));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bp2, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x104));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand bp2c4 = Operand(rbp, rcx, times_pointer_size, -4 * kPointerSize);
+
+  // Test 14:
+  __ movl(rdx, bp2c4);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x102));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bp2c4, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x100));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bp2c4, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x104));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand bx0 = Operand(rbx, 0);
+
+  // Test 17.
+  __ movl(rdx, bx0);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x105));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bx0, 5 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x100));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bx0, -4 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x109));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand bx2 = Operand(rbx, 2 * kPointerSize);
+
+  // Test 20.
+  __ movl(rdx, bx2);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x103));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bx2, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x101));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Non-zero to zero displacement.
+  __ movl(rdx, Operand(bx2, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x105));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand bx2c2 = Operand(rbx, rcx, times_pointer_size, -2 * kPointerSize);
+
+  // Test 23.
+  __ movl(rdx, bx2c2);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x105));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bx2c2, 2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x103));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(bx2c2, -2 * kPointerSize));
+  __ cmpl(rdx, Immediate(0x107));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand r80 = Operand(r8, 0);
+
+  // Test 26.
+  __ movl(rdx, r80);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x80808080));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, -8 * kIntSize));
+  __ cmpl(rdx, Immediate(0x78787878));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, 8 * kIntSize));
+  __ cmpl(rdx, Immediate(0x88888888));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, -64 * kIntSize));
+  __ cmpl(rdx, Immediate(0x40404040));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, 64 * kIntSize));
+  __ cmpl(rdx, Immediate(0xC0C0C0C0));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  Operand r88 = Operand(r8, 8 * kIntSize);
+
+  // Test 31.
+  __ movl(rdx, r88);  // Sanity check.
+  __ cmpl(rdx, Immediate(0x88888888));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r88, -8 * kIntSize));
+  __ cmpl(rdx, Immediate(0x80808080));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r88, 8 * kIntSize));
+  __ cmpl(rdx, Immediate(0x90909090));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r88, -64 * kIntSize));
+  __ cmpl(rdx, Immediate(0x48484848));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r88, 64 * kIntSize));
+  __ cmpl(rdx, Immediate(0xC8C8C8C8));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+
+  Operand r864 = Operand(r8, 64 * kIntSize);
+
+  // Test 36.
+  __ movl(rdx, r864);  // Sanity check.
+  __ cmpl(rdx, Immediate(0xC0C0C0C0));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r864, -8 * kIntSize));
+  __ cmpl(rdx, Immediate(0xB8B8B8B8));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r864, 8 * kIntSize));
+  __ cmpl(rdx, Immediate(0xC8C8C8C8));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r864, -64 * kIntSize));
+  __ cmpl(rdx, Immediate(0x80808080));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r864, 32 * kIntSize));
+  __ cmpl(rdx, Immediate(0xE0E0E0E0));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // 32-bit offset to 8-bit offset.
+  __ movl(rdx, Operand(r864, -60 * kIntSize));
+  __ cmpl(rdx, Immediate(0x84848484));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r864, 60 * kIntSize));
+  __ cmpl(rdx, Immediate(0xFCFCFCFC));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Test unaligned offsets.
+
+  // Test 43.
+  __ movl(rdx, Operand(r80, 2));
+  __ cmpl(rdx, Immediate(0x81818080));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, -2));
+  __ cmpl(rdx, Immediate(0x80807F7F));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, 126));
+  __ cmpl(rdx, Immediate(0xA0A09F9F));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, -126));
+  __ cmpl(rdx, Immediate(0x61616060));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, 254));
+  __ cmpl(rdx, Immediate(0xC0C0BFBF));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  __ movl(rdx, Operand(r80, -254));
+  __ cmpl(rdx, Immediate(0x41414040));
+  __ j(not_equal, &exit);
+  __ incq(rax);
+
+  // Success.
+
+  __ movl(rax, Immediate(0));
+  __ bind(&exit);
+  __ lea(rsp, Operand(rbp, kPointerSize));
+  __ pop(rbp);
+  __ pop(rbx);
+  __ pop(r13);
+  __ pop(r12);
+  __ ret(0);
+
+
+  CodeDesc desc;
+  masm->GetCode(&desc);
+  // Call the function from C++.
+  int result = FUNCTION_CAST<F0>(buffer)();
+  CHECK_EQ(0, result);
+}
+
+
+
 #undef __
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index e5850c9..b438d25 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -19,22 +19,64 @@
 using i::ProfileGenerator;
 using i::SampleRateCalculator;
 using i::TickSample;
+using i::TokenEnumerator;
 using i::Vector;
 
 
+namespace v8 {
+namespace internal {
+
+class TokenEnumeratorTester {
+ public:
+  static i::List<bool>* token_removed(TokenEnumerator* te) {
+    return &te->token_removed_;
+  }
+};
+
+} }  // namespace v8::internal
+
+TEST(TokenEnumerator) {
+  TokenEnumerator te;
+  CHECK_EQ(CodeEntry::kNoSecurityToken, te.GetTokenId(NULL));
+  v8::HandleScope hs;
+  v8::Local<v8::String> token1(v8::String::New("1"));
+  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
+  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
+  v8::Local<v8::String> token2(v8::String::New("2"));
+  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
+  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
+  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
+  {
+    v8::HandleScope hs;
+    v8::Local<v8::String> token3(v8::String::New("3"));
+    CHECK_EQ(2, te.GetTokenId(*v8::Utils::OpenHandle(*token3)));
+    CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
+    CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
+  }
+  CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
+  i::Heap::CollectAllGarbage(false);
+  CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
+  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
+  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
+}
+
+
 TEST(ProfileNodeFindOrAddChild) {
   ProfileNode node(NULL, NULL);
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
   ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
   CHECK_NE(NULL, childNode1);
   CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
   ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
   CHECK_NE(NULL, childNode2);
   CHECK_NE(childNode1, childNode2);
   CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
   CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
-  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
+  CodeEntry entry3(
+      i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken);
   ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
   CHECK_NE(NULL, childNode3);
   CHECK_NE(childNode1, childNode3);
@@ -75,9 +117,12 @@
 }  // namespace
 
 TEST(ProfileTreeAddPathFromStart) {
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
-  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry3(
+      i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken);
   ProfileTree tree;
   ProfileTreeTestHelper helper(&tree);
   CHECK_EQ(NULL, helper.Walk(&entry1));
@@ -142,9 +187,12 @@
 
 
 TEST(ProfileTreeAddPathFromEnd) {
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
-  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry3(
+      i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken);
   ProfileTree tree;
   ProfileTreeTestHelper helper(&tree);
   CHECK_EQ(NULL, helper.Walk(&entry1));
@@ -222,11 +270,30 @@
   CHECK_EQ(1, empty_tree.root()->total_ticks());
   CHECK_EQ(1, empty_tree.root()->self_ticks());
 
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
   CodeEntry* e1_path[] = {&entry1};
   Vector<CodeEntry*> e1_path_vec(
       e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
+
+  ProfileTree single_child_tree;
+  single_child_tree.AddPathFromStart(e1_path_vec);
+  single_child_tree.root()->IncrementSelfTicks();
+  CHECK_EQ(0, single_child_tree.root()->total_ticks());
+  CHECK_EQ(1, single_child_tree.root()->self_ticks());
+  ProfileTreeTestHelper single_child_helper(&single_child_tree);
+  ProfileNode* node1 = single_child_helper.Walk(&entry1);
+  CHECK_NE(NULL, node1);
+  CHECK_EQ(0, node1->total_ticks());
+  CHECK_EQ(1, node1->self_ticks());
+  single_child_tree.CalculateTotalTicks();
+  CHECK_EQ(2, single_child_tree.root()->total_ticks());
+  CHECK_EQ(1, single_child_tree.root()->self_ticks());
+  CHECK_EQ(1, node1->total_ticks());
+  CHECK_EQ(1, node1->self_ticks());
+
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
   CodeEntry* e1_e2_path[] = {&entry1, &entry2};
   Vector<CodeEntry*> e1_e2_path_vec(
       e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
@@ -241,7 +308,7 @@
   // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
   CHECK_EQ(0, flat_tree.root()->total_ticks());
   CHECK_EQ(0, flat_tree.root()->self_ticks());
-  ProfileNode* node1 = flat_helper.Walk(&entry1);
+  node1 = flat_helper.Walk(&entry1);
   CHECK_NE(NULL, node1);
   CHECK_EQ(0, node1->total_ticks());
   CHECK_EQ(2, node1->self_ticks());
@@ -261,7 +328,8 @@
   CodeEntry* e2_path[] = {&entry2};
   Vector<CodeEntry*> e2_path_vec(
       e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
-  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
+  CodeEntry entry3(
+      i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken);
   CodeEntry* e3_path[] = {&entry3};
   Vector<CodeEntry*> e3_path_vec(
       e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
@@ -316,16 +384,119 @@
 }
 
 
+TEST(ProfileTreeFilteredClone) {
+  ProfileTree source_tree;
+  const int token0 = 0, token1 = 1, token2 = 2;
+  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, token0);
+  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, token1);
+  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, token0);
+  CodeEntry entry4(
+      i::Logger::FUNCTION_TAG, "", "ddd", "", 0,
+      CodeEntry::kInheritsSecurityToken);
+
+  {
+    CodeEntry* e1_e2_path[] = {&entry1, &entry2};
+    Vector<CodeEntry*> e1_e2_path_vec(
+        e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
+    source_tree.AddPathFromStart(e1_e2_path_vec);
+    CodeEntry* e2_e4_path[] = {&entry2, &entry4};
+    Vector<CodeEntry*> e2_e4_path_vec(
+        e2_e4_path, sizeof(e2_e4_path) / sizeof(e2_e4_path[0]));
+    source_tree.AddPathFromStart(e2_e4_path_vec);
+    CodeEntry* e3_e1_path[] = {&entry3, &entry1};
+    Vector<CodeEntry*> e3_e1_path_vec(
+        e3_e1_path, sizeof(e3_e1_path) / sizeof(e3_e1_path[0]));
+    source_tree.AddPathFromStart(e3_e1_path_vec);
+    CodeEntry* e3_e2_path[] = {&entry3, &entry2};
+    Vector<CodeEntry*> e3_e2_path_vec(
+        e3_e2_path, sizeof(e3_e2_path) / sizeof(e3_e2_path[0]));
+    source_tree.AddPathFromStart(e3_e2_path_vec);
+    source_tree.CalculateTotalTicks();
+    // Results in               -> {entry1,0,1,0} -> {entry2,1,1,1}
+    //            {root,0,4,-1} -> {entry2,0,1,1} -> {entry4,1,1,inherits}
+    //                          -> {entry3,0,2,0} -> {entry1,1,1,0}
+    //                                            -> {entry2,1,1,1}
+    CHECK_EQ(4, source_tree.root()->total_ticks());
+    CHECK_EQ(0, source_tree.root()->self_ticks());
+  }
+
+  {
+    ProfileTree token0_tree;
+    token0_tree.FilteredClone(&source_tree, token0);
+    // Should be                -> {entry1,1,1,0}
+    //            {root,1,4,-1} -> {entry3,1,2,0} -> {entry1,1,1,0}
+    // [self ticks from filtered nodes are attributed to their parents]
+    CHECK_EQ(4, token0_tree.root()->total_ticks());
+    CHECK_EQ(1, token0_tree.root()->self_ticks());
+    ProfileTreeTestHelper token0_helper(&token0_tree);
+    ProfileNode* node1 = token0_helper.Walk(&entry1);
+    CHECK_NE(NULL, node1);
+    CHECK_EQ(1, node1->total_ticks());
+    CHECK_EQ(1, node1->self_ticks());
+    CHECK_EQ(NULL, token0_helper.Walk(&entry2));
+    ProfileNode* node3 = token0_helper.Walk(&entry3);
+    CHECK_NE(NULL, node3);
+    CHECK_EQ(2, node3->total_ticks());
+    CHECK_EQ(1, node3->self_ticks());
+    ProfileNode* node3_1 = token0_helper.Walk(&entry3, &entry1);
+    CHECK_NE(NULL, node3_1);
+    CHECK_EQ(1, node3_1->total_ticks());
+    CHECK_EQ(1, node3_1->self_ticks());
+    CHECK_EQ(NULL, token0_helper.Walk(&entry3, &entry2));
+  }
+
+  {
+    ProfileTree token1_tree;
+    token1_tree.FilteredClone(&source_tree, token1);
+    // Should be
+    //            {root,1,4,-1} -> {entry2,2,3,1} -> {entry4,1,1,inherits}
+    // [child nodes referring to the same entry get merged and
+    //  their self times summed up]
+    CHECK_EQ(4, token1_tree.root()->total_ticks());
+    CHECK_EQ(1, token1_tree.root()->self_ticks());
+    ProfileTreeTestHelper token1_helper(&token1_tree);
+    CHECK_EQ(NULL, token1_helper.Walk(&entry1));
+    CHECK_EQ(NULL, token1_helper.Walk(&entry3));
+    ProfileNode* node2 = token1_helper.Walk(&entry2);
+    CHECK_NE(NULL, node2);
+    CHECK_EQ(3, node2->total_ticks());
+    CHECK_EQ(2, node2->self_ticks());
+    ProfileNode* node2_4 = token1_helper.Walk(&entry2, &entry4);
+    CHECK_NE(NULL, node2_4);
+    CHECK_EQ(1, node2_4->total_ticks());
+    CHECK_EQ(1, node2_4->self_ticks());
+  }
+
+  {
+    ProfileTree token2_tree;
+    token2_tree.FilteredClone(&source_tree, token2);
+    // Should be
+    //            {root,4,4,-1}
+    // [no nodes, all ticks get migrated into root node]
+    CHECK_EQ(4, token2_tree.root()->total_ticks());
+    CHECK_EQ(4, token2_tree.root()->self_ticks());
+    ProfileTreeTestHelper token2_helper(&token2_tree);
+    CHECK_EQ(NULL, token2_helper.Walk(&entry1));
+    CHECK_EQ(NULL, token2_helper.Walk(&entry2));
+    CHECK_EQ(NULL, token2_helper.Walk(&entry3));
+  }
+}
+
+
 static inline i::Address ToAddress(int n) {
   return reinterpret_cast<i::Address>(n);
 }
 
 TEST(CodeMapAddCode) {
   CodeMap code_map;
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
-  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
-  CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry3(
+      i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry4(
+      i::Logger::FUNCTION_TAG, "", "ddd", "", 0, CodeEntry::kNoSecurityToken);
   code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
   code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
   code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
@@ -352,8 +523,10 @@
 
 TEST(CodeMapMoveAndDeleteCode) {
   CodeMap code_map;
-  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
-  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+  CodeEntry entry1(
+      i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken);
+  CodeEntry entry2(
+      i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken);
   code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
   code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
   CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
@@ -425,7 +598,8 @@
   sample3.frames_count = 2;
   generator.RecordTickSample(sample3);
 
-  CpuProfile* profile = profiles.StopProfiling("", 1);
+  CpuProfile* profile =
+      profiles.StopProfiling(CodeEntry::kNoSecurityToken, "", 1);
   CHECK_NE(NULL, profile);
   ProfileTreeTestHelper top_down_test_helper(profile->top_down());
   CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc
index 83a1e19..aed7466 100644
--- a/test/cctest/test-thread-termination.cc
+++ b/test/cctest/test-thread-termination.cc
@@ -308,3 +308,48 @@
   v8::Script::Compile(source)->Run();
   context.Dispose();
 }
+
+v8::Handle<v8::Value> ReenterAfterTermination(const v8::Arguments& args) {
+  v8::TryCatch try_catch;
+  CHECK(!v8::V8::IsExecutionTerminating());
+  v8::Script::Compile(v8::String::New("function f() {"
+                                      "  var term = true;"
+                                      "  try {"
+                                      "    while(true) {"
+                                      "      if (term) terminate();"
+                                      "      term = false;"
+                                      "    }"
+                                      "    fail();"
+                                      "  } catch(e) {"
+                                      "    fail();"
+                                      "  }"
+                                      "}"
+                                      "f()"))->Run();
+  CHECK(try_catch.HasCaught());
+  CHECK(try_catch.Exception()->IsNull());
+  CHECK(try_catch.Message().IsEmpty());
+  CHECK(!try_catch.CanContinue());
+  CHECK(v8::V8::IsExecutionTerminating());
+  v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run();
+  return v8::Undefined();
+}
+
+// Test that reentry into V8 while the termination exception is still pending
+// (has not yet unwound the 0-level JS frame) does not crash.
+TEST(TerminateAndReenterFromThreadItself) {
+  v8::HandleScope scope;
+  v8::Handle<v8::ObjectTemplate> global =
+      CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination);
+  v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
+  v8::Context::Scope context_scope(context);
+  CHECK(!v8::V8::IsExecutionTerminating());
+  v8::Handle<v8::String> source =
+      v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
+  v8::Script::Compile(source)->Run();
+  CHECK(!v8::V8::IsExecutionTerminating());
+  // Check we can run JS again after termination.
+  CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }"
+                                            "f()"))->Run()->IsTrue());
+  context.Dispose();
+}
+
diff --git a/test/cctest/test-unbound-queue.cc b/test/cctest/test-unbound-queue.cc
new file mode 100644
index 0000000..df5509e
--- /dev/null
+++ b/test/cctest/test-unbound-queue.cc
@@ -0,0 +1,54 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+//
+// Tests of the unbound queue.
+
+#include "v8.h"
+#include "unbound-queue-inl.h"
+#include "cctest.h"
+
+namespace i = v8::internal;
+
+using i::UnboundQueue;
+
+
+TEST(SingleRecord) {
+  typedef int Record;
+  UnboundQueue<Record> cq;
+  CHECK(cq.IsEmpty());
+  cq.Enqueue(1);
+  CHECK(!cq.IsEmpty());
+  Record rec = 0;
+  cq.Dequeue(&rec);
+  CHECK_EQ(1, rec);
+  CHECK(cq.IsEmpty());
+}
+
+
+TEST(MultipleRecords) {
+  typedef int Record;
+  UnboundQueue<Record> cq;
+  CHECK(cq.IsEmpty());
+  cq.Enqueue(1);
+  CHECK(!cq.IsEmpty());
+  for (int i = 2; i <= 5; ++i) {
+    cq.Enqueue(i);
+    CHECK(!cq.IsEmpty());
+  }
+  Record rec = 0;
+  for (int i = 1; i <= 4; ++i) {
+    CHECK(!cq.IsEmpty());
+    cq.Dequeue(&rec);
+    CHECK_EQ(i, rec);
+  }
+  for (int i = 6; i <= 12; ++i) {
+    cq.Enqueue(i);
+    CHECK(!cq.IsEmpty());
+  }
+  for (int i = 5; i <= 12; ++i) {
+    CHECK(!cq.IsEmpty());
+    cq.Dequeue(&rec);
+    CHECK_EQ(i, rec);
+  }
+  CHECK(cq.IsEmpty());
+}
+
diff --git a/test/mjsunit/compiler/assignment.js b/test/mjsunit/compiler/assignment.js
index ee2d323..6aded4e 100644
--- a/test/mjsunit/compiler/assignment.js
+++ b/test/mjsunit/compiler/assignment.js
@@ -262,3 +262,15 @@
 }
 
 bar_loop();
+
+
+// Test for assignment using a keyed store ic:
+function store_i_in_element_i_of_object_i() {
+  var i = new Object();
+  i[i] = i;
+}
+
+// Run three times to exercise caches.
+store_i_in_element_i_of_object_i();
+store_i_in_element_i_of_object_i();
+store_i_in_element_i_of_object_i();
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
index 43b1c7f..46bfb34 100644
--- a/test/mjsunit/object-define-property.js
+++ b/test/mjsunit/object-define-property.js
@@ -53,36 +53,46 @@
   assertTrue(/called on non-object/.test(e));
 }
 
-// Object
+// Object.
 var obj1 = {};
 
-// Values
+// Values.
 var val1 = 0;
 var val2 = 0;
 var val3 = 0;
 
-// Descriptors
+function setter1() {val1++; }
+function getter1() {return val1; }
+
+function setter2() {val2++; }
+function getter2() {return val2; }
+
+function setter3() {val3++; }
+function getter3() {return val3; }
+
+
+// Descriptors.
 var emptyDesc = {};
 
 var accessorConfigurable = { 
-    set: function() { val1++; },
-    get: function() { return val1; },
+    set: setter1,
+    get: getter1,
     configurable: true
 };
 
 var accessorNoConfigurable = {
-    set: function() { val2++; },
-    get: function() { return val2; },
+    set: setter2,
+    get: getter2,
     configurable: false 
 };
 
 var accessorOnlySet = {
-  set: function() { val3++; },
+  set: setter3,
   configurable: true
 };
 
 var accessorOnlyGet = {
-  get: function() { return val3; },
+  get: getter3,
   configurable: true
 };
 
@@ -200,7 +210,7 @@
 assertEquals(4, val2);
 assertEquals(4, obj1.bar);
 
-// Define an accessor that has only a setter
+// Define an accessor that has only a setter.
 Object.defineProperty(obj1, "setOnly", accessorOnlySet);
 desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
 assertTrue(desc.configurable);
@@ -212,7 +222,7 @@
 assertEquals(1, obj1.setOnly = 1);
 assertEquals(1, val3);
 
-// Add a getter - should not touch the setter
+// Add a getter - should not touch the setter.
 Object.defineProperty(obj1, "setOnly", accessorOnlyGet);
 desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
 assertTrue(desc.configurable);
@@ -256,7 +266,7 @@
 assertEquals(obj1.foobar, 1000);
 
 
-// Redefine to writable descriptor - now writing to foobar should be allowed
+// Redefine to writable descriptor - now writing to foobar should be allowed.
 Object.defineProperty(obj1, "foobar", dataWritable);
 desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
 assertEquals(obj1.foobar, 3000);
@@ -279,7 +289,7 @@
 assertEquals(obj1.foobar, 2000);
 assertEquals(desc.value, 2000);
 assertFalse(desc.configurable);
-assertFalse(desc.writable);
+assertTrue(desc.writable);
 assertFalse(desc.enumerable);
 assertEquals(desc.get, undefined);
 assertEquals(desc.set, undefined);
@@ -307,7 +317,7 @@
 assertEquals(obj1.foobar, 2000);
 assertEquals(desc.value, 2000);
 assertFalse(desc.configurable);
-assertFalse(desc.writable);
+assertTrue(desc.writable);
 assertFalse(desc.enumerable);
 assertEquals(desc.get, undefined);
 assertEquals(desc.set, undefined);
@@ -375,7 +385,7 @@
 
 
 // Redefinition of an accessor defined using __defineGetter__ and 
-// __defineSetter__
+// __defineSetter__.
 function get(){return this.x}
 function set(x){this.x=x};
 
@@ -442,7 +452,7 @@
 assertEquals(5, val1);
 assertEquals(5, obj4.bar);
 
-// Make sure an error is thrown when trying to access to redefined function
+// Make sure an error is thrown when trying to access to redefined function.
 try {
   obj4.bar();
   assertTrue(false);
@@ -453,7 +463,7 @@
 
 // Test runtime calls to DefineOrRedefineDataProperty and
 // DefineOrRedefineAccessorProperty - make sure we don't 
-// crash
+// crash.
 try {
   %DefineOrRedefineAccessorProperty(0, 0, 0, 0, 0);
 } catch (e) {
@@ -497,3 +507,210 @@
 } catch (e) {
   assertTrue(/illegal access/.test(e));
 }
+
+// Test that all possible differences in step 6 in DefineOwnProperty are
+// exercised, i.e., any difference in the given property descriptor and the
+// existing properties should not return true, but throw an error if the
+// existing configurable property is false. 
+
+var obj5 = {};
+// Enumerable will default to false.
+Object.defineProperty(obj5, 'foo', accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj5, 'foo');
+// First, test that we are actually allowed to set the accessor if all
+// values are of the descriptor are the same as the existing one.
+Object.defineProperty(obj5, 'foo', accessorNoConfigurable);
+
+// Different setter.
+var descDifferent = {
+  configurable:false,
+  enumerable:false,
+  set: setter1,
+  get: getter2
+};
+
+try {
+  Object.defineProperty(obj5, 'foo', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Different getter.
+descDifferent = {
+  configurable:false,
+  enumerable:false,
+  set: setter2,
+  get: getter1
+};
+
+try {
+  Object.defineProperty(obj5, 'foo', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Different enumerable.
+descDifferent = {
+  configurable:false,
+  enumerable:true,
+  set: setter2,
+  get: getter2
+};
+
+try {
+  Object.defineProperty(obj5, 'foo', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Different configurable.
+descDifferent = {
+  configurable:false,
+  enumerable:true,
+  set: setter2,
+  get: getter2
+};
+
+try {
+  Object.defineProperty(obj5, 'foo', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// No difference.
+descDifferent = {
+  configurable:false,
+  enumerable:false,
+  set: setter2,
+  get: getter2
+};
+// Make sure we can still redefine if all properties are the same.
+Object.defineProperty(obj5, 'foo', descDifferent);
+
+// Make sure that obj5 still holds the original values.
+desc = Object.getOwnPropertyDescriptor(obj5, 'foo');
+assertEquals(desc.get, getter2);
+assertEquals(desc.set, setter2);
+assertFalse(desc.enumerable);
+assertFalse(desc.configurable);
+
+
+// Also exercise step 6 on data property, writable and enumerable
+// defaults to false.
+Object.defineProperty(obj5, 'bar', dataNoConfigurable);
+
+// Test that redefinition with the same property descriptor is possible
+Object.defineProperty(obj5, 'bar', dataNoConfigurable);
+
+// Different value.
+descDifferent = {
+  configurable:false,
+  enumerable:false,
+  writable: false,
+  value: 1999
+};
+
+try {
+  Object.defineProperty(obj5, 'bar', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Different writable.
+descDifferent = {
+  configurable:false,
+  enumerable:false,
+  writable: true,
+  value: 2000
+};
+
+try {
+  Object.defineProperty(obj5, 'bar', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Different enumerable.
+descDifferent = {
+  configurable:false,
+  enumerable:true ,
+  writable:false,
+  value: 2000
+};
+
+try {
+  Object.defineProperty(obj5, 'bar', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Different configurable.
+descDifferent = {
+  configurable:true,
+  enumerable:false,
+  writable:false,
+  value: 2000
+};
+
+try {
+  Object.defineProperty(obj5, 'bar', descDifferent);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// No difference.
+descDifferent = {
+  configurable:false,
+  enumerable:false,
+  writable:false,
+  value:2000
+};
+// Make sure we can still redefine if all properties are the same.
+Object.defineProperty(obj5, 'bar', descDifferent);
+
+// Make sure that obj5 still holds the original values.
+desc = Object.getOwnPropertyDescriptor(obj5, 'bar');
+assertEquals(desc.value, 2000);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertFalse(desc.configurable);
+
+
+// Make sure that we can't overwrite +0 with -0 and vice versa.
+var descMinusZero = {value: -0, configurable: false};
+var descPlusZero = {value: +0, configurable: false};
+
+Object.defineProperty(obj5, 'minuszero', descMinusZero);
+
+// Make sure we can redefine with -0.
+Object.defineProperty(obj5, 'minuszero', descMinusZero);
+
+try {
+  Object.defineProperty(obj5, 'minuszero', descPlusZero);
+  assertUnreachable();
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+Object.defineProperty(obj5, 'pluszero', descPlusZero);
+
+// Make sure we can redefine with +0.
+Object.defineProperty(obj5, 'pluszero', descPlusZero);
+
+try {
+  Object.defineProperty(obj5, 'pluszero', descMinusZero);
+  assertUnreachable();
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
diff --git a/test/mjsunit/regress/regress-712.js b/test/mjsunit/regress/regress-712.js
new file mode 100644
index 0000000..b26b94a
--- /dev/null
+++ b/test/mjsunit/regress/regress-712.js
@@ -0,0 +1,38 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This regression test is used to ensure that Object.defineProperty
+// can't be called with an empty property descriptor on a non-configurable
+// existing property and override the existing property.
+// See: http://code.google.com/p/v8/issues/detail?id=712
+
+var obj = {};
+Object.defineProperty(obj, "x", { get: function() { return "42"; },
+                                  configurable: false });
+assertEquals(obj.x, "42");
+Object.defineProperty(obj, 'x', {});
+assertEquals(obj.x, "42");
diff --git a/test/mjsunit/regress/regress-720.js b/test/mjsunit/regress/regress-720.js
new file mode 100644
index 0000000..97e1284
--- /dev/null
+++ b/test/mjsunit/regress/regress-720.js
@@ -0,0 +1,36 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This regression test is used to ensure that Object.defineProperty
+// keeps the existing value of the writable flag if none is given
+// in the provided descriptor. 
+// See: http://code.google.com/p/v8/issues/detail?id=720
+
+var o = {x: 10};
+Object.defineProperty(o, "x", {value: 5});
+var desc = Object.getOwnPropertyDescriptor(o, "x");
+assertTrue(desc["writable"]);
diff --git a/test/mjsunit/samevalue.js b/test/mjsunit/samevalue.js
new file mode 100644
index 0000000..6cb35e6
--- /dev/null
+++ b/test/mjsunit/samevalue.js
@@ -0,0 +1,102 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Flags: --expose-natives_as natives
+// Test the SameValue internal method.
+
+var obj1 = {x: 10, y: 11, z: "test"};
+var obj2 = {x: 10, y: 11, z: "test"};
+
+assertTrue(natives.SameValue(0, 0));
+assertTrue(natives.SameValue(+0, +0));
+assertTrue(natives.SameValue(-0, -0));
+assertTrue(natives.SameValue(1, 1));
+assertTrue(natives.SameValue(2, 2));
+assertTrue(natives.SameValue(-1, -1));
+assertTrue(natives.SameValue(0.5, 0.5));
+assertTrue(natives.SameValue(true, true));
+assertTrue(natives.SameValue(false, false));
+assertTrue(natives.SameValue(NaN, NaN));
+assertTrue(natives.SameValue(null, null));
+assertTrue(natives.SameValue("foo", "foo"));
+assertTrue(natives.SameValue(obj1, obj1));
+// Undefined values.
+assertTrue(natives.SameValue());
+assertTrue(natives.SameValue(undefined, undefined));
+
+assertFalse(natives.SameValue(0,1));
+assertFalse(natives.SameValue("foo", "bar"));
+assertFalse(natives.SameValue(obj1, obj2));
+assertFalse(natives.SameValue(true, false));
+
+assertFalse(natives.SameValue(obj1, true));
+assertFalse(natives.SameValue(obj1, "foo"));
+assertFalse(natives.SameValue(obj1, 1));
+assertFalse(natives.SameValue(obj1, undefined));
+assertFalse(natives.SameValue(obj1, NaN));
+
+assertFalse(natives.SameValue(undefined, true));
+assertFalse(natives.SameValue(undefined, "foo"));
+assertFalse(natives.SameValue(undefined, 1));
+assertFalse(natives.SameValue(undefined, obj1));
+assertFalse(natives.SameValue(undefined, NaN));
+
+assertFalse(natives.SameValue(NaN, true));
+assertFalse(natives.SameValue(NaN, "foo"));
+assertFalse(natives.SameValue(NaN, 1));
+assertFalse(natives.SameValue(NaN, obj1));
+assertFalse(natives.SameValue(NaN, undefined));
+
+assertFalse(natives.SameValue("foo", true));
+assertFalse(natives.SameValue("foo", 1));
+assertFalse(natives.SameValue("foo", obj1));
+assertFalse(natives.SameValue("foo", undefined));
+assertFalse(natives.SameValue("foo", NaN));
+
+assertFalse(natives.SameValue(true, 1));
+assertFalse(natives.SameValue(true, obj1));
+assertFalse(natives.SameValue(true, undefined));
+assertFalse(natives.SameValue(true, NaN));
+assertFalse(natives.SameValue(true, "foo"));
+
+assertFalse(natives.SameValue(1, true));
+assertFalse(natives.SameValue(1, obj1));
+assertFalse(natives.SameValue(1, undefined));
+assertFalse(natives.SameValue(1, NaN));
+assertFalse(natives.SameValue(1, "foo"));
+
+// Special string cases.
+assertFalse(natives.SameValue("1", 1));
+assertFalse(natives.SameValue("true", true));
+assertFalse(natives.SameValue("false", false));
+assertFalse(natives.SameValue("undefined", undefined));
+assertFalse(natives.SameValue("NaN", NaN));
+
+// -0 and +0 are should be different
+assertFalse(natives.SameValue(+0, -0));
+assertFalse(natives.SameValue(-0, +0));
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index c92bfa6..b4ec444 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -161,6 +161,7 @@
 # In Denmark the adjustment starts one week earlier!.
 # Tests based on shell that use dates in this gap are flaky.
 ecma/Date/15.9.5.10-1: PASS || FAIL
+ecma/Date/15.9.5.10-2: PASS || TIMEOUT if ($arch == arm && $mode == debug)
 ecma/Date/15.9.5.12-1: PASS || FAIL
 ecma/Date/15.9.5.14: PASS || FAIL
 ecma/Date/15.9.5.34-1: PASS || FAIL