Version 3.8.6

Add primitive WebGL array support to d8.

Improve heap size estimation (issue 1893).

Hash collision DOS workaround extended from string keys to numeric keys.

Provide an API for iterating through all external strings referenced from the JS heap.

Adjust position recorded for call expressions. http://crbug.com/109195

Fix GC crash related to instanceof. http://crbug.com/109448

Performance improvements and bug fixes.
Review URL: http://codereview.chromium.org/9227007

git-svn-id: http://v8.googlecode.com/svn/trunk@10406 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 5fc9188..edb859e 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -73,6 +73,7 @@
     'test-fixed-dtoa.cc',
     'test-flags.cc',
     'test-func-name-inference.cc',
+    'test-hashing.cc',
     'test-hashmap.cc',
     'test-heap-profiler.cc',
     'test-heap.cc',
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index c04d893..0b93562 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -104,7 +104,7 @@
                     FOURTH_PART,
                     LAST_PART = FOURTH_PART };
 
-  static void Setup(PartOfTest part);
+  static void SetUp(PartOfTest part);
   static void RunAllTests();
   static void TearDown();
   // This method switches threads if we are running the Threading test.
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index 899c902..c654dfa 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -203,10 +203,10 @@
 
 TEST(CodeRange) {
   const int code_range_size = 32*MB;
-  OS::Setup();
+  OS::SetUp();
   Isolate::Current()->InitializeLoggingAndCounters();
   CodeRange* code_range = new CodeRange(Isolate::Current());
-  code_range->Setup(code_range_size);
+  code_range->SetUp(code_range_size);
   int current_allocated = 0;
   int total_allocated = 0;
   List<Block> blocks(1000);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index fb8becd..d001e65 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -2867,6 +2867,16 @@
   obj = env->Global()->Get(v8_str("obj"));
   CHECK(!obj->IsInt32());
   CHECK(!obj->IsUint32());
+  // Positive zero
+  CompileRun("var obj = 0.0;");
+  obj = env->Global()->Get(v8_str("obj"));
+  CHECK(obj->IsInt32());
+  CHECK(obj->IsUint32());
+  // Positive zero
+  CompileRun("var obj = -0.0;");
+  obj = env->Global()->Get(v8_str("obj"));
+  CHECK(!obj->IsInt32());
+  CHECK(!obj->IsUint32());
 }
 
 
@@ -7941,7 +7951,7 @@
   other->SetSecurityToken(token);
   current->SetSecurityToken(token);
 
-  // Setup reference from current to other.
+  // Set up reference from current to other.
   current->Global()->Set(v8_str("other"), other->Global());
 
   // Check that new variables are introduced in other context.
@@ -8021,7 +8031,7 @@
   v8::Persistent<Context> context0 = Context::New();
   v8::Persistent<Context> context1 = Context::New();
 
-  // Setup function in context0 that uses eval from context0.
+  // Set up function in context0 that uses eval from context0.
   context0->Enter();
   v8::Handle<v8::Value> fun =
       CompileRun("var x = 42;"
@@ -8059,7 +8069,7 @@
   other->SetSecurityToken(token);
   current->SetSecurityToken(token);
 
-  // Setup reference from current to other.
+  // Set up reference from current to other.
   current->Global()->Set(v8_str("other"), other->Global());
 
   // Trigger lazy loading in other context.
@@ -10170,7 +10180,7 @@
 static unsigned linear_congruential_generator;
 
 
-void ApiTestFuzzer::Setup(PartOfTest part) {
+void ApiTestFuzzer::SetUp(PartOfTest part) {
   linear_congruential_generator = i::FLAG_testing_prng_seed;
   fuzzing_ = true;
   int count = RegisterThreadedTest::count();
@@ -10234,25 +10244,25 @@
 
 // Lets not be needlessly self-referential.
 TEST(Threading) {
-  ApiTestFuzzer::Setup(ApiTestFuzzer::FIRST_PART);
+  ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART);
   ApiTestFuzzer::RunAllTests();
   ApiTestFuzzer::TearDown();
 }
 
 TEST(Threading2) {
-  ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART);
+  ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART);
   ApiTestFuzzer::RunAllTests();
   ApiTestFuzzer::TearDown();
 }
 
 TEST(Threading3) {
-  ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART);
+  ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART);
   ApiTestFuzzer::RunAllTests();
   ApiTestFuzzer::TearDown();
 }
 
 TEST(Threading4) {
-  ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART);
+  ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART);
   ApiTestFuzzer::RunAllTests();
   ApiTestFuzzer::TearDown();
 }
@@ -12111,7 +12121,7 @@
                                   callback_templ->GetFunction());
   calling_context0->Exit();
 
-  // Expose context0 in context1 and setup a function that calls the
+  // Expose context0 in context1 and set up a function that calls the
   // callback function.
   calling_context1->Enter();
   calling_context1->Global()->Set(v8_str("context0"),
@@ -12269,18 +12279,18 @@
 
   i::Handle<i::Smi> value(i::Smi::FromInt(2));
   i::Handle<i::Object> no_failure;
-  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
   ASSERT(!no_failure.is_null());
   i::USE(no_failure);
   CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
   *value.location() = i::Smi::FromInt(256);
-  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
   ASSERT(!no_failure.is_null());
   i::USE(no_failure);
   CHECK_EQ(255,
            i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
   *value.location() = i::Smi::FromInt(-1);
-  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
   ASSERT(!no_failure.is_null());
   i::USE(no_failure);
   CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
@@ -13549,21 +13559,24 @@
 // Test that idle notification can be handled and eventually returns true.
 // This just checks the contract of the IdleNotification() function,
 // and does not verify that it does reasonable work.
-THREADED_TEST(IdleNotificationWithHint) {
+TEST(IdleNotificationWithHint) {
   v8::HandleScope scope;
   LocalContext env;
-  CompileRun("function binom(n, m) {"
-             "  var C = [[1]];"
-             "  for (var i = 1; i <= n; ++i) {"
-             "    C[i] = [1];"
-             "    for (var j = 1; j < i; ++j) {"
-             "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
-             "    }"
-             "    C[i][i] = 1;"
-             "  }"
-             "  return C[n][m];"
-             "};"
-             "binom(1000, 500)");
+  {
+    i::AlwaysAllocateScope always_allocate;
+    CompileRun("function binom(n, m) {"
+               "  var C = [[1]];"
+               "  for (var i = 1; i <= n; ++i) {"
+               "    C[i] = [1];"
+               "    for (var j = 1; j < i; ++j) {"
+               "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
+               "    }"
+               "    C[i][i] = 1;"
+               "  }"
+               "  return C[n][m];"
+               "};"
+               "binom(1000, 500)");
+  }
   bool rv = false;
   intptr_t old_size = HEAP->SizeOfObjects();
   bool no_idle_work = v8::V8::IdleNotification(10);
@@ -13665,6 +13678,59 @@
 }
 
 
+class VisitorImpl : public v8::ExternalResourceVisitor {
+ public:
+  VisitorImpl(TestResource* r1, TestResource* r2)
+      : resource1_(r1),
+        resource2_(r2),
+        found_resource1_(false),
+        found_resource2_(false) {}
+  virtual ~VisitorImpl() {}
+  virtual void VisitExternalString(v8::Handle<v8::String> string) {
+    if (!string->IsExternal()) {
+      CHECK(string->IsExternalAscii());
+      return;
+    }
+    v8::String::ExternalStringResource* resource =
+        string->GetExternalStringResource();
+    CHECK(resource);
+    if (resource1_ == resource) {
+      CHECK(!found_resource1_);
+      found_resource1_ = true;
+    }
+    if (resource2_ == resource) {
+      CHECK(!found_resource2_);
+      found_resource2_ = true;
+    }
+  }
+  void CheckVisitedResources() {
+    CHECK(found_resource1_);
+    CHECK(found_resource2_);
+  }
+
+ private:
+  v8::String::ExternalStringResource* resource1_;
+  v8::String::ExternalStringResource* resource2_;
+  bool found_resource1_;
+  bool found_resource2_;
+};
+
+TEST(VisitExternalStrings) {
+  v8::HandleScope scope;
+  LocalContext env;
+  const char* string = "Some string";
+  uint16_t* two_byte_string = AsciiToTwoByteString(string);
+  TestResource* resource1 = new TestResource(two_byte_string);
+  v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
+  TestResource* resource2 = new TestResource(two_byte_string);
+  v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
+
+  VisitorImpl visitor(resource1, resource2);
+  v8::V8::VisitExternalResources(&visitor);
+  visitor.CheckVisitedResources();
+}
+
+
 static double DoubleFromBits(uint64_t value) {
   double target;
   memcpy(&target, &value, sizeof(target));
diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc
index 959cf3f..d81923f 100644
--- a/test/cctest/test-assembler-x64.cc
+++ b/test/cctest/test-assembler-x64.cc
@@ -99,7 +99,7 @@
 
 
 TEST(AssemblerX64ReturnOperation) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -121,7 +121,7 @@
 }
 
 TEST(AssemblerX64StackOperations) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -153,7 +153,7 @@
 }
 
 TEST(AssemblerX64ArithmeticOperations) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -175,7 +175,7 @@
 }
 
 TEST(AssemblerX64ImulOperation) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -203,7 +203,7 @@
 }
 
 TEST(AssemblerX64MemoryOperands) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -237,7 +237,7 @@
 }
 
 TEST(AssemblerX64ControlFlow) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -266,7 +266,7 @@
 }
 
 TEST(AssemblerX64LoopImmediates) {
-  OS::Setup();
+  OS::SetUp();
   // Allocate an executable page of memory.
   size_t actual_size;
   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index f567a0f..b10e688 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -216,7 +216,7 @@
 TEST(CrashIfStoppingLastNonExistentProfile) {
   InitializeVM();
   TestSetup test_setup;
-  CpuProfiler::Setup();
+  CpuProfiler::SetUp();
   CpuProfiler::StartProfiling("1");
   CpuProfiler::StopProfiling("2");
   CpuProfiler::StartProfiling("1");
@@ -268,7 +268,7 @@
 TEST(DeleteAllCpuProfiles) {
   InitializeVM();
   TestSetup test_setup;
-  CpuProfiler::Setup();
+  CpuProfiler::SetUp();
   CHECK_EQ(0, CpuProfiler::GetProfilesCount());
   CpuProfiler::DeleteAllProfiles();
   CHECK_EQ(0, CpuProfiler::GetProfilesCount());
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 8543a37..4fa7afa 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -2743,7 +2743,7 @@
   v8::Handle<v8::Value> args[kArgc] = { a };
   foo->Call(env->Global(), kArgc, args);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
@@ -2790,7 +2790,7 @@
   v8::Handle<v8::Value> args[kArgc] = { a };
   foo->Call(env->Global(), kArgc, args);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
@@ -2834,7 +2834,7 @@
   // Call function without any break points to ensure inlining is in place.
   foo->Call(env->Global(), 0, NULL);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 4);
   step_action = StepNext;
   break_point_hit_count = 0;
@@ -2869,7 +2869,7 @@
   // Call function without any break points to ensure inlining is in place.
   foo->Call(env->Global(), 0, NULL);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
@@ -5709,7 +5709,7 @@
   v8::HandleScope scope;
   DebugLocalContext env;
 
-  // Setup message and host dispatch handlers.
+  // Set up message and host dispatch handlers.
   v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
   v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
 
@@ -5797,7 +5797,7 @@
   v8::HandleScope scope;
   DebugLocalContext env;
 
-  // Setup debug message dispatch handler.
+  // Set up debug message dispatch handler.
   v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
 
   CompileRun("var y = 1 + 2;\n");
@@ -5851,7 +5851,7 @@
   bool ok;
 
   // Initialize the socket library.
-  i::Socket::Setup();
+  i::Socket::SetUp();
 
   // Test starting and stopping the agent without any client connection.
   debugger->StartAgent("test", kPort1);
@@ -5949,7 +5949,7 @@
   OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
 
   // Initialize the socket library.
-  i::Socket::Setup();
+  i::Socket::SetUp();
 
   // Create a socket server to receive a debugger agent message.
   DebuggerAgentProtocolServerThread* server =
diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc
index 032e6bc..0e9432d 100644
--- a/test/cctest/test-disasm-arm.cc
+++ b/test/cctest/test-disasm-arm.cc
@@ -69,10 +69,10 @@
 }
 
 
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
 // disassembler. Declare the variables and allocate the data structures used
 // in the rest of the macros.
-#define SETUP()                                           \
+#define SET_UP()                                           \
   InitializeVM();                                         \
   v8::HandleScope scope;                                  \
   byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -102,7 +102,7 @@
 
 
 TEST(Type0) {
-  SETUP();
+  SET_UP();
 
   COMPARE(and_(r0, r1, Operand(r2)),
           "e0010002       and r0, r1, r2");
@@ -329,7 +329,7 @@
 
 
 TEST(Type1) {
-  SETUP();
+  SET_UP();
 
   COMPARE(and_(r0, r1, Operand(0x00000000)),
           "e2010000       and r0, r1, #0");
@@ -358,7 +358,7 @@
 
 
 TEST(Type3) {
-  SETUP();
+  SET_UP();
 
   if (CpuFeatures::IsSupported(ARMv7)) {
     COMPARE(ubfx(r0, r1, 5, 10),
@@ -413,7 +413,7 @@
 
 
 TEST(Vfp) {
-  SETUP();
+  SET_UP();
 
   if (CpuFeatures::IsSupported(VFP3)) {
     CpuFeatures::Scope scope(VFP3);
@@ -546,7 +546,7 @@
 
 
 TEST(LoadStore) {
-  SETUP();
+  SET_UP();
 
   COMPARE(ldrb(r0, MemOperand(r1)),
           "e5d10000       ldrb r0, [r1, #+0]");
diff --git a/test/cctest/test-disasm-mips.cc b/test/cctest/test-disasm-mips.cc
index 5ad99d7..8eadc64 100644
--- a/test/cctest/test-disasm-mips.cc
+++ b/test/cctest/test-disasm-mips.cc
@@ -71,10 +71,10 @@
 }
 
 
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
 // disassembler. Declare the variables and allocate the data structures used
 // in the rest of the macros.
-#define SETUP()                                           \
+#define SET_UP()                                           \
   InitializeVM();                                         \
   v8::HandleScope scope;                                  \
   byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -104,7 +104,7 @@
 
 
 TEST(Type0) {
-  SETUP();
+  SET_UP();
 
   COMPARE(addu(a0, a1, a2),
           "00a62021       addu    a0, a1, a2");
diff --git a/test/cctest/test-hashing.cc b/test/cctest/test-hashing.cc
index df1ab20..a626510 100644
--- a/test/cctest/test-hashing.cc
+++ b/test/cctest/test-hashing.cc
@@ -46,65 +46,106 @@
 
 static v8::Persistent<v8::Context> env;
 
-#define __ assm->
+#define __ masm->
 
 
-void generate(MacroAssembler* assm, i::Vector<const char> string) {
+void generate(MacroAssembler* masm, i::Vector<const char> string) {
+  // GenerateHashInit takes the first character as an argument so it can't
+  // handle the zero length string.
+  ASSERT(string.length() > 0);
 #ifdef V8_TARGET_ARCH_IA32
   __ push(ebx);
   __ push(ecx);
   __ mov(eax, Immediate(0));
-  if (string.length() > 0) {
-    __ mov(ebx, Immediate(string.at(0)));
-    StringHelper::GenerateHashInit(assm, eax, ebx, ecx);
-  }
+  __ mov(ebx, Immediate(string.at(0)));
+  StringHelper::GenerateHashInit(masm, eax, ebx, ecx);
   for (int i = 1; i < string.length(); i++) {
     __ mov(ebx, Immediate(string.at(i)));
-    StringHelper::GenerateHashAddCharacter(assm, eax, ebx, ecx);
+    StringHelper::GenerateHashAddCharacter(masm, eax, ebx, ecx);
   }
-  StringHelper::GenerateHashGetHash(assm, eax, ecx);
+  StringHelper::GenerateHashGetHash(masm, eax, ecx);
   __ pop(ecx);
   __ pop(ebx);
   __ Ret();
 #elif V8_TARGET_ARCH_X64
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
   __ push(rbx);
   __ push(rcx);
   __ movq(rax, Immediate(0));
-  if (string.length() > 0) {
-    __ movq(rbx, Immediate(string.at(0)));
-    StringHelper::GenerateHashInit(assm, rax, rbx, rcx);
-  }
+  __ movq(rbx, Immediate(string.at(0)));
+  StringHelper::GenerateHashInit(masm, rax, rbx, rcx);
   for (int i = 1; i < string.length(); i++) {
     __ movq(rbx, Immediate(string.at(i)));
-    StringHelper::GenerateHashAddCharacter(assm, rax, rbx, rcx);
+    StringHelper::GenerateHashAddCharacter(masm, rax, rbx, rcx);
   }
-  StringHelper::GenerateHashGetHash(assm, rax, rcx);
+  StringHelper::GenerateHashGetHash(masm, rax, rcx);
   __ pop(rcx);
   __ pop(rbx);
+  __ pop(kRootRegister);
   __ Ret();
 #elif V8_TARGET_ARCH_ARM
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
+
   __ mov(r0, Operand(0));
-  if (string.length() > 0) {
-    __ mov(ip, Operand(string.at(0)));
-    StringHelper::GenerateHashInit(assm, r0, ip);
-  }
+  __ mov(ip, Operand(string.at(0)));
+  StringHelper::GenerateHashInit(masm, r0, ip);
   for (int i = 1; i < string.length(); i++) {
     __ mov(ip, Operand(string.at(i)));
-    StringHelper::GenerateHashAddCharacter(assm, r0, ip);
+    StringHelper::GenerateHashAddCharacter(masm, r0, ip);
   }
-  StringHelper::GenerateHashGetHash(assm, r0);
+  StringHelper::GenerateHashGetHash(masm, r0);
+  __ pop(kRootRegister);
   __ mov(pc, Operand(lr));
 #elif V8_TARGET_ARCH_MIPS
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
+
   __ li(v0, Operand(0));
-  if (string.length() > 0) {
-    __ li(t1, Operand(string.at(0)));
-    StringHelper::GenerateHashInit(assm, v0, t1);
-  }
+  __ li(t1, Operand(string.at(0)));
+  StringHelper::GenerateHashInit(masm, v0, t1);
   for (int i = 1; i < string.length(); i++) {
     __ li(t1, Operand(string.at(i)));
-    StringHelper::GenerateHashAddCharacter(assm, v0, t1);
+    StringHelper::GenerateHashAddCharacter(masm, v0, t1);
   }
-  StringHelper::GenerateHashGetHash(assm, v0);
+  StringHelper::GenerateHashGetHash(masm, v0);
+  __ pop(kRootRegister);
+  __ jr(ra);
+  __ nop();
+#endif
+}
+
+
+void generate(MacroAssembler* masm, uint32_t key) {
+#ifdef V8_TARGET_ARCH_IA32
+  __ push(ebx);
+  __ mov(eax, Immediate(key));
+  __ GetNumberHash(eax, ebx);
+  __ pop(ebx);
+  __ Ret();
+#elif V8_TARGET_ARCH_X64
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
+  __ push(rbx);
+  __ movq(rax, Immediate(key));
+  __ GetNumberHash(rax, rbx);
+  __ pop(rbx);
+  __ pop(kRootRegister);
+  __ Ret();
+#elif V8_TARGET_ARCH_ARM
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
+  __ mov(r0, Operand(key));
+  __ GetNumberHash(r0, ip);
+  __ pop(kRootRegister);
+  __ mov(pc, Operand(lr));
+#elif V8_TARGET_ARCH_MIPS
+  __ push(kRootRegister);
+  __ InitializeRootRegister();
+  __ li(v0, Operand(key));
+  __ GetNumberHash(v0, t1);
+  __ pop(kRootRegister);
   __ jr(ra);
   __ nop();
 #endif
@@ -114,12 +155,12 @@
 void check(i::Vector<const char> string) {
   v8::HandleScope scope;
   v8::internal::byte buffer[2048];
-  MacroAssembler assm(Isolate::Current(), buffer, sizeof buffer);
+  MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
 
-  generate(&assm, string);
+  generate(&masm, string);
 
   CodeDesc desc;
-  assm.GetCode(&desc);
+  masm.GetCode(&desc);
   Code* code = Code::cast(HEAP->CreateCode(
       desc,
       Code::ComputeFlags(Code::STUB),
@@ -140,12 +181,47 @@
 }
 
 
+void check(uint32_t key) {
+  v8::HandleScope scope;
+  v8::internal::byte buffer[2048];
+  MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
+
+  generate(&masm, key);
+
+  CodeDesc desc;
+  masm.GetCode(&desc);
+  Code* code = Code::cast(HEAP->CreateCode(
+      desc,
+      Code::ComputeFlags(Code::STUB),
+      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
+  CHECK(code->IsCode());
+
+  HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(code->entry());
+#ifdef USE_SIMULATOR
+  uint32_t codegen_hash =
+      reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0));
+#else
+  uint32_t codegen_hash = hash();
+#endif
+
+  uint32_t runtime_hash = ComputeIntegerHash(
+      key,
+      Isolate::Current()->heap()->HashSeed());
+  CHECK(runtime_hash == codegen_hash);
+}
+
+
 void check_twochars(char a, char b) {
   char ab[2] = {a, b};
   check(i::Vector<const char>(ab, 2));
 }
 
 
+static uint32_t PseudoRandom(uint32_t i, uint32_t j) {
+  return ~(~((i * 781) ^ (j * 329)));
+}
+
+
 TEST(StringHash) {
   if (env.IsEmpty()) env = v8::Context::New();
   for (int a = 0; a < String::kMaxAsciiCharCode; a++) {
@@ -156,7 +232,6 @@
       check_twochars(static_cast<char>(a), static_cast<char>(b));
     }
   }
-  check(i::Vector<const char>("",        0));
   check(i::Vector<const char>("*",       1));
   check(i::Vector<const char>(".zZ",     3));
   check(i::Vector<const char>("muc",     3));
@@ -164,4 +239,22 @@
   check(i::Vector<const char>("-=[ vee eight ftw ]=-", 21));
 }
 
+
+TEST(NumberHash) {
+  if (env.IsEmpty()) env = v8::Context::New();
+
+  // Some specific numbers
+  for (uint32_t key = 0; key < 42; key += 7) {
+    check(key);
+  }
+
+  // Some pseudo-random numbers
+  static const uint32_t kLimit = 1000;
+  for (uint32_t i = 0; i < 5; i++) {
+    for (uint32_t j = 0; j < 5; j++) {
+      check(PseudoRandom(i, j) % kLimit);
+    }
+  }
+}
+
 #undef __
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 42b5789..1e4e332 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1187,6 +1187,44 @@
 }
 
 
+TEST(TestSizeOfObjects) {
+  v8::V8::Initialize();
+
+  // Get initial heap size after several full GCs, which will stabilize
+  // the heap size and return with sweeping finished completely.
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
+  int initial_size = static_cast<int>(HEAP->SizeOfObjects());
+
+  {
+    // Allocate objects on several different old-space pages so that
+    // lazy sweeping kicks in for subsequent GC runs.
+    AlwaysAllocateScope always_allocate;
+    int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
+    for (int i = 1; i <= 100; i++) {
+      HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
+      CHECK_EQ(initial_size + i * filler_size,
+               static_cast<int>(HEAP->SizeOfObjects()));
+    }
+  }
+
+  // The heap size should go back to initial size after a full GC, even
+  // though sweeping didn't finish yet.
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
+  CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+
+  // Advancing the sweeper step-wise should not change the heap size.
+  while (!HEAP->old_pointer_space()->IsSweepingComplete()) {
+    HEAP->old_pointer_space()->AdvanceSweeper(KB);
+    CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+  }
+}
+
+
 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
   InitializeVM();
   HEAP->EnsureHeapIsIterable();
@@ -1476,3 +1514,61 @@
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(0, NumberOfGlobalObjects());
 }
+
+
+TEST(InstanceOfStubWriteBarrier) {
+  i::FLAG_allow_natives_syntax = true;
+#ifdef DEBUG
+  i::FLAG_verify_heap = true;
+#endif
+  InitializeVM();
+  if (!i::V8::UseCrankshaft()) return;
+  v8::HandleScope outer_scope;
+
+  {
+    v8::HandleScope scope;
+    CompileRun(
+        "function foo () { }"
+        "function mkbar () { return new (new Function(\"\")) (); }"
+        "function f (x) { return (x instanceof foo); }"
+        "function g () { f(mkbar()); }"
+        "f(new foo()); f(new foo());"
+        "%OptimizeFunctionOnNextCall(f);"
+        "f(new foo()); g();");
+  }
+
+  IncrementalMarking* marking = HEAP->incremental_marking();
+  marking->Abort();
+  marking->Start();
+
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+  CHECK(f->IsOptimized());
+
+  while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) &&
+         !marking->IsStopped()) {
+    marking->Step(MB);
+  }
+
+  CHECK(marking->IsMarking());
+
+  // Discard any pending GC requests otherwise we will get GC when we enter
+  // code below.
+  if (ISOLATE->stack_guard()->IsGCRequest()) {
+    ISOLATE->stack_guard()->Continue(GC_REQUEST);
+  }
+
+  {
+    v8::HandleScope scope;
+    v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
+    v8::Handle<v8::Function> g =
+        v8::Handle<v8::Function>::Cast(global->Get(v8_str("g")));
+    g->Call(global, 0, NULL);
+  }
+
+  HEAP->incremental_marking()->set_should_hurry(true);
+  HEAP->CollectGarbage(OLD_POINTER_SPACE);
+}
diff --git a/test/cctest/test-platform-linux.cc b/test/cctest/test-platform-linux.cc
index 756b947..2a8d497 100644
--- a/test/cctest/test-platform-linux.cc
+++ b/test/cctest/test-platform-linux.cc
@@ -67,7 +67,7 @@
 
 
 TEST(VirtualMemory) {
-  OS::Setup();
+  OS::SetUp();
   VirtualMemory* vm = new VirtualMemory(1 * MB);
   CHECK(vm->IsReserved());
   void* block_addr = vm->address();
diff --git a/test/cctest/test-platform-win32.cc b/test/cctest/test-platform-win32.cc
index 9bd0014..36b30aa 100644
--- a/test/cctest/test-platform-win32.cc
+++ b/test/cctest/test-platform-win32.cc
@@ -13,7 +13,7 @@
 
 
 TEST(VirtualMemory) {
-  OS::Setup();
+  OS::SetUp();
   VirtualMemory* vm = new VirtualMemory(1 * MB);
   CHECK(vm->IsReserved());
   void* block_addr = vm->address();
diff --git a/test/cctest/test-sockets.cc b/test/cctest/test-sockets.cc
index 4af55db..ad73540 100644
--- a/test/cctest/test-sockets.cc
+++ b/test/cctest/test-sockets.cc
@@ -129,7 +129,7 @@
   bool ok;
 
   // Initialize socket support.
-  ok = Socket::Setup();
+  ok = Socket::SetUp();
   CHECK(ok);
 
   // Send and receive some data.
diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc
index ee60086..6e495bc 100644
--- a/test/cctest/test-spaces.cc
+++ b/test/cctest/test-spaces.cc
@@ -125,14 +125,14 @@
 
 
 TEST(MemoryAllocator) {
-  OS::Setup();
+  OS::SetUp();
   Isolate* isolate = Isolate::Current();
   isolate->InitializeLoggingAndCounters();
   Heap* heap = isolate->heap();
   CHECK(isolate->heap()->ConfigureHeapDefault());
 
   MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
-  CHECK(memory_allocator->Setup(heap->MaxReserved(),
+  CHECK(memory_allocator->SetUp(heap->MaxReserved(),
                                 heap->MaxExecutableSize()));
 
   int total_pages = 0;
@@ -175,21 +175,21 @@
 
 
 TEST(NewSpace) {
-  OS::Setup();
+  OS::SetUp();
   Isolate* isolate = Isolate::Current();
   isolate->InitializeLoggingAndCounters();
   Heap* heap = isolate->heap();
   CHECK(heap->ConfigureHeapDefault());
   MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
-  CHECK(memory_allocator->Setup(heap->MaxReserved(),
+  CHECK(memory_allocator->SetUp(heap->MaxReserved(),
                                 heap->MaxExecutableSize()));
   TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
 
   NewSpace new_space(heap);
 
-  CHECK(new_space.Setup(HEAP->ReservedSemiSpaceSize(),
+  CHECK(new_space.SetUp(HEAP->ReservedSemiSpaceSize(),
                         HEAP->ReservedSemiSpaceSize()));
-  CHECK(new_space.HasBeenSetup());
+  CHECK(new_space.HasBeenSetUp());
 
   while (new_space.Available() >= Page::kMaxHeapObjectSize) {
     Object* obj =
@@ -204,13 +204,13 @@
 
 
 TEST(OldSpace) {
-  OS::Setup();
+  OS::SetUp();
   Isolate* isolate = Isolate::Current();
   isolate->InitializeLoggingAndCounters();
   Heap* heap = isolate->heap();
   CHECK(heap->ConfigureHeapDefault());
   MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
-  CHECK(memory_allocator->Setup(heap->MaxReserved(),
+  CHECK(memory_allocator->SetUp(heap->MaxReserved(),
                                 heap->MaxExecutableSize()));
   TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
 
@@ -220,7 +220,7 @@
                              NOT_EXECUTABLE);
   CHECK(s != NULL);
 
-  CHECK(s->Setup());
+  CHECK(s->SetUp());
 
   while (s->Available() > 0) {
     s->AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked();
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index e4f70df..df8ff72 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -105,7 +105,7 @@
 
 TEST(MemCopy) {
   v8::V8::Initialize();
-  OS::Setup();
+  OS::SetUp();
   const int N = OS::kMinComplexMemCopy + 128;
   Vector<byte> buffer1 = Vector<byte>::New(N);
   Vector<byte> buffer2 = Vector<byte>::New(N);
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 81c6cfe..72cfd85 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -43,6 +43,50 @@
 assertEquals(0, a[0]);
 assertEquals(0, a[1]);
 
+// No-parameter constructor should fail right now.
+function abfunc1() {
+  return new ArrayBuffer();
+}
+assertThrows(abfunc1);
+
+// Test derivation from an ArrayBuffer
+var ab = new ArrayBuffer(12);
+var derived_uint8 = new Uint8Array(ab);
+assertEquals(12, derived_uint8.length);
+var derived_uint32 = new Uint32Array(ab);
+assertEquals(3, derived_uint32.length);
+var derived_uint32_2 = new Uint32Array(ab,4);
+assertEquals(2, derived_uint32_2.length);
+var derived_uint32_3 = new Uint32Array(ab,4,1);
+assertEquals(1, derived_uint32_3.length);
+
+// If a given byteOffset and length references an area beyond the end of the
+// ArrayBuffer an exception is raised.
+function abfunc3() {
+  new Uint32Array(ab,4,3);
+}
+assertThrows(abfunc3);
+function abfunc4() {
+  new Uint32Array(ab,16);
+}
+assertThrows(abfunc4);
+
+// The given byteOffset must be a multiple of the element size of the specific
+// type, otherwise an exception is raised.
+function abfunc5() {
+  new Uint32Array(ab,5);
+}
+assertThrows(abfunc5);
+
+// If length is not explicitly specified, the length of the ArrayBuffer minus
+// the byteOffset must be a multiple of the element size of the specific type,
+// or an exception is raised.
+var ab2 = new ArrayBuffer(13);
+function abfunc6() {
+  new Uint32Array(ab2,4);
+}
+assertThrows(abfunc6);
+
 // Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
 // "constant", but not read-only).
 a = new Int32Array(2);
diff --git a/test/mjsunit/math-min-max.js b/test/mjsunit/math-min-max.js
index 0833c5c..7717b3b 100644
--- a/test/mjsunit/math-min-max.js
+++ b/test/mjsunit/math-min-max.js
@@ -115,3 +115,67 @@
 
 assertEquals(Infinity, 1/Math.max(ZERO, -0));
 assertEquals(Infinity, 1/Math.max(-0, ZERO));
+
+function run(crankshaft_test) {
+  crankshaft_test(1);
+  crankshaft_test(1);
+  %OptimizeFunctionOnNextCall(crankshaft_test);
+  crankshaft_test(-0);
+}
+
+function crankshaft_test_1(arg) {
+  var v1 = 1;
+  var v2 = 5;
+  var v3 = 1.5;
+  var v4 = 5.5;
+  var v5 = 2;
+  var v6 = 6;
+  var v7 = 0;
+  var v8 = -0;
+
+  var v9 = 9.9;
+  var v0 = 10.1;
+  // Integer32 representation.
+  assertEquals(v2, Math.max(v1++, v2++));
+  assertEquals(v1, Math.min(v1++, v2++));
+  // Tagged representation.
+  assertEquals(v4, Math.max(v3, v4));
+  assertEquals(v3, Math.min(v3, v4));
+  assertEquals(v6, Math.max(v5, v6));
+  assertEquals(v5, Math.min(v5, v6));
+  // Double representation.
+  assertEquals(v0, Math.max(v0++, v9++));
+  assertEquals(v9, Math.min(v0++, v9++));
+  // Minus zero.
+  assertEquals(Infinity, 1/Math.max(v7, v8));
+  assertEquals(-Infinity, 1/Math.min(v7, v8));
+  // NaN.
+  assertEquals(NaN, Math.max(NaN, v8));
+  assertEquals(NaN, Math.min(NaN, v9));
+  assertEquals(NaN, Math.max(v8, NaN));
+  assertEquals(NaN, Math.min(v9, NaN));
+  // Minus zero as Integer32.
+  assertEquals((arg === -0) ? -Infinity : 1, 1/Math.min(arg, v2));
+}
+
+run(crankshaft_test_1);
+
+function crankshaft_test_2() {
+  var v9 = {};
+  v9.valueOf = function() { return 6; }
+  // Deopt expected due to non-heapnumber objects.
+  assertEquals(6, Math.min(v9, 12));
+}
+
+run(crankshaft_test_2);
+
+// Test overriding Math.min and Math.max
+Math.min = function(a, b) { return a + b; }
+Math.max = function(a, b) { return a - b; }
+
+function crankshaft_test_3() {
+  assertEquals(8, Math.min(3, 5));
+  assertEquals(3, Math.max(5, 2));
+}
+
+run(crankshaft_test_3);
diff --git a/test/mjsunit/regress/regress-109195.js b/test/mjsunit/regress/regress-109195.js
new file mode 100644
index 0000000..97538aa
--- /dev/null
+++ b/test/mjsunit/regress/regress-109195.js
@@ -0,0 +1,65 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+  for (var i = 0, n = exec_state.frameCount(); i < n; i++) {
+    exec_state.frame().scopeCount(i);
+  }
+  exec_state.prepareStep(Debug.StepAction.Continue, 1);
+}
+
+Debug.setListener(listener);
+
+var F = function () {
+  1, function () {
+    var d = 0;
+    (function () { d; });
+    debugger;
+  }();
+};
+
+var src = "(" + F.toString() + ")()";
+eval(src);
+
+Function.prototype.__defineGetter__("f", function () {
+  debugger;
+  return 0;
+});
+
+var G = function () {
+  1, function () {
+    var d = 0;
+    (function () { d; });
+    debugger;
+  }['f'];
+};
+
+var src = "(" + G.toString() + ")()";
+eval(src);
diff --git a/test/mjsunit/regress/regress-1898.js b/test/mjsunit/regress/regress-1898.js
new file mode 100644
index 0000000..5440446
--- /dev/null
+++ b/test/mjsunit/regress/regress-1898.js
@@ -0,0 +1,37 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+  Math.log(Math.min(0.1, Math.abs(x)));
+}
+
+f(0.1);
+f(0.1);
+%OptimizeFunctionOnNextCall(f);
+f(0.1);