update V8 to TOT snapshot branch
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 0a392eb..db16bfc 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -394,6 +394,9 @@
     v8::HandleScope scope;
     LocalContext env;
     Local<String> source = String::New(two_byte_source);
+    // Trigger GCs so that the newly allocated string moves to old gen.
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(new TestResource(two_byte_source));
     CHECK(success);
     Local<Script> script = Script::Compile(source);
@@ -416,6 +419,9 @@
     v8::HandleScope scope;
     LocalContext env;
     Local<String> source = v8_str(c_source);
+    // Trigger GCs so that the newly allocated string moves to old gen.
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(
         new TestAsciiResource(i::StrDup(c_source)));
     CHECK(success);
@@ -432,6 +438,80 @@
 }
 
 
+TEST(MakingExternalStringConditions) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  // Free some space in the new space so that we can check freshness.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+
+  Local<String> small_string = String::New(AsciiToTwoByteString("small"));
+  // We should refuse to externalize newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  // Trigger GCs so that the newly allocated string moves to old gen.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  // Old space strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  small_string = String::New(AsciiToTwoByteString("small 2"));
+  // We should refuse externalizing newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  for (int i = 0; i < 100; i++) {
+    String::Value value(small_string);
+  }
+  // Frequently used strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  const int buf_size = 10 * 1024;
+  char* buf = i::NewArray<char>(buf_size);
+  memset(buf, 'a', buf_size);
+  buf[buf_size - 1] = '\0';
+  Local<String> large_string = String::New(AsciiToTwoByteString(buf));
+  i::DeleteArray(buf);
+  // Large strings should be immediately accepted.
+  CHECK(large_string->CanMakeExternal());
+}
+
+
+TEST(MakingExternalAsciiStringConditions) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  // Free some space in the new space so that we can check freshness.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+
+  Local<String> small_string = String::New("small");
+  // We should refuse to externalize newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  // Trigger GCs so that the newly allocated string moves to old gen.
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  // Old space strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  small_string = String::New("small 2");
+  // We should refuse externalizing newly created small string.
+  CHECK(!small_string->CanMakeExternal());
+  for (int i = 0; i < 100; i++) {
+    String::Value value(small_string);
+  }
+  // Frequently used strings should be accepted.
+  CHECK(small_string->CanMakeExternal());
+
+  const int buf_size = 10 * 1024;
+  char* buf = i::NewArray<char>(buf_size);
+  memset(buf, 'a', buf_size);
+  buf[buf_size - 1] = '\0';
+  Local<String> large_string = String::New(buf);
+  i::DeleteArray(buf);
+  // Large strings should be immediately accepted.
+  CHECK(large_string->CanMakeExternal());
+}
+
+
 THREADED_TEST(UsingExternalString) {
   {
     v8::HandleScope scope;
@@ -2448,6 +2528,33 @@
 }
 
 
+static v8::Handle<Value> SetXOnPrototypeGetter(Local<String> property,
+                                               const AccessorInfo& info) {
+  // Set x on the prototype object and do not handle the get request.
+  v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
+  v8::Handle<v8::Object>::Cast(proto)->Set(v8_str("x"), v8::Integer::New(23));
+  return v8::Handle<Value>();
+}
+
+
+// This is a regression test for http://crbug.com/20104. Map
+// transitions should not interfere with post interceptor lookup.
+THREADED_TEST(NamedInterceptorMapTransitionRead) {
+  v8::HandleScope scope;
+  Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New();
+  Local<v8::ObjectTemplate> instance_template
+      = function_template->InstanceTemplate();
+  instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
+  LocalContext context;
+  context->Global()->Set(v8_str("F"), function_template->GetFunction());
+  // Create an instance of F and introduce a map transition for x.
+  CompileRun("var o = new F(); o.x = 23;");
+  // Create an instance of F and invoke the getter. The result should be 23.
+  Local<Value> result = CompileRun("o = new F(); o.x");
+  CHECK_EQ(result->Int32Value(), 23);
+}
+
+
 static v8::Handle<Value> IndexedPropertyGetter(uint32_t index,
                                                const AccessorInfo& info) {
   ApiTestFuzzer::Fuzz();
@@ -2529,6 +2636,195 @@
 }
 
 
+THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  obj->TurnOnAccessCheck();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = obj[0];"
+      "    if (v != undefined) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 5) {"
+      "      %EnableAccessChecks(obj);"
+      "      expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 5) %DisableAccessChecks(obj);"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = obj[i];"
+      "    if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 50) {"
+      "       i = 'foobar';"
+      "       expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorGoingMegamorphic) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var original = obj;"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 50) {"
+      "       obj = {50: 'foobar'};"
+      "       expected = 'foobar';"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 50) obj = original;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorReceiverTurningSmi) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var original = obj;"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    if (i == 5) {"
+      "       obj = 239;"
+      "       expected = undefined;"
+      "    }"
+      "    var v = obj[i];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "    if (i == 5) obj = original;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
+THREADED_TEST(IndexedInterceptorOnProto) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "var o = {__proto__: obj};"
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var v = o[i];"
+      "    if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
 THREADED_TEST(MultiContexts) {
   v8::HandleScope scope;
   v8::Handle<ObjectTemplate> templ = ObjectTemplate::New();
@@ -4844,6 +5140,84 @@
 }
 
 
+THREADED_TEST(SetPrototype) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
+  t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->SetHiddenPrototype(true);
+  t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1));
+  Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+  t2->SetHiddenPrototype(true);
+  t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2));
+  Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+  t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3));
+
+  Local<v8::Object> o0 = t0->GetFunction()->NewInstance();
+  Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
+  Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
+  Local<v8::Object> o3 = t3->GetFunction()->NewInstance();
+
+  // Setting the prototype on an object does not skip hidden prototypes.
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK(o0->SetPrototype(o1));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK(o1->SetPrototype(o2));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
+  CHECK(o2->SetPrototype(o3));
+  CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
+  CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
+  CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
+  CHECK_EQ(3, o0->Get(v8_str("u"))->Int32Value());
+
+  // Getting the prototype of o0 should get the first visible one
+  // which is o3.  Therefore, z should not be defined on the prototype
+  // object.
+  Local<Value> proto = o0->Get(v8_str("__proto__"));
+  CHECK(proto->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto), o3);
+
+  // However, Object::GetPrototype ignores hidden prototype.
+  Local<Value> proto0 = o0->GetPrototype();
+  CHECK(proto0->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto0), o1);
+
+  Local<Value> proto1 = o1->GetPrototype();
+  CHECK(proto1->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto1), o2);
+
+  Local<Value> proto2 = o2->GetPrototype();
+  CHECK(proto2->IsObject());
+  CHECK_EQ(v8::Handle<v8::Object>::Cast(proto2), o3);
+}
+
+
+THREADED_TEST(SetPrototypeThrows) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+
+  Local<v8::Object> o0 = t->GetFunction()->NewInstance();
+  Local<v8::Object> o1 = t->GetFunction()->NewInstance();
+
+  CHECK(o0->SetPrototype(o1));
+  // If setting the prototype leads to the cycle, SetPrototype should
+  // return false and keep VM in sane state.
+  v8::TryCatch try_catch;
+  CHECK(!o1->SetPrototype(o0));
+  CHECK(!try_catch.HasCaught());
+  ASSERT(!i::Top::has_pending_exception());
+
+  CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
+}
+
+
 THREADED_TEST(GetterSetterExceptions) {
   v8::HandleScope handle_scope;
   LocalContext context;
@@ -5078,7 +5452,7 @@
 
 
 static v8::Handle<Value> call_as_function(const v8::Arguments& args) {
-  //ApiTestFuzzer::Fuzz();
+  ApiTestFuzzer::Fuzz();
   if (args.IsConstructCall()) {
     if (args[0]->IsInt32()) {
        return v8_num(-args[0]->Int32Value());
@@ -5891,6 +6265,294 @@
   CHECK_EQ(239 * 10, value->Int32Value());
 }
 
+static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
+                                                  const AccessorInfo& info) {
+  ApiTestFuzzer::Fuzz();
+  int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
+  ++(*call_count);
+  if ((*call_count) % 20 == 0) {
+    v8::internal::Heap::CollectAllGarbage(true);
+  }
+  return v8::Handle<Value>();
+}
+
+static v8::Handle<Value> FastApiCallback_TrivialSignature(
+    const v8::Arguments& args) {
+  ApiTestFuzzer::Fuzz();
+  CHECK_EQ(args.This(), args.Holder());
+  CHECK(args.Data()->Equals(v8_str("method_data")));
+  return v8::Integer::New(args[0]->Int32Value() + 1);
+}
+
+static v8::Handle<Value> FastApiCallback_SimpleSignature(
+    const v8::Arguments& args) {
+  ApiTestFuzzer::Fuzz();
+  CHECK_EQ(args.This()->GetPrototype(), args.Holder());
+  CHECK(args.Data()->Equals(v8_str("method_data")));
+  // Note, we're using HasRealNamedProperty instead of Has to avoid
+  // invoking the interceptor again.
+  CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo")));
+  return v8::Integer::New(args[0]->Int32Value() + 1);
+}
+
+// Helper to maximize the odds of object moving.
+static void GenerateSomeGarbage() {
+  CompileRun(
+      "var garbage;"
+      "for (var i = 0; i < 1000; i++) {"
+      "  garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];"
+      "}"
+      "garbage = undefined;");
+}
+
+THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+                                v8_str("method_data"),
+                                v8::Handle<v8::Signature>());
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = o.method(41);"
+      "}");
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(100, interceptor_call_count);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "}");
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(100, interceptor_call_count);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: function(x) { return x - 1 }};"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    o.method = function(x) { return x - 1 };"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
+  int interceptor_call_count = 0;
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
+                                 NULL, NULL, NULL, NULL,
+                                 v8::External::Wrap(&interceptor_call_count));
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::TryCatch try_catch;
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: receiver.method};"
+      "  }"
+      "}");
+  CHECK(try_catch.HasCaught());
+  CHECK_EQ(v8_str("TypeError: Illegal invocation"),
+           try_catch.Exception()->ToString());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+  CHECK_GE(interceptor_call_count, 50);
+}
+
+THREADED_TEST(CallICFastApi_TrivialSignature) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+                                v8_str("method_data"),
+                                v8::Handle<v8::Signature>());
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = o.method(41);"
+      "}");
+
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+}
+
+THREADED_TEST(CallICFastApi_SimpleSignature) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "}");
+
+  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
+}
+
+THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
+  v8::HandleScope scope;
+  v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  v8::Handle<v8::FunctionTemplate> method_templ =
+      v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+                                v8_str("method_data"),
+                                v8::Signature::New(fun_templ));
+  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+  proto_templ->Set(v8_str("method"), method_templ);
+  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+  LocalContext context;
+  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+  GenerateSomeGarbage();
+  context->Global()->Set(v8_str("o"), fun->NewInstance());
+  v8::Handle<Value> value = CompileRun(
+      "o.foo = 17;"
+      "var receiver = {};"
+      "receiver.__proto__ = o;"
+      "var result = 0;"
+      "var saved_result = 0;"
+      "for (var i = 0; i < 100; i++) {"
+      "  result = receiver.method(41);"
+      "  if (i == 50) {"
+      "    saved_result = result;"
+      "    receiver = {method: function(x) { return x - 1 }};"
+      "  }"
+      "}");
+  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
+  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+}
+
 
 static int interceptor_call_count = 0;
 
@@ -8927,3 +9589,138 @@
 
   other_context.Dispose();
 }
+
+
+THREADED_TEST(ScriptOrigin) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  v8::Handle<v8::String> script = v8::String::New(
+      "function f() {}\n\nfunction g() {}");
+  v8::Script::Compile(script, &origin)->Run();
+  v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("f")));
+  v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("g")));
+
+  v8::ScriptOrigin script_origin_f = f->GetScriptOrigin();
+  CHECK_EQ("test", *v8::String::AsciiValue(script_origin_f.ResourceName()));
+  CHECK_EQ(0, script_origin_f.ResourceLineOffset()->Int32Value());
+
+  v8::ScriptOrigin script_origin_g = g->GetScriptOrigin();
+  CHECK_EQ("test", *v8::String::AsciiValue(script_origin_g.ResourceName()));
+  CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value());
+}
+
+
+THREADED_TEST(ScriptLineNumber) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  v8::Handle<v8::String> script = v8::String::New(
+      "function f() {}\n\nfunction g() {}");
+  v8::Script::Compile(script, &origin)->Run();
+  v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("f")));
+  v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("g")));
+  CHECK_EQ(0, f->GetScriptLineNumber());
+  CHECK_EQ(2, g->GetScriptLineNumber());
+}
+
+
+static v8::Handle<Value> GetterWhichReturns42(Local<String> name,
+                                              const AccessorInfo& info) {
+  return v8_num(42);
+}
+
+
+static void SetterWhichSetsYOnThisTo23(Local<String> name,
+                                       Local<Value> value,
+                                       const AccessorInfo& info) {
+  info.This()->Set(v8_str("y"), v8_num(23));
+}
+
+
+THREADED_TEST(SetterOnConstructorPrototype) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetAccessor(v8_str("x"),
+                     GetterWhichReturns42,
+                     SetterWhichSetsYOnThisTo23);
+  LocalContext context;
+  context->Global()->Set(v8_str("P"), templ->NewInstance());
+  CompileRun("function C1() {"
+             "  this.x = 23;"
+             "};"
+             "C1.prototype = P;"
+             "function C2() {"
+             "  this.x = 23"
+             "};"
+             "C2.prototype = { };"
+             "C2.prototype.__proto__ = P;");
+
+  v8::Local<v8::Script> script;
+  script = v8::Script::Compile(v8_str("new C1();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value());
+  }
+
+  script = v8::Script::Compile(v8_str("new C2();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(42, c2->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(23, c2->Get(v8_str("y"))->Int32Value());
+  }
+}
+
+
+static v8::Handle<Value> NamedPropertyGetterWhichReturns42(
+    Local<String> name, const AccessorInfo& info) {
+  return v8_num(42);
+}
+
+
+static v8::Handle<Value> NamedPropertySetterWhichSetsYOnThisTo23(
+    Local<String> name, Local<Value> value, const AccessorInfo& info) {
+  if (name->Equals(v8_str("x"))) {
+    info.This()->Set(v8_str("y"), v8_num(23));
+  }
+  return v8::Handle<Value>();
+}
+
+
+THREADED_TEST(InterceptorOnConstructorPrototype) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
+                                 NamedPropertySetterWhichSetsYOnThisTo23);
+  LocalContext context;
+  context->Global()->Set(v8_str("P"), templ->NewInstance());
+  CompileRun("function C1() {"
+             "  this.x = 23;"
+             "};"
+             "C1.prototype = P;"
+             "function C2() {"
+             "  this.x = 23"
+             "};"
+             "C2.prototype = { };"
+             "C2.prototype.__proto__ = P;");
+
+  v8::Local<v8::Script> script;
+  script = v8::Script::Compile(v8_str("new C1();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value());
+  }
+
+  script = v8::Script::Compile(v8_str("new C2();"));
+  for (int i = 0; i < 10; i++) {
+    v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
+    CHECK_EQ(23, c2->Get(v8_str("x"))->Int32Value());
+    CHECK_EQ(42, c2->Get(v8_str("y"))->Int32Value());
+  }
+}
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
new file mode 100644
index 0000000..ab011a7
--- /dev/null
+++ b/test/cctest/test-assembler-mips.cc
@@ -0,0 +1,257 @@
+// 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.
+
+#include "v8.h"
+
+#include "disassembler.h"
+#include "factory.h"
+#include "macro-assembler.h"
+#include "mips/macro-assembler-mips.h"
+#include "mips/simulator-mips.h"
+
+#include "cctest.h"
+
+using namespace v8::internal;
+
+
+// Define these function prototypes to match JSEntryFunction in execution.cc.
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
+typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+
+
+static v8::Persistent<v8::Context> env;
+
+
+// The test framework does not accept flags on the command line, so we set them.
+static void InitializeVM() {
+  // Disable compilation of natives by specifying an empty natives file.
+  FLAG_natives_file = "";
+
+  // Enable generation of comments.
+  FLAG_debug_code = true;
+
+  if (env.IsEmpty()) {
+    env = v8::Context::New();
+  }
+}
+
+
+#define __ assm.
+
+TEST(MIPS0) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+
+  // Addition.
+  __ addu(v0, a0, a1);
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(0xabc, res);
+}
+
+
+TEST(MIPS1) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+  Label L, C;
+
+  __ mov(a1, a0);
+  __ li(v0, 0);
+  __ b(&C);
+  __ nop();
+
+  __ bind(&L);
+  __ add(v0, v0, a1);
+  __ addiu(a1, a1, -1);
+
+  __ bind(&C);
+  __ xori(v1, a1, 0);
+  __ Branch(ne, &L, v1, Operand(0));
+  __ nop();
+
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(1275, res);
+}
+
+
+TEST(MIPS2) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  MacroAssembler assm(NULL, 0);
+
+  Label exit, error;
+
+  // ----- Test all instructions.
+
+  // Test lui, ori, and addiu, used in the li pseudo-instruction.
+  // This way we can then safely load registers with chosen values.
+
+  __ ori(t0, zero_reg, 0);
+  __ lui(t0, 0x1234);
+  __ ori(t0, t0, 0);
+  __ ori(t0, t0, 0x0f0f);
+  __ ori(t0, t0, 0xf0f0);
+  __ addiu(t1, t0, 1);
+  __ addiu(t2, t1, -0x10);
+
+  // Load values in temporary registers.
+  __ li(t0, 0x00000004);
+  __ li(t1, 0x00001234);
+  __ li(t2, 0x12345678);
+  __ li(t3, 0x7fffffff);
+  __ li(t4, 0xfffffffc);
+  __ li(t5, 0xffffedcc);
+  __ li(t6, 0xedcba988);
+  __ li(t7, 0x80000000);
+
+  // SPECIAL class.
+  __ srl(v0, t2, 8);    // 0x00123456
+  __ sll(v0, v0, 11);   // 0x91a2b000
+  __ sra(v0, v0, 3);    // 0xf2345600
+  __ srav(v0, v0, t0);  // 0xff234560
+  __ sllv(v0, v0, t0);  // 0xf2345600
+  __ srlv(v0, v0, t0);  // 0x0f234560
+  __ Branch(ne, &error, v0, Operand(0x0f234560));
+  __ nop();
+
+  __ add(v0, t0, t1);   // 0x00001238
+  __ sub(v0, v0, t0);   // 0x00001234
+  __ Branch(ne, &error, v0, Operand(0x00001234));
+  __ nop();
+  __ addu(v1, t3, t0);
+  __ Branch(ne, &error, v1, Operand(0x80000003));
+  __ nop();
+  __ subu(v1, t7, t0);  // 0x7ffffffc
+  __ Branch(ne, &error, v1, Operand(0x7ffffffc));
+  __ nop();
+
+  __ and_(v0, t1, t2);  // 0x00001230
+  __ or_(v0, v0, t1);   // 0x00001234
+  __ xor_(v0, v0, t2);  // 0x1234444c
+  __ nor(v0, v0, t2);   // 0xedcba987
+  __ Branch(ne, &error, v0, Operand(0xedcba983));
+  __ nop();
+
+  __ slt(v0, t7, t3);
+  __ Branch(ne, &error, v0, Operand(0x1));
+  __ nop();
+  __ sltu(v0, t7, t3);
+  __ Branch(ne, &error, v0, Operand(0x0));
+  __ nop();
+  // End of SPECIAL class.
+
+  __ addi(v0, zero_reg, 0x7421);  // 0x00007421
+  __ addi(v0, v0, -0x1);  // 0x00007420
+  __ addiu(v0, v0, -0x20);  // 0x00007400
+  __ Branch(ne, &error, v0, Operand(0x00007400));
+  __ nop();
+  __ addiu(v1, t3, 0x1);  // 0x80000000
+  __ Branch(ne, &error, v1, Operand(0x80000000));
+  __ nop();
+
+  __ slti(v0, t1, 0x00002000);  // 0x1
+  __ slti(v0, v0, 0xffff8000);  // 0x0
+  __ Branch(ne, &error, v0, Operand(0x0));
+  __ nop();
+  __ sltiu(v0, t1, 0x00002000);  // 0x1
+  __ sltiu(v0, v0, 0x00008000);  // 0x1
+  __ Branch(ne, &error, v0, Operand(0x1));
+  __ nop();
+
+  __ andi(v0, t1, 0xf0f0);  // 0x00001030
+  __ ori(v0, v0, 0x8a00);  // 0x00009a30
+  __ xori(v0, v0, 0x83cc);  // 0x000019fc
+  __ Branch(ne, &error, v0, Operand(0x000019fc));
+  __ nop();
+  __ lui(v1, 0x8123);  // 0x81230000
+  __ Branch(ne, &error, v1, Operand(0x81230000));
+  __ nop();
+
+  // Everything was correctly executed. Load the expected result.
+  __ li(v0, 0x31415926);
+  __ b(&exit);
+  __ nop();
+
+  __ bind(&error);
+  // Got an error. Return a wrong result.
+
+  __ bind(&exit);
+  __ jr(ra);
+  __ nop();
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
+  CHECK(code->IsCode());
+#ifdef DEBUG
+  Code::cast(code)->Print();
+#endif
+  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
+  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+  ::printf("f() = %d\n", res);
+  CHECK_EQ(0x31415926, res);
+}
+
+#undef __
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index b5f12b9..471753c 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -120,6 +120,7 @@
                                                      0,
                                                      NULL,
                                                      NULL,
+                                                     Handle<String>::null(),
                                                      NOT_NATIVES_CODE);
   return Factory::NewFunctionFromBoilerplate(boilerplate,
                                              Top::global_context());
@@ -322,3 +323,27 @@
   CHECK_EQ(-1, GetScriptLineNumber(script, 100));
   CHECK_EQ(-1, GetScriptLineNumber(script, -1));
 }
+
+
+TEST(GetScriptLineNumber) {
+  LocalContext env;
+  v8::HandleScope scope;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  const char function_f[] = "function f() {}";
+  const int max_rows = 1000;
+  const int buffer_size = max_rows + sizeof(function_f);
+  ScopedVector<char> buffer(buffer_size);
+  memset(buffer.start(), '\n', buffer_size - 1);
+  buffer[buffer_size - 1] = '\0';
+
+  for (int i = 0; i < max_rows; ++i) {
+    if (i > 0)
+      buffer[i - 1] = '\n';
+    memcpy(&buffer[i], function_f, sizeof(function_f) - 1);
+    v8::Handle<v8::String> script_body = v8::String::New(buffer.start());
+    v8::Script::Compile(script_body, &origin)->Run();
+    v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+        env->Global()->Get(v8::String::New("f")));
+    CHECK_EQ(i, f->GetScriptLineNumber());
+  }
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 92e18e0..b7c39b2 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -550,6 +550,15 @@
 v8::Local<v8::Function> frame_script_data;
 
 
+// Source for The JavaScript function which picks out the script data from
+// AfterCompile event
+const char* compiled_script_data_source =
+    "function compiled_script_data(event_data) {"
+    "  return event_data.script().data();"
+    "}";
+v8::Local<v8::Function> compiled_script_data;
+
+
 // Source for The JavaScript function which returns the number of frames.
 static const char* frame_count_source =
     "function frame_count(exec_state) {"
@@ -647,6 +656,19 @@
         script_data->WriteAscii(last_script_data_hit);
       }
     }
+  } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) {
+    const int argc = 1;
+    v8::Handle<v8::Value> argv[argc] = { event_data };
+    v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state,
+                                                              argc, argv);
+    if (result->IsUndefined()) {
+      last_script_data_hit[0] = '\0';
+    } else {
+      result = result->ToString();
+      CHECK(result->IsString());
+      v8::Handle<v8::String> script_data(result->ToString());
+      script_data->WriteAscii(last_script_data_hit);
+    }
   }
 }
 
@@ -3884,6 +3906,11 @@
 }
 
 
+static int StringToInt(const char* s) {
+  return atoi(s);  // NOLINT
+}
+
+
 // We match parts of the message to get evaluate result int value.
 int GetEvaluateIntResult(char *message) {
   const char* value = "\"value\":";
@@ -3892,7 +3919,7 @@
     return -1;
   }
   int res = -1;
-  res = atoi(pos + strlen(value));
+  res = StringToInt(pos + strlen(value));
   return res;
 }
 
@@ -3905,7 +3932,7 @@
     return -1;
   }
   int res = -1;
-  res = atoi(pos + strlen(breakpoints));
+  res = StringToInt(pos + strlen(breakpoints));
   return res;
 }
 
@@ -3918,11 +3945,7 @@
     return -1;
   }
   pos += strlen(prefix);
-  char* pos_end = pos;
-  int res = static_cast<int>(strtol(pos, &pos_end, 10));
-  if (pos_end == pos) {
-    return -1;
-  }
+  int res = StringToInt(pos);
   return res;
 }
 
@@ -5231,6 +5254,9 @@
   frame_script_data = CompileFunction(&env,
                                       frame_script_data_source,
                                       "frame_script_data");
+  compiled_script_data = CompileFunction(&env,
+                                         compiled_script_data_source,
+                                         "compiled_script_data");
 
   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
                                    v8::Undefined());
@@ -5277,6 +5303,16 @@
   CHECK_EQ(3, break_point_hit_count);
   CHECK_EQ("new name", last_script_name_hit);
   CHECK_EQ("abc 123", last_script_data_hit);
+
+  v8::Handle<v8::Script> script3 =
+      v8::Script::Compile(script, &origin2, NULL,
+                          v8::String::New("in compile"));
+  CHECK_EQ("in compile", last_script_data_hit);
+  script3->Run();
+  f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
+  f->Call(env->Global(), 0, NULL);
+  CHECK_EQ(4, break_point_hit_count);
+  CHECK_EQ("in compile", last_script_data_hit);
 }
 
 
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index eca2c2b..9853af3 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -170,21 +170,110 @@
 #endif  // __linux__
 
 
-static int CheckThatProfilerWorks(int log_pos) {
-  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU);
+namespace {
+
+class ScopedLoggerInitializer {
+ public:
+  explicit ScopedLoggerInitializer(bool log, bool prof_lazy)
+      : saved_log_(i::FLAG_log),
+        saved_prof_lazy_(i::FLAG_prof_lazy),
+        saved_prof_(i::FLAG_prof),
+        saved_prof_auto_(i::FLAG_prof_auto),
+        trick_to_run_init_flags_(init_flags_(log, prof_lazy)),
+        need_to_set_up_logger_(i::V8::IsRunning()),
+        scope_(),
+        env_(v8::Context::New()) {
+    if (need_to_set_up_logger_) Logger::Setup();
+    env_->Enter();
+  }
+
+  ~ScopedLoggerInitializer() {
+    env_->Exit();
+    Logger::TearDown();
+    i::FLAG_prof_lazy = saved_prof_lazy_;
+    i::FLAG_prof = saved_prof_;
+    i::FLAG_prof_auto = saved_prof_auto_;
+    i::FLAG_log = saved_log_;
+  }
+
+  v8::Handle<v8::Context>& env() { return env_; }
+
+ private:
+  static bool init_flags_(bool log, bool prof_lazy) {
+    i::FLAG_log = log;
+    i::FLAG_prof = true;
+    i::FLAG_prof_lazy = prof_lazy;
+    i::FLAG_prof_auto = false;
+    i::FLAG_logfile = "*";
+    return prof_lazy;
+  }
+
+  const bool saved_log_;
+  const bool saved_prof_lazy_;
+  const bool saved_prof_;
+  const bool saved_prof_auto_;
+  const bool trick_to_run_init_flags_;
+  const bool need_to_set_up_logger_;
+  v8::HandleScope scope_;
+  v8::Handle<v8::Context> env_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer);
+};
+
+
+class LogBufferMatcher {
+ public:
+  LogBufferMatcher() {
+    // Skip all initially logged stuff.
+    log_pos_ = GetLogLines(0, &buffer_);
+  }
+
+  int log_pos() { return log_pos_; }
+
+  int GetNextChunk() {
+    int chunk_size = GetLogLines(log_pos_, &buffer_);
+    CHECK_GT(buffer_.length(), chunk_size);
+    buffer_[chunk_size] = '\0';
+    log_pos_ += chunk_size;
+    return chunk_size;
+  }
+
+  const char* Find(const char* substr) {
+    return strstr(buffer_.start(), substr);
+  }
+
+  const char* Find(const i::Vector<char>& substr) {
+    return Find(substr.start());
+  }
+
+  bool IsInSequence(const char* s1, const char* s2) {
+    const char* s1_pos = Find(s1);
+    const char* s2_pos = Find(s2);
+    CHECK_NE(NULL, s1_pos);
+    CHECK_NE(NULL, s2_pos);
+    return s1_pos < s2_pos;
+  }
+
+  void PrintBuffer() {
+    puts(buffer_.start());
+  }
+
+ private:
+  EmbeddedVector<char, 102400> buffer_;
+  int log_pos_;
+};
+
+}  // namespace
+
+
+static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
   CHECK(LoggerTestHelper::IsSamplerActive());
 
   // Verify that the current map of compiled functions has been logged.
-  EmbeddedVector<char, 102400> buffer;
-  int map_log_size = GetLogLines(log_pos, &buffer);
-  printf("map_log_size: %d\n", map_log_size);
-  CHECK_GT(map_log_size, 0);
-  CHECK_GT(buffer.length(), map_log_size);
-  log_pos += map_log_size;
-  // Check buffer contents.
-  buffer[map_log_size] = '\0';
+  CHECK_GT(matcher->GetNextChunk(), 0);
   const char* code_creation = "\ncode-creation,";  // eq. to /^code-creation,/
-  CHECK_NE(NULL, strstr(buffer.start(), code_creation));
+  CHECK_NE(NULL, matcher->Find(code_creation));
 
 #ifdef __linux__
   // Intercept SIGPROF handler to make sure that the test process
@@ -204,7 +293,7 @@
   i::OS::SNPrintF(script_src,
                   "function f%d(x) { return %d * x; }"
                   "for (var i = 0; i < 10000; ++i) { f%d(i); }",
-                  log_pos, log_pos, log_pos);
+                  matcher->log_pos(), matcher->log_pos(), matcher->log_pos());
   // Run code for 200 msecs to get some ticks.
   const double end_time = i::OS::TimeCurrentMillis() + 200;
   while (i::OS::TimeCurrentMillis() < end_time) {
@@ -213,7 +302,7 @@
     i::OS::Sleep(1);
   }
 
-  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU);
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
   CHECK(!LoggerTestHelper::IsSamplerActive());
 
   // Wait 50 msecs to allow Profiler thread to process the last
@@ -221,68 +310,39 @@
   i::OS::Sleep(50);
 
   // Now we must have compiler and tick records.
-  int log_size = GetLogLines(log_pos, &buffer);
-  printf("log_size: %d\n", log_size);
-  CHECK_GT(log_size, 0);
-  CHECK_GT(buffer.length(), log_size);
-  log_pos += log_size;
-  // Check buffer contents.
-  buffer[log_size] = '\0';
-  printf("%s", buffer.start());
+  CHECK_GT(matcher->GetNextChunk(), 0);
+  matcher->PrintBuffer();
+  CHECK_NE(NULL, matcher->Find(code_creation));
   const char* tick = "\ntick,";
-  CHECK_NE(NULL, strstr(buffer.start(), code_creation));
-  const bool ticks_found = strstr(buffer.start(), tick) != NULL;
+  const bool ticks_found = matcher->Find(tick) != NULL;
   CHECK_EQ(was_sigprof_received, ticks_found);
-
-  return log_pos;
 }
 
 
 TEST(ProfLazyMode) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = true;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
+  ScopedLoggerInitializer initialize_logger(false, true);
 
   // No sampling should happen prior to resuming profiler.
   CHECK(!LoggerTestHelper::IsSamplerActive());
 
-  EmbeddedVector<char, 102400> buffer;
+  LogBufferMatcher matcher;
   // Nothing must be logged until profiling is resumed.
-  int log_pos = GetLogLines(0, &buffer);
-  CHECK_EQ(0, log_pos);
+  CHECK_EQ(0, matcher.log_pos());
 
   CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
 
   // Nothing must be logged while profiling is suspended.
-  CHECK_EQ(0, GetLogLines(log_pos, &buffer));
+  CHECK_EQ(0, matcher.GetNextChunk());
 
-  log_pos = CheckThatProfilerWorks(log_pos);
+  CheckThatProfilerWorks(&matcher);
 
   CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
 
   // No new data beyond last retrieved position.
-  CHECK_EQ(0, GetLogLines(log_pos, &buffer));
+  CHECK_EQ(0, matcher.GetNextChunk());
 
   // Check that profiling can be resumed again.
-  CheckThatProfilerWorks(log_pos);
-
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
+  CheckThatProfilerWorks(&matcher);
 }
 
 
@@ -480,25 +540,8 @@
 }
 
 TEST(LogCallbacks) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = false;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
-
-  // Skip all initially logged stuff.
-  EmbeddedVector<char, 102400> buffer;
-  int log_pos = GetLogLines(0, &buffer);
+  ScopedLoggerInitializer initialize_logger(false, false);
+  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
@@ -511,16 +554,14 @@
                                        signature),
              static_cast<v8::PropertyAttribute>(v8::DontDelete));
 
-  env->Global()->Set(v8_str("Obj"), obj->GetFunction());
+  initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
   CompileAndRunScript("Obj.prototype.method1.toString();");
 
   i::Logger::LogCompiledFunctions();
-  log_pos = GetLogLines(log_pos, &buffer);
-  CHECK_GT(log_pos, 0);
-  buffer[log_pos] = 0;
+  CHECK_GT(matcher.GetNextChunk(), 0);
 
   const char* callback_rec = "code-creation,Callback,";
-  char* pos = strstr(buffer.start(), callback_rec);
+  char* pos = const_cast<char*>(matcher.Find(callback_rec));
   CHECK_NE(NULL, pos);
   pos += strlen(callback_rec);
   EmbeddedVector<char, 100> ref_data;
@@ -530,12 +571,6 @@
   CHECK_EQ(ref_data.start(), pos);
 
   obj.Dispose();
-
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
 }
 
 
@@ -555,25 +590,8 @@
 }
 
 TEST(LogAccessorCallbacks) {
-  const bool saved_prof_lazy = i::FLAG_prof_lazy;
-  const bool saved_prof = i::FLAG_prof;
-  const bool saved_prof_auto = i::FLAG_prof_auto;
-  i::FLAG_prof = true;
-  i::FLAG_prof_lazy = false;
-  i::FLAG_prof_auto = false;
-  i::FLAG_logfile = "*";
-
-  // If tests are being run manually, V8 will be already initialized
-  // by the bottom test.
-  const bool need_to_set_up_logger = i::V8::IsRunning();
-  v8::HandleScope scope;
-  v8::Handle<v8::Context> env = v8::Context::New();
-  if (need_to_set_up_logger) Logger::Setup();
-  env->Enter();
-
-  // Skip all initially logged stuff.
-  EmbeddedVector<char, 102400> buffer;
-  int log_pos = GetLogLines(0, &buffer);
+  ScopedLoggerInitializer initialize_logger(false, false);
+  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
@@ -583,34 +601,112 @@
   inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
 
   i::Logger::LogAccessorCallbacks();
-  log_pos = GetLogLines(log_pos, &buffer);
-  CHECK_GT(log_pos, 0);
-  buffer[log_pos] = 0;
-  printf("%s", buffer.start());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  matcher.PrintBuffer();
 
   EmbeddedVector<char, 100> prop1_getter_record;
   i::OS::SNPrintF(prop1_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
                   Prop1Getter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop1_getter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop1_getter_record));
   EmbeddedVector<char, 100> prop1_setter_record;
   i::OS::SNPrintF(prop1_setter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
                   Prop1Setter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop1_setter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop1_setter_record));
   EmbeddedVector<char, 100> prop2_getter_record;
   i::OS::SNPrintF(prop2_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
                   Prop2Getter);
-  CHECK_NE(NULL, strstr(buffer.start(), prop2_getter_record.start()));
+  CHECK_NE(NULL, matcher.Find(prop2_getter_record));
 
   obj.Dispose();
+}
 
-  env->Exit();
-  Logger::TearDown();
-  i::FLAG_prof_lazy = saved_prof_lazy;
-  i::FLAG_prof = saved_prof;
-  i::FLAG_prof_auto = saved_prof_auto;
+
+TEST(LogTags) {
+  ScopedLoggerInitializer initialize_logger(true, false);
+  LogBufferMatcher matcher;
+
+  const char* open_tag = "open-tag,";
+  const char* close_tag = "close-tag,";
+
+  // Check compatibility with the old style behavior.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_EQ(NULL, matcher.Find(open_tag));
+  CHECK_EQ(NULL, matcher.Find(close_tag));
+
+  const char* open_tag1 = "open-tag,1\n";
+  const char* close_tag1 = "close-tag,1\n";
+
+  // Check non-nested tag case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  CHECK(matcher.IsInSequence(open_tag1, close_tag1));
+
+  const char* open_tag2 = "open-tag,2\n";
+  const char* close_tag2 = "close-tag,2\n";
+
+  // Check nested tags case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  // open_tag1 < open_tag2 < close_tag2 < close_tag1
+  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
+  CHECK(matcher.IsInSequence(open_tag2, close_tag2));
+  CHECK(matcher.IsInSequence(close_tag2, close_tag1));
+
+  // Check overlapped tags case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  CHECK_GT(matcher.GetNextChunk(), 0);
+  // open_tag1 < open_tag2 < close_tag1 < close_tag2
+  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
+  CHECK(matcher.IsInSequence(open_tag2, close_tag1));
+  CHECK(matcher.IsInSequence(close_tag1, close_tag2));
+
+  const char* open_tag3 = "open-tag,3\n";
+  const char* close_tag3 = "close-tag,3\n";
+
+  // Check pausing overflow case.
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+  CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
+  CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+  // Must be no tags, because logging must be disabled.
+  CHECK_EQ(NULL, matcher.Find(open_tag3));
+  CHECK_EQ(NULL, matcher.Find(close_tag3));
 }
 
 
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 18f6988..5335e9b 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -131,7 +131,7 @@
       ExternalReference::address_of_real_stack_limit();
   CHECK_EQ(make_code(UNCLASSIFIED, 5),
            encoder.Encode(real_stack_limit_address.address()));
-  CHECK_EQ(make_code(UNCLASSIFIED, 11),
+  CHECK_EQ(make_code(UNCLASSIFIED, 12),
            encoder.Encode(ExternalReference::debug_break().address()));
   CHECK_EQ(make_code(UNCLASSIFIED, 7),
            encoder.Encode(ExternalReference::new_space_start().address()));
@@ -165,7 +165,7 @@
   CHECK_EQ(ExternalReference::address_of_real_stack_limit().address(),
            decoder.Decode(make_code(UNCLASSIFIED, 5)));
   CHECK_EQ(ExternalReference::debug_break().address(),
-           decoder.Decode(make_code(UNCLASSIFIED, 11)));
+           decoder.Decode(make_code(UNCLASSIFIED, 12)));
   CHECK_EQ(ExternalReference::new_space_start().address(),
            decoder.Decode(make_code(UNCLASSIFIED, 7)));
 }
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index 1d65e68..24b3c90 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -35,111 +35,6 @@
 using namespace v8::internal;
 
 
-enum Mode {
-  forward,
-  backward_unsigned
-};
-
-
-static v8::internal::byte* Write(v8::internal::byte* p, Mode m, int x) {
-  v8::internal::byte* q = NULL;
-  switch (m) {
-    case forward:
-      q = EncodeInt(p, x);
-      CHECK(q <= p + sizeof(x) + 1);
-      break;
-    case backward_unsigned:
-      q = EncodeUnsignedIntBackward(p, x);
-      CHECK(q >= p - sizeof(x) - 1);
-      break;
-  }
-  return q;
-}
-
-
-static v8::internal::byte* Read(v8::internal::byte* p, Mode m, int x) {
-  v8::internal::byte* q = NULL;
-  int y;
-  switch (m) {
-    case forward:
-      q = DecodeInt(p, &y);
-      CHECK(q <= p + sizeof(y) + 1);
-      break;
-    case backward_unsigned: {
-      unsigned int uy;
-      q = DecodeUnsignedIntBackward(p, &uy);
-      y = uy;
-      CHECK(q >= p - sizeof(uy) - 1);
-      break;
-    }
-  }
-  CHECK(y == x);
-  return q;
-}
-
-
-static v8::internal::byte* WriteMany(v8::internal::byte* p, Mode m, int x) {
-  p = Write(p, m, x - 7);
-  p = Write(p, m, x - 1);
-  p = Write(p, m, x);
-  p = Write(p, m, x + 1);
-  p = Write(p, m, x + 2);
-  p = Write(p, m, -x - 5);
-  p = Write(p, m, -x - 1);
-  p = Write(p, m, -x);
-  p = Write(p, m, -x + 1);
-  p = Write(p, m, -x + 3);
-
-  return p;
-}
-
-
-static v8::internal::byte* ReadMany(v8::internal::byte* p, Mode m, int x) {
-  p = Read(p, m, x - 7);
-  p = Read(p, m, x - 1);
-  p = Read(p, m, x);
-  p = Read(p, m, x + 1);
-  p = Read(p, m, x + 2);
-  p = Read(p, m, -x - 5);
-  p = Read(p, m, -x - 1);
-  p = Read(p, m, -x);
-  p = Read(p, m, -x + 1);
-  p = Read(p, m, -x + 3);
-
-  return p;
-}
-
-
-void ProcessValues(int* values, int n, Mode m) {
-  v8::internal::byte buf[4 * KB];  // make this big enough
-  v8::internal::byte* p0 = (m == forward ? buf : buf + ARRAY_SIZE(buf));
-
-  v8::internal::byte* p = p0;
-  for (int i = 0; i < n; i++) {
-    p = WriteMany(p, m, values[i]);
-  }
-
-  v8::internal::byte* q = p0;
-  for (int i = 0; i < n; i++) {
-    q = ReadMany(q, m, values[i]);
-  }
-
-  CHECK(p == q);
-}
-
-
-TEST(Utils0) {
-  int values[] = {
-    0, 1, 10, 16, 32, 64, 128, 256, 512, 1024, 1234, 5731,
-    10000, 100000, 1000000, 10000000, 100000000, 1000000000
-  };
-  const int n = ARRAY_SIZE(values);
-
-  ProcessValues(values, n, forward);
-  ProcessValues(values, n, backward_unsigned);
-}
-
-
 TEST(Utils1) {
   CHECK_EQ(-1000000, FastD2I(-1000000.0));
   CHECK_EQ(-1, FastD2I(-1.0));
diff --git a/test/mjsunit/array-functions-prototype-misc.js b/test/mjsunit/array-functions-prototype-misc.js
new file mode 100644
index 0000000..0543c32
--- /dev/null
+++ b/test/mjsunit/array-functions-prototype-misc.js
@@ -0,0 +1,314 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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.
+
+/**
+ * @fileoverview Test splice, shift, unshift, slice and join on small
+ * and large arrays.  Some of these methods are specified such that they
+ * should work on other objects too, so we test that too.
+ */
+
+var LARGE = 40000000;
+var VERYLARGE = 4000000000;
+
+// Nicer for firefox 1.5.  Unless you uncomment the following two lines,
+// smjs will appear to hang on this file.
+//var LARGE = 40000;
+//var VERYLARGE = 40000;
+
+var fourhundredth = LARGE/400;
+
+function PseudoArray() {
+};
+
+for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
+  var poses = [0, 140, 20000, VERYLARGE];
+  var the_prototype;
+  var new_function;
+  var push_function;
+  var concat_function;
+  var slice_function;
+  var splice_function;
+  var splice_function_2;
+  var unshift_function;
+  var unshift_function_2;
+  var shift_function;
+  if (use_real_arrays) {
+    new_function = function(length) {
+      return new Array(length);
+    };
+    the_prototype = Array.prototype;
+    push_function = function(array, elt) {
+      return array.push(elt);
+    };
+    concat_function = function(array, other) {
+      return array.concat(other);
+    };
+    slice_function = function(array, start, len) {
+      return array.slice(start, len);
+    };
+    splice_function = function(array, start, len) {
+      return array.splice(start, len);
+    };
+    splice_function_2 = function(array, start, len, elt) {
+      return array.splice(start, len, elt);
+    };
+    unshift_function = function(array, elt) {
+      return array.unshift(elt);
+    };
+    unshift_function_2 = function(array, elt1, elt2) {
+      return array.unshift(elt1, elt2);
+    };
+    shift_function = function(array) {
+      return array.shift();
+    };
+  } else {
+    // Don't run largest size on non-arrays or we'll be here for ever.
+    poses.pop();
+    new_function = function(length) {
+      var obj = new PseudoArray();
+      obj.length = length;
+      return obj;
+    };
+    the_prototype = PseudoArray.prototype;
+    push_function = function(array, elt) {
+      array[array.length] = elt;
+      array.length++;
+    };
+    concat_function = function(array, other) {
+      return Array.prototype.concat.call(array, other);
+    };
+    slice_function = function(array, start, len) {
+      return Array.prototype.slice.call(array, start, len);
+    };
+    splice_function = function(array, start, len) {
+      return Array.prototype.splice.call(array, start, len);
+    };
+    splice_function_2 = function(array, start, len, elt) {
+      return Array.prototype.splice.call(array, start, len, elt);
+    };
+    unshift_function = function(array, elt) {
+      return Array.prototype.unshift.call(array, elt);
+    };
+    unshift_function_2 = function(array, elt1, elt2) {
+      return Array.prototype.unshift.call(array, elt1, elt2);
+    };
+    shift_function = function(array) {
+      return Array.prototype.shift.call(array);
+    };
+  }
+
+  for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
+    var pos = poses[pos_pos];
+    if (pos > 100) {
+      var a = new_function(pos);
+      assertEquals(pos, a.length);
+      push_function(a, 'foo');
+      assertEquals(pos + 1, a.length);
+      var b = ['bar'];
+      // Delete a huge number of holes.
+      var c = splice_function(a, 10, pos - 20);
+      assertEquals(pos - 20, c.length);
+      assertEquals(21, a.length);
+    }
+
+    // Add a numeric property to the prototype of the array class.  This
+    // allows us to test some borderline stuff relative to the standard.
+    the_prototype["" + (pos + 1)] = 'baz';
+
+    if (use_real_arrays) {
+      // It seems quite clear from ECMAScript spec 15.4.4.5.  Just call Get on
+      // every integer in the range.
+      // IE, Safari get this right.
+      // FF, Opera get this wrong.
+      var a = ['zero', ,'two'];
+      if (pos == 0) {
+        assertEquals("zero,baz,two", a.join(","));
+      }
+
+      // Concat only applies to real arrays, unlike most of the other methods.
+      var a = new_function(pos);
+      push_function(a, "con");
+      assertEquals("con", a[pos]);
+      assertEquals(pos + 1, a.length);
+      var b = new_function(0);
+      push_function(b, "cat");
+      assertEquals("cat", b[0]);
+      var ab = concat_function(a, b);
+      assertEquals("con", ab[pos]);
+      assertEquals(pos + 2, ab.length);
+      assertEquals("cat", ab[pos + 1]);
+      var ba = concat_function(b, a);
+      assertEquals("con", ba[pos + 1]);
+      assertEquals(pos + 2, ba.length);
+      assertEquals("cat", ba[0]);
+
+      // Join with '' as separator.
+      var join = a.join('');
+      assertEquals("con", join);
+      join = b.join('');
+      assertEquals("cat", join);
+      join = ab.join('');
+      assertEquals("concat", join);
+      join = ba.join('');
+      assertEquals("catcon", join);
+
+      var sparse = [];
+      sparse[pos + 1000] = 'is ';
+      sparse[pos + 271828] = 'time ';
+      sparse[pos + 31415] = 'the ';
+      sparse[pos + 012260199] = 'all ';
+      sparse[-1] = 'foo';
+      sparse[pos + 22591927] = 'good ';
+      sparse[pos + 1618033] = 'for ';
+      sparse[pos + 91] = ': Now ';
+      sparse[pos + 86720199] = 'men.';
+      sparse.hest = 'fisk';
+
+      assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+    }
+
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+
+    // Splice works differently from join.
+    // IE, Safari get this wrong.
+    // FF, Opera get this right.
+    // 15.4.4.12 line 24 says the object itself has to have the property...
+    var zero = splice_function(a, pos, 1);
+    assertEquals("undefined", typeof(a[pos]));
+    assertEquals("two", a[pos+1], "pos1:" + pos);
+    assertEquals(pos + 2, a.length, "a length");
+    assertEquals(1, zero.length, "zero length");
+    assertEquals("zero", zero[0]);
+
+    // 15.4.4.12 line 41 says the object itself has to have the property...
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+    var nothing = splice_function_2(a, pos, 0, 'minus1');
+    assertEquals("minus1", a[pos]);
+    assertEquals("zero", a[pos+1]);
+    assertEquals("undefined", typeof(a[pos+2]), "toot!");
+    assertEquals("two", a[pos+3], "pos3");
+    assertEquals(pos + 4, a.length);
+    assertEquals(1, zero.length);
+    assertEquals("zero", zero[0]);
+
+    // 15.4.4.12 line 10 says the object itself has to have the property...
+    a = new_function(pos);
+    push_function(a, 'zero');
+    push_function(a, void 0);
+    push_function(a, 'two');
+    var one = splice_function(a, pos + 1, 1);
+    assertEquals("", one.join(","));
+    assertEquals(pos + 2, a.length);
+    assertEquals("zero", a[pos]);
+    assertEquals("two", a[pos+1]);
+
+    // Set things back to the way they were.
+    the_prototype[pos + 1] = undefined;
+
+    // Unshift.
+    var a = new_function(pos);
+    push_function(a, "foo");
+    assertEquals("foo", a[pos]);
+    assertEquals(pos + 1, a.length);
+    unshift_function(a, "bar");
+    assertEquals("foo", a[pos+1]);
+    assertEquals(pos + 2, a.length);
+    assertEquals("bar", a[0]);
+    unshift_function_2(a, "baz", "boo");
+    assertEquals("foo", a[pos+3]);
+    assertEquals(pos + 4, a.length);
+    assertEquals("baz", a[0]);
+    assertEquals("boo", a[1]);
+    assertEquals("bar", a[2]);
+
+    // Shift.
+    var baz = shift_function(a);
+    assertEquals("baz", baz);
+    assertEquals("boo", a[0]);
+    assertEquals(pos + 3, a.length);
+    assertEquals("foo", a[pos + 2]);
+
+    // Slice.
+    var bar = slice_function(a, 1, 0);  // don't throw an exception please.
+    bar = slice_function(a, 1, 2);
+    assertEquals("bar", bar[0]);
+    assertEquals(1, bar.length);
+    assertEquals("bar", a[1]);
+
+  }
+}
+
+// Lets see if performance is reasonable.
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += 1000) {
+  a[i] = i;
+}
+
+// Take something near the end of the array.
+for (var i = 0; i < 100; i++) {
+  var top = a.splice(LARGE, 5);
+  assertEquals(5, top.length);
+  assertEquals(LARGE, top[0]);
+  assertEquals("undefined", typeof(top[1]));
+  assertEquals(LARGE + 5, a.length);
+  a.splice(LARGE, 0, LARGE);
+  a.length = LARGE + 10;
+}
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += fourhundredth) {
+  a[i] = i;
+}
+
+// Take something near the middle of the array.
+for (var i = 0; i < 10; i++) {
+  var top = a.splice(LARGE >> 1, 5);
+  assertEquals(5, top.length);
+  assertEquals(LARGE >> 1, top[0]);
+  assertEquals("undefined", typeof(top[1]));
+  assertEquals(LARGE + 5, a.length);
+  a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
+}
+
+
+// Test http://b/issue?id=1202711
+arr = [0];
+arr.length = 2;
+Array.prototype[1] = 1;
+assertEquals(1, arr.pop());
+assertEquals(0, arr.pop());
+Array.prototype[1] = undefined;
+
+// Test http://code.google.com/p/chromium/issues/detail?id=21860
+Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
diff --git a/test/mjsunit/array-shift.js b/test/mjsunit/array-shift.js
new file mode 100644
index 0000000..d985b31
--- /dev/null
+++ b/test/mjsunit/array-shift.js
@@ -0,0 +1,71 @@
+// 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.
+
+// Check that shifting array of holes keeps it as array of holes
+(function() {
+  var array = new Array(10);
+  array.shift();
+  assertFalse(0 in array);
+})();
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+  Array.prototype[3] = "@3";
+  Array.prototype[7] = "@7";
+
+  assertEquals(len, array.length);
+  for (var i = 0; i < array.length; i++) {
+    assertEquals(array[i], Array.prototype[i]);
+  }
+
+  array.shift();
+
+  assertEquals(len - 1, array.length);
+  // Note that shift copies values from prototype into the array.
+  assertEquals(array[2], Array.prototype[3]);
+  assertTrue(array.hasOwnProperty(2));
+
+  assertEquals(array[6], Array.prototype[7]);
+  assertTrue(array.hasOwnProperty(6));
+
+  // ... but keeps the rest as holes:
+  Array.prototype[5] = "@5";
+  assertEquals(array[5], Array.prototype[5]);
+  assertFalse(array.hasOwnProperty(5));
+
+  assertEquals(array[3], Array.prototype[3]);
+  assertFalse(array.hasOwnProperty(3));
+
+  assertEquals(array[7], Array.prototype[7]);
+  assertFalse(array.hasOwnProperty(7));
+
+  assertTrue(delete Array.prototype[3]);
+  assertTrue(delete Array.prototype[5]);
+  assertTrue(delete Array.prototype[7]);
+})();
diff --git a/test/mjsunit/array-slice.js b/test/mjsunit/array-slice.js
new file mode 100644
index 0000000..c993a07
--- /dev/null
+++ b/test/mjsunit/array-slice.js
@@ -0,0 +1,162 @@
+// 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.
+
+// Check that slicing array of holes keeps it as array of holes
+(function() {
+  var array = new Array(10);
+  for (var i = 0; i < 7; i++) {
+    var sliced = array.slice();
+    assertEquals(array.length, sliced.length);
+    assertFalse(0 in sliced);
+  }
+})();
+
+
+// Check various forms of arguments omission.
+(function() {
+  var array = new Array(7);
+
+  for (var i = 0; i < 7; i++) {
+    assertEquals(array, array.slice());
+    assertEquals(array, array.slice(0));
+    assertEquals(array, array.slice(undefined));
+    assertEquals(array, array.slice("foobar"));
+    assertEquals(array, array.slice(undefined, undefined));
+  }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+  var array = new Array(7);
+
+  for (var i = 0; i < 7; i++) {
+    assertEquals(7, array.slice(-100).length);
+    assertEquals(3, array.slice(-3).length);
+    assertEquals(3, array.slice(4).length);
+    assertEquals(1, array.slice(6).length);
+    assertEquals(0, array.slice(7).length);
+    assertEquals(0, array.slice(8).length);
+    assertEquals(0, array.slice(100).length);
+
+    assertEquals(0, array.slice(0, -100).length);
+    assertEquals(4, array.slice(0, -3).length);
+    assertEquals(4, array.slice(0, 4).length);
+    assertEquals(6, array.slice(0, 6).length);
+    assertEquals(7, array.slice(0, 7).length);
+    assertEquals(7, array.slice(0, 8).length);
+    assertEquals(7, array.slice(0, 100).length);
+
+    // Some exotic cases.
+
+    obj = { toString: function() { throw 'Exception'; } };
+
+    // More than 2 arguments:
+    assertEquals(7, array.slice(0, 7, obj, null, undefined).length);
+
+    // Custom conversion:
+    assertEquals(1, array.slice({valueOf: function() { return 1; }},
+                                {toString: function() { return 2; }}).length);
+
+    // Throwing an exception in conversion:
+    try {
+      assertEquals(7, array.slice(0, obj).length);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
+    }
+  }
+})();
+
+
+// Nasty: modify the array in ToInteger.
+(function() {
+  var array = [];
+  var expected = []
+  bad_guy = { valueOf: function() { array.push(array.length); return -1; } };
+
+  for (var i = 0; i < 13; i++) {
+    var sliced = array.slice(bad_guy);
+    expected.push(i);
+    assertEquals(expected, array);
+    // According to the spec (15.4.4.10), length is calculated before
+    // performing ToInteger on arguments.
+    if (i == 0) {
+      assertEquals([], sliced);  // Length was 0, nothing to get.
+    } else {
+      // Actually out of array [0..i] we get [i - 1] as length is i.
+      assertEquals([i - 1], sliced);
+    }
+  }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+
+  var at3 = "@3";
+  var at7 = "@7";
+
+  for (var i = 0; i < 7; i++) {
+    Array.prototype[3] = at3;
+    Array.prototype[7] = at7;
+
+    assertEquals(len, array.length);
+    for (var i = 0; i < array.length; i++) {
+      assertEquals(array[i], Array.prototype[i]);
+    }
+
+    var sliced = array.slice();
+
+    assertEquals(len, sliced.length);
+
+    assertTrue(delete Array.prototype[3]);
+    assertTrue(delete Array.prototype[7]);
+
+    // Note that slice copies values from prototype into the array.
+    assertEquals(array[3], undefined);
+    assertFalse(array.hasOwnProperty(3));
+    assertEquals(sliced[3], at3);
+    assertTrue(sliced.hasOwnProperty(3));
+
+    assertEquals(array[7], undefined);
+    assertFalse(array.hasOwnProperty(7));
+    assertEquals(sliced[7], at7);
+    assertTrue(sliced.hasOwnProperty(7));
+
+    // ... but keeps the rest as holes:
+    Array.prototype[5] = "@5";
+    assertEquals(array[5], Array.prototype[5]);
+    assertFalse(array.hasOwnProperty(5));
+    assertEquals(sliced[5], Array.prototype[5]);
+    assertFalse(sliced.hasOwnProperty(5));
+
+    assertTrue(delete Array.prototype[5]);
+  }
+})();
diff --git a/test/mjsunit/array-splice.js b/test/mjsunit/array-splice.js
index 0543c32..18f81fe 100644
--- a/test/mjsunit/array-splice.js
+++ b/test/mjsunit/array-splice.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -25,290 +25,265 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-/**
- * @fileoverview Test splice, shift, unshift, slice and join on small
- * and large arrays.  Some of these methods are specified such that they
- * should work on other objects too, so we test that too.
- */
+// Check that splicing array of holes keeps it as array of holes
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var array = new Array(10);
+    var spliced = array.splice(1, 1, 'one', 'two');
+    assertEquals(1, spliced.length);
+    assertFalse(0 in spliced);
 
-var LARGE = 40000000;
-var VERYLARGE = 4000000000;
-
-// Nicer for firefox 1.5.  Unless you uncomment the following two lines,
-// smjs will appear to hang on this file.
-//var LARGE = 40000;
-//var VERYLARGE = 40000;
-
-var fourhundredth = LARGE/400;
-
-function PseudoArray() {
-};
-
-for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
-  var poses = [0, 140, 20000, VERYLARGE];
-  var the_prototype;
-  var new_function;
-  var push_function;
-  var concat_function;
-  var slice_function;
-  var splice_function;
-  var splice_function_2;
-  var unshift_function;
-  var unshift_function_2;
-  var shift_function;
-  if (use_real_arrays) {
-    new_function = function(length) {
-      return new Array(length);
-    };
-    the_prototype = Array.prototype;
-    push_function = function(array, elt) {
-      return array.push(elt);
-    };
-    concat_function = function(array, other) {
-      return array.concat(other);
-    };
-    slice_function = function(array, start, len) {
-      return array.slice(start, len);
-    };
-    splice_function = function(array, start, len) {
-      return array.splice(start, len);
-    };
-    splice_function_2 = function(array, start, len, elt) {
-      return array.splice(start, len, elt);
-    };
-    unshift_function = function(array, elt) {
-      return array.unshift(elt);
-    };
-    unshift_function_2 = function(array, elt1, elt2) {
-      return array.unshift(elt1, elt2);
-    };
-    shift_function = function(array) {
-      return array.shift();
-    };
-  } else {
-    // Don't run largest size on non-arrays or we'll be here for ever.
-    poses.pop();
-    new_function = function(length) {
-      var obj = new PseudoArray();
-      obj.length = length;
-      return obj;
-    };
-    the_prototype = PseudoArray.prototype;
-    push_function = function(array, elt) {
-      array[array.length] = elt;
-      array.length++;
-    };
-    concat_function = function(array, other) {
-      return Array.prototype.concat.call(array, other);
-    };
-    slice_function = function(array, start, len) {
-      return Array.prototype.slice.call(array, start, len);
-    };
-    splice_function = function(array, start, len) {
-      return Array.prototype.splice.call(array, start, len);
-    };
-    splice_function_2 = function(array, start, len, elt) {
-      return Array.prototype.splice.call(array, start, len, elt);
-    };
-    unshift_function = function(array, elt) {
-      return Array.prototype.unshift.call(array, elt);
-    };
-    unshift_function_2 = function(array, elt1, elt2) {
-      return Array.prototype.unshift.call(array, elt1, elt2);
-    };
-    shift_function = function(array) {
-      return Array.prototype.shift.call(array);
-    };
+    assertEquals(11, array.length);
+    assertFalse(0 in array);
+    assertTrue(1 in array);
+    assertTrue(2 in array);
+    assertFalse(3 in array);
   }
+})();
 
-  for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
-    var pos = poses[pos_pos];
-    if (pos > 100) {
-      var a = new_function(pos);
-      assertEquals(pos, a.length);
-      push_function(a, 'foo');
-      assertEquals(pos + 1, a.length);
-      var b = ['bar'];
-      // Delete a huge number of holes.
-      var c = splice_function(a, 10, pos - 20);
-      assertEquals(pos - 20, c.length);
-      assertEquals(21, a.length);
+
+// Check various forms of arguments omission.
+(function() {
+  var array;
+  for (var i = 0; i < 7; i++) {
+    // SpiderMonkey and JSC return undefined in the case where no
+    // arguments are given instead of using the implicit undefined
+    // arguments.  This does not follow ECMA-262, but we do the same for
+    // compatibility.
+    // TraceMonkey follows ECMA-262 though.
+    array = [1, 2, 3]
+    assertEquals(undefined, array.splice());
+    assertEquals([1, 2, 3], array);
+
+    // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+    // given differently from when an undefined delete count is given.
+    // This does not follow ECMA-262, but we do the same for
+    // compatibility.
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice(0));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice(undefined));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([1, 2, 3], array.splice("foobar"));
+    assertEquals([], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice(undefined, undefined));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice("foobar", undefined));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice(undefined, "foobar"));
+    assertEquals([1, 2, 3], array);
+
+    array = [1, 2, 3]
+    assertEquals([], array.splice("foobar", "foobar"));
+    assertEquals([1, 2, 3], array);
+  }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+  var array, spliced;
+  for (var i = 0; i < 7; i++) {
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(-100);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(-3);
+    assertEquals([1, 2, 3, 4], array);
+    assertEquals([5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(4);
+    assertEquals([1, 2, 3, 4], array);
+    assertEquals([5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(6);
+    assertEquals([1, 2, 3, 4, 5, 6], array);
+    assertEquals([7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(7);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(8);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(100);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, -100);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, -3);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+    assertEquals([], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 4);
+    assertEquals([5, 6, 7], array);
+    assertEquals([1, 2, 3, 4], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 6);
+    assertEquals([7], array);
+    assertEquals([1, 2, 3, 4, 5, 6], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 7);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 8);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    array = [1, 2, 3, 4, 5, 6, 7];
+    spliced = array.splice(0, 100);
+    assertEquals([], array);
+    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+    // Some exotic cases.
+    obj = { toString: function() { throw 'Exception'; } };
+
+    // Throwing an exception in conversion:
+    try {
+      [1, 2, 3].splice(obj, 3);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
     }
 
-    // Add a numeric property to the prototype of the array class.  This
-    // allows us to test some borderline stuff relative to the standard.
-    the_prototype["" + (pos + 1)] = 'baz';
-
-    if (use_real_arrays) {
-      // It seems quite clear from ECMAScript spec 15.4.4.5.  Just call Get on
-      // every integer in the range.
-      // IE, Safari get this right.
-      // FF, Opera get this wrong.
-      var a = ['zero', ,'two'];
-      if (pos == 0) {
-        assertEquals("zero,baz,two", a.join(","));
-      }
-
-      // Concat only applies to real arrays, unlike most of the other methods.
-      var a = new_function(pos);
-      push_function(a, "con");
-      assertEquals("con", a[pos]);
-      assertEquals(pos + 1, a.length);
-      var b = new_function(0);
-      push_function(b, "cat");
-      assertEquals("cat", b[0]);
-      var ab = concat_function(a, b);
-      assertEquals("con", ab[pos]);
-      assertEquals(pos + 2, ab.length);
-      assertEquals("cat", ab[pos + 1]);
-      var ba = concat_function(b, a);
-      assertEquals("con", ba[pos + 1]);
-      assertEquals(pos + 2, ba.length);
-      assertEquals("cat", ba[0]);
-
-      // Join with '' as separator.
-      var join = a.join('');
-      assertEquals("con", join);
-      join = b.join('');
-      assertEquals("cat", join);
-      join = ab.join('');
-      assertEquals("concat", join);
-      join = ba.join('');
-      assertEquals("catcon", join);
-
-      var sparse = [];
-      sparse[pos + 1000] = 'is ';
-      sparse[pos + 271828] = 'time ';
-      sparse[pos + 31415] = 'the ';
-      sparse[pos + 012260199] = 'all ';
-      sparse[-1] = 'foo';
-      sparse[pos + 22591927] = 'good ';
-      sparse[pos + 1618033] = 'for ';
-      sparse[pos + 91] = ': Now ';
-      sparse[pos + 86720199] = 'men.';
-      sparse.hest = 'fisk';
-
-      assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+    try {
+      [1, 2, 3].splice(0, obj, 3);
+      throw 'Should have thrown';
+    } catch (e) {
+      assertEquals('Exception', e);
     }
 
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
+    array = [1, 2, 3];
+    array.splice(0, 3, obj);
+    assertEquals(1, array.length);
 
-    // Splice works differently from join.
-    // IE, Safari get this wrong.
-    // FF, Opera get this right.
-    // 15.4.4.12 line 24 says the object itself has to have the property...
-    var zero = splice_function(a, pos, 1);
-    assertEquals("undefined", typeof(a[pos]));
-    assertEquals("two", a[pos+1], "pos1:" + pos);
-    assertEquals(pos + 2, a.length, "a length");
-    assertEquals(1, zero.length, "zero length");
-    assertEquals("zero", zero[0]);
-
-    // 15.4.4.12 line 41 says the object itself has to have the property...
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
-    var nothing = splice_function_2(a, pos, 0, 'minus1');
-    assertEquals("minus1", a[pos]);
-    assertEquals("zero", a[pos+1]);
-    assertEquals("undefined", typeof(a[pos+2]), "toot!");
-    assertEquals("two", a[pos+3], "pos3");
-    assertEquals(pos + 4, a.length);
-    assertEquals(1, zero.length);
-    assertEquals("zero", zero[0]);
-
-    // 15.4.4.12 line 10 says the object itself has to have the property...
-    a = new_function(pos);
-    push_function(a, 'zero');
-    push_function(a, void 0);
-    push_function(a, 'two');
-    var one = splice_function(a, pos + 1, 1);
-    assertEquals("", one.join(","));
-    assertEquals(pos + 2, a.length);
-    assertEquals("zero", a[pos]);
-    assertEquals("two", a[pos+1]);
-
-    // Set things back to the way they were.
-    the_prototype[pos + 1] = undefined;
-
-    // Unshift.
-    var a = new_function(pos);
-    push_function(a, "foo");
-    assertEquals("foo", a[pos]);
-    assertEquals(pos + 1, a.length);
-    unshift_function(a, "bar");
-    assertEquals("foo", a[pos+1]);
-    assertEquals(pos + 2, a.length);
-    assertEquals("bar", a[0]);
-    unshift_function_2(a, "baz", "boo");
-    assertEquals("foo", a[pos+3]);
-    assertEquals(pos + 4, a.length);
-    assertEquals("baz", a[0]);
-    assertEquals("boo", a[1]);
-    assertEquals("bar", a[2]);
-
-    // Shift.
-    var baz = shift_function(a);
-    assertEquals("baz", baz);
-    assertEquals("boo", a[0]);
-    assertEquals(pos + 3, a.length);
-    assertEquals("foo", a[pos + 2]);
-
-    // Slice.
-    var bar = slice_function(a, 1, 0);  // don't throw an exception please.
-    bar = slice_function(a, 1, 2);
-    assertEquals("bar", bar[0]);
-    assertEquals(1, bar.length);
-    assertEquals("bar", a[1]);
-
+    // Custom conversion:
+    array = [1, 2, 3];
+    spliced = array.splice({valueOf: function() { return 1; }},
+                           {toString: function() { return 2; }},
+                           'one', 'two');
+    assertEquals([2, 3], spliced);
+    assertEquals([1, 'one', 'two'], array);
   }
-}
-
-// Lets see if performance is reasonable.
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += 1000) {
-  a[i] = i;
-}
-
-// Take something near the end of the array.
-for (var i = 0; i < 100; i++) {
-  var top = a.splice(LARGE, 5);
-  assertEquals(5, top.length);
-  assertEquals(LARGE, top[0]);
-  assertEquals("undefined", typeof(top[1]));
-  assertEquals(LARGE + 5, a.length);
-  a.splice(LARGE, 0, LARGE);
-  a.length = LARGE + 10;
-}
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += fourhundredth) {
-  a[i] = i;
-}
-
-// Take something near the middle of the array.
-for (var i = 0; i < 10; i++) {
-  var top = a.splice(LARGE >> 1, 5);
-  assertEquals(5, top.length);
-  assertEquals(LARGE >> 1, top[0]);
-  assertEquals("undefined", typeof(top[1]));
-  assertEquals(LARGE + 5, a.length);
-  a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
-}
+})();
 
 
-// Test http://b/issue?id=1202711
-arr = [0];
-arr.length = 2;
-Array.prototype[1] = 1;
-assertEquals(1, arr.pop());
-assertEquals(0, arr.pop());
-Array.prototype[1] = undefined;
+// Nasty: modify the array in ToInteger.
+(function() {
+  var array = [];
+  var spliced;
 
-// Test http://code.google.com/p/chromium/issues/detail?id=21860
-Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
+  for (var i = 0; i < 13; i++) {
+    bad_start = { valueOf: function() { array.push(2*i); return -1; } };
+    bad_count = { valueOf: function() { array.push(2*i + 1); return 1; } };
+    spliced = array.splice(bad_start, bad_count);
+    // According to the spec (15.4.4.12), length is calculated before
+    // performing ToInteger on arguments.  However, v8 ignores elements
+    // we add while converting, so we need corrective pushes.
+    array.push(2*i); array.push(2*i + 1);
+    if (i == 0) {
+      assertEquals([], spliced);  // Length was 0, nothing to get.
+      assertEquals([0, 1], array);
+    } else {
+      // When we start splice, array is [0 .. 2*i - 1], so we get
+      // as a result [2*i], this element is removed from the array,
+      // but [2 * i, 2 * i + 1] are added.
+      assertEquals([2 * i - 1], spliced);
+      assertEquals(2 * i, array[i]);
+      assertEquals(2 * i + 1, array[i + 1]);
+    }
+  }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+
+  var at3 = "@3";
+  var at7 = "@7";
+
+  for (var i = 0; i < 7; i++) {
+    var array = new Array(len);
+    Array.prototype[3] = at3;
+    Array.prototype[7] = at7;
+
+    var spliced = array.splice(2, 2, 'one', undefined, 'two');
+
+    // Second hole (at index 3) of array turns into
+    // value of Array.prototype[3] while copying.
+    assertEquals([, at3], spliced);
+    assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
+
+    // ... but array[7] is actually a hole:
+    assertTrue(delete Array.prototype[7]);
+    assertEquals(undefined, array[7]);
+
+    // and now check hasOwnProperty
+    assertFalse(array.hasOwnProperty(0));
+    assertFalse(array.hasOwnProperty(1));
+    assertTrue(array.hasOwnProperty(2));
+    assertTrue(array.hasOwnProperty(3));
+    assertTrue(array.hasOwnProperty(4));
+    assertFalse(array.hasOwnProperty(5));
+    assertFalse(array.hasOwnProperty(6));
+    assertFalse(array.hasOwnProperty(7));
+    assertTrue(array.hasOwnProperty(8));
+    assertFalse(array.hasOwnProperty(9));
+
+    // and now check couple of indices above length.
+    assertFalse(array.hasOwnProperty(10));
+    assertFalse(array.hasOwnProperty(15));
+    assertFalse(array.hasOwnProperty(31));
+    assertFalse(array.hasOwnProperty(63));
+    assertFalse(array.hasOwnProperty(2 << 32 - 1));
+  }
+})();
+
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    try {
+      new Array((1 << 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
+      throw 'Should have thrown RangeError';
+    } catch (e) {
+      assertTrue(e instanceof RangeError);
+    }
+
+    // Check smi boundary
+    var bigNum = (1 << 30) - 3;
+    var array = new Array(bigNum);
+    array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
+    assertEquals(bigNum + 7, array.length);
+  }
+})();
diff --git a/test/mjsunit/array-unshift.js b/test/mjsunit/array-unshift.js
new file mode 100644
index 0000000..06a78a7
--- /dev/null
+++ b/test/mjsunit/array-unshift.js
@@ -0,0 +1,132 @@
+// 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.
+
+// Check that unshifting array of holes keeps the original array
+// as array of holes
+(function() {
+  var array = new Array(10);
+  assertEquals(13, array.unshift('1st', '2ns', '3rd'));
+  assertTrue(0 in array);
+  assertTrue(1 in array);
+  assertTrue(2 in array);
+  assertFalse(3 in array);
+})();
+
+
+// Check that unshif with no args has a side-effect of
+// feeling the holes with elements from the prototype
+// (if present, of course)
+(function() {
+  var len = 3;
+  var array = new Array(len);
+
+  var at0 = '@0';
+  var at2 = '@2';
+
+  Array.prototype[0] = at0;
+  Array.prototype[2] = at2;
+
+  // array owns nothing...
+  assertFalse(array.hasOwnProperty(0));
+  assertFalse(array.hasOwnProperty(1));
+  assertFalse(array.hasOwnProperty(2));
+
+  // ... but sees values from Array.prototype
+  assertEquals(array[0], at0);
+  assertEquals(array[1], undefined);
+  assertEquals(array[2], at2);
+
+  assertEquals(len, array.unshift());
+
+  assertTrue(delete Array.prototype[0]);
+  assertTrue(delete Array.prototype[2]);
+
+  // unshift makes array own 0 and 2...
+  assertTrue(array.hasOwnProperty(0));
+  assertFalse(array.hasOwnProperty(1));
+  assertTrue(array.hasOwnProperty(2));
+
+  // ... so they are not affected be delete.
+  assertEquals(array[0], at0);
+  assertEquals(array[1], undefined);
+  assertEquals(array[2], at2);
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var len = 9;
+  var array = new Array(len);
+  Array.prototype[3] = "@3";
+  Array.prototype[7] = "@7";
+
+  assertEquals(len, array.length);
+  for (var i = 0; i < array.length; i++) {
+    assertEquals(array[i], Array.prototype[i]);
+  }
+
+  assertEquals(len + 1, array.unshift('head'));
+
+  assertEquals(len + 1, array.length);
+  // Note that unshift copies values from prototype into the array.
+  assertEquals(array[4], Array.prototype[3]);
+  assertTrue(array.hasOwnProperty(4));
+
+  assertEquals(array[8], Array.prototype[7]);
+  assertTrue(array.hasOwnProperty(8));
+
+  // ... but keeps the rest as holes:
+  Array.prototype[5] = "@5";
+  assertEquals(array[5], Array.prototype[5]);
+  assertFalse(array.hasOwnProperty(5));
+
+  assertEquals(array[3], Array.prototype[3]);
+  assertFalse(array.hasOwnProperty(3));
+
+  assertEquals(array[7], Array.prototype[7]);
+  assertFalse(array.hasOwnProperty(7));
+
+  assertTrue(delete Array.prototype[3]);
+  assertTrue(delete Array.prototype[5]);
+  assertTrue(delete Array.prototype[7]);
+})();
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    try {
+      new Array((1 << 32) - 3).unshift(1, 2, 3, 4, 5);
+      throw 'Should have thrown RangeError';
+    } catch (e) {
+      assertTrue(e instanceof RangeError);
+    }
+
+    // Check smi boundary
+    var bigNum = (1 << 30) - 3;
+    assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7));
+  }
+})();
diff --git a/test/mjsunit/bugs/618.js b/test/mjsunit/bugs/618.js
new file mode 100644
index 0000000..afa9929
--- /dev/null
+++ b/test/mjsunit/bugs/618.js
@@ -0,0 +1,86 @@
+// 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.
+
+// Simple class using inline constructor.
+function C1() {
+  this.x = 23;
+};
+var c1 = new C1();
+assertEquals(23, c1.x);
+assertEquals("undefined", typeof c1.y);
+  
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C1.prototype = { set x(value) { this.y = 23; } };
+var c1 = new C1();
+assertEquals("undefined", typeof c1.x);
+assertEquals(23, c1.y);
+  
+// Simple class using inline constructor.
+function C2() {
+  this.x = 23;
+};
+var c2 = new C2();
+assertEquals(23, c2.x);
+assertEquals("undefined", typeof c2.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+var c2 = new C2();
+assertEquals("undefined", typeof c2.x);
+assertEquals(23, c2.y);
+
+// Simple class using inline constructor.
+function C3() {
+  this.x = 23;
+};
+var c3 = new C3();
+assertEquals(23, c3.x);
+assertEquals("undefined", typeof c3.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+var c3 = new C3();
+assertEquals("undefined", typeof c3.x);
+assertEquals(23, c3.y);
+
+// Simple class using inline constructor.
+function C4() {
+  this.x = 23;
+};
+var c4 = new C4();
+assertEquals(23, c4.x);
+assertEquals("undefined", typeof c4.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+var c4 = new C4();
+assertEquals("undefined", typeof c4.x);
+assertEquals(23, c4.y);
diff --git a/test/mjsunit/bugs/bug-619.js b/test/mjsunit/bugs/bug-619.js
new file mode 100644
index 0000000..ef8ba80
--- /dev/null
+++ b/test/mjsunit/bugs/bug-619.js
@@ -0,0 +1,62 @@
+// 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.
+
+// When this bug is corrected move to object-define-property and add
+// additional tests for configurable in the same manner as existing tests
+// there.
+
+var obj = {};
+obj[1] = 42;
+assertEquals(42, obj[1]);
+Object.defineProperty(obj, '1', {value:10, writable:false});
+assertEquals(10, obj[1]);
+
+// We should not be able to override obj[1].
+obj[1] = 5;
+assertEquals(10, obj[1]);
+
+// Try on a range of numbers.
+for(var i = 0; i < 1024; i++) {
+  obj[i] = 42;
+}
+
+for(var i = 0; i < 1024; i++) {
+  Object.defineProperty(obj, i, {value: i, writable:false});
+}
+
+for(var i = 0; i < 1024; i++) {
+  assertEquals(i, obj[i]);
+}
+
+for(var i = 0; i < 1024; i++) {
+  obj[1] = 5;
+}
+
+for(var i = 0; i < 1024; i++) {
+  assertEquals(i, obj[i]);
+}
+
diff --git a/test/mjsunit/codegen-coverage.js b/test/mjsunit/codegen-coverage.js
index d5e7769..42c371b 100644
--- a/test/mjsunit/codegen-coverage.js
+++ b/test/mjsunit/codegen-coverage.js
@@ -25,64 +25,110 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test the paths in the code generator where values in specific
-// registers get moved around so that the shift operation can use
-// register ECX on ia32 for the shift amount.  Other codegen coverage
-// tests should go here too.
+// Flags: --nofull-compiler --nofast-compiler
 
-
-
+// Test paths in the code generator where values in specific registers
+// get moved around.
 function identity(x) {
   return x;
 }
 
 function cover_codegen_paths() {
   var x = 1;
-  var a;  // Register EAX
-  var b;  // Register EBX
-  var c;  // Register ECX
-  var d;  // Register EDX
-  // Register ESI is already used.
-  var di;  // Register EDI
+
+  // This test depends on the fixed order of register allocation.  We try to
+  // get values in specific registers (ia32, x64):
+  var a;   // Register eax, rax.
+  var b;   // Register ebx, rbx.
+  var c;   // Register ecx, rcx.
+  var d;   // Register edx, rdx.
+  var di;  // Register edi, rdi.
 
   while (x == 1) {
+    // The call will spill registers and leave x in {eax,rax}.
     x = identity(1);
+    // The add will spill x and reuse {eax,rax} for the result.
     a = x + 1;
+    // A fresh register {ebx,rbx} will be allocated for x, then reused for
+    // the result.
+    b = x + 1;
+    // Et cetera.
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
     // Locals are in the corresponding registers here.
-    assertEquals(c << a, 8);
+    assertEquals(8, c << a);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
-    assertEquals(a << c, 8);
+    assertEquals(8, a << c);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
     c = 0; // Free register ecx.
-    assertEquals(a << d, 8);
+    assertEquals(8, a << d);
 
     x = identity(1);
     a = x + 1;
+    b = x + 1;
     c = x + 1;
     d = x + 1;
-    b = x + 1;
     di = x + 1;
-    // Locals are in the corresponding registers here.
     b = 0; // Free register ebx.
-    assertEquals(a << d, 8);
+    assertEquals(8, a << d);
+
+    // Test the non-commutative subtraction operation with a smi on the
+    // left, all available registers on the right, and a non-smi result.
+    x = identity(-1073741824);  // Least (31-bit) smi.
+    a = x + 1;  // Still a smi, the greatest smi negated.
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    // Subtraction should overflow the 31-bit smi range.  The result
+    // (1073741824) is outside the 31-bit smi range so it doesn't hit the
+    // "unsafe smi" code that spills a register.
+    assertEquals(1073741824, 1 - a);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - b);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - c);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - d);
+
+    x = identity(-1073741824);
+    a = x + 1;
+    b = x + 1;
+    c = x + 1;
+    d = x + 1;
+    di = x + 1;
+    assertEquals(1073741824, 1 - di);
 
     x = 3;
   }
diff --git a/test/mjsunit/compiler/assignment.js b/test/mjsunit/compiler/assignment.js
new file mode 100644
index 0000000..ee2d323
--- /dev/null
+++ b/test/mjsunit/compiler/assignment.js
@@ -0,0 +1,264 @@
+// 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.
+
+// Tests for compound assignments at the top level
+
+z = 2;
+z += 4;
+
+assertEquals(z, 6);
+
+a = new Array(10);
+
+a[2] += 7;
+a[2] = 15;
+a[2] += 2;
+
+assertEquals(17, a[2]);
+
+b = new Object();
+b.foo = 5;
+b.foo += 12;
+
+assertEquals(17, b.foo);
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+  var z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  var a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  var b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+  z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo() {
+  var z = 3;
+  z += 4;
+
+  assertEquals(z, 7);
+
+  var a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  var b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+foo();
+
+// Test compound assignments in a named function with global variables.
+function bar() {
+  z = 2;
+  z += 5;
+
+  assertEquals(z, 7);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+bar();
+
+// Entire series of tests repeated, in loops.
+// -------------------------------------------
+// Tests for compound assignments in a loop at the top level
+
+for (i = 0; i < 5; ++i) {
+  z = 2;
+  z += 4;
+
+  assertEquals(z, 6);
+
+  a = new Array(10);
+
+  a[2] += 7;
+  a[2] = 15;
+  a[2] += 2;
+
+  assertEquals(17, a[2]);
+
+  b = new Object();
+  b.foo = 5;
+  b.foo += 12;
+
+  assertEquals(17, b.foo);
+}
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+  for (var i = 0; i < 5; ++i) {
+    var z = 2;
+    z += 4;
+
+    assertEquals(z, 6);
+
+    var a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    var b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+  for (i = 0; i < 5; ++i) {
+    z = 2;
+    z += 4;
+
+    assertEquals(z, 6);
+
+    a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo_loop() {
+  for (i = 0; i < 5; ++i) {
+    var z = 3;
+    z += 4;
+
+    assertEquals(z, 7);
+
+    var a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    var b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+}
+
+foo_loop();
+
+// Test compound assignments in a named function with global variables.
+function bar_loop() {
+  for (i = 0; i < 5; ++i) {
+    z = 2;
+    z += 5;
+
+    assertEquals(z, 7);
+
+    a = new Array(10);
+
+    a[2] += 7;
+    a[2] = 15;
+    a[2] += 2;
+
+    assertEquals(17, a[2]);
+
+    b = new Object();
+    b.foo = 5;
+    b.foo += 12;
+
+    assertEquals(17, b.foo);
+  }
+}
+
+bar_loop();
diff --git a/test/mjsunit/compiler/simple-bailouts.js b/test/mjsunit/compiler/simple-bailouts.js
new file mode 100644
index 0000000..af80b7f
--- /dev/null
+++ b/test/mjsunit/compiler/simple-bailouts.js
@@ -0,0 +1,127 @@
+// 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: --fast-compiler
+
+function Test() {
+  this.result = 0;
+  this.x = 0;
+  this.y = 0;
+  this.z = 0;
+}
+var a = 1;
+var b = 2;
+var c = 4;
+var d = 8;
+
+// Test operations expected to stay on the fast path.  Enumerate all binary
+// trees with <= 4 leaves.
+Test.prototype.test0 = function () {
+  this.result = a | b;
+};
+
+Test.prototype.test1 = function() {
+  this.result = (a | b) | c;
+};
+
+Test.prototype.test2 = function() {
+  this.result = a | (b | c);
+};
+
+Test.prototype.test3 = function() {
+  this.result = ((a | b) | c) | d;
+};
+
+Test.prototype.test4 = function() {
+  this.result = (a | (b | c)) | d;
+};
+
+Test.prototype.test5 = function() {
+  this.result = (a | b) | (c | d);
+};
+
+Test.prototype.test6 = function() {
+  this.result = a | ((b | c) | d);
+};
+
+Test.prototype.test7 = function() {
+  this.result = a | (b | (c | d));
+};
+
+// These tests should fail if we bailed out to the beginning of the full
+// code.
+Test.prototype.test8 = function () {
+  // If this.x = 1 and a = 1.1:
+  this.y = this.x | b;  // Should be (1 | 2) == 3.
+  this.x = c;           // Should be 4.
+  this.z = this.x | a;  // Should be (4 | 1.1) == 5.
+};
+
+Test.prototype.test9 = function() {
+  // If this.x = 2 and a = 1.1:
+  this.z =              // (14 | 1.1) == 15
+      (this.x =         // (6 | 8) == 14
+           (this.y =    // (2 | 4) == 6
+                this.x  // 2
+                | c)    // 4
+            | d)        // 8
+       | a;             // 1.1
+}
+
+var t = new Test();
+
+t.test0();
+assertEquals(3, t.result);
+
+t.test1();
+assertEquals(7, t.result);
+t.test2();
+assertEquals(7, t.result);
+
+t.test3();
+assertEquals(15, t.result);
+t.test4();
+assertEquals(15, t.result);
+t.test5();
+assertEquals(15, t.result);
+t.test6();
+assertEquals(15, t.result);
+t.test7();
+assertEquals(15, t.result);
+
+a = 1.1;
+t.x = 1;
+t.test8();
+assertEquals(4, t.x);
+assertEquals(3, t.y);
+assertEquals(5, t.z);
+
+t.x = 2;
+t.test9();
+assertEquals(14, t.x);
+assertEquals(6, t.y);
+assertEquals(15, t.z);
diff --git a/test/mjsunit/compiler/simple-binary-op.js b/test/mjsunit/compiler/simple-binary-op.js
new file mode 100644
index 0000000..15e1a55
--- /dev/null
+++ b/test/mjsunit/compiler/simple-binary-op.js
@@ -0,0 +1,40 @@
+// 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: --fast-compiler
+
+var a = 1;
+var b = 2;
+var c = 4;
+
+function f() { this.x = this.x | a | b | c | a | c; }
+
+var o = {x:0, g:f}
+
+o.g();
+
+assertEquals(7, o.x);
diff --git a/test/mjsunit/compiler/simple-global-access.js b/test/mjsunit/compiler/simple-global-access.js
new file mode 100644
index 0000000..35746ba
--- /dev/null
+++ b/test/mjsunit/compiler/simple-global-access.js
@@ -0,0 +1,53 @@
+// 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: --fast-compiler
+
+// Test global variable loads with the fast compiler.
+var g1 = 42;
+var g2 = 43;
+var g3 = 44;
+this.__defineGetter__("g4", function () { return 45; });
+
+function f1() { this.x = this.y = this.z = g1; }
+function f2() { this.x = g1; this.y = g2; this.z = g3; }
+function f3() { this.x = g4; }
+
+var o = { x:0, y:0, z:0, test1:f1, test2:f2, test3:f3 }
+
+o.test1();
+assertEquals(42, o.x);
+assertEquals(42, o.y);
+assertEquals(42, o.z);
+
+o.test2();
+assertEquals(42, o.x);
+assertEquals(43, o.y);
+assertEquals(44, o.z);
+
+o.test3();
+assertEquals(45, o.x);
diff --git a/test/mjsunit/compiler/this-property-refs.js b/test/mjsunit/compiler/this-property-refs.js
new file mode 100644
index 0000000..5e8ea59
--- /dev/null
+++ b/test/mjsunit/compiler/this-property-refs.js
@@ -0,0 +1,64 @@
+// 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: --fast-compiler
+
+// Test references to properties of this.
+function Test() {
+  this.a = 0;
+  this.b = 1;
+  this.c = 2;
+  this.d = 3;
+}
+
+Test.prototype.test0 = function () {
+  this.a = this.b;
+};
+
+Test.prototype.test1 = function() {
+  this.a = this.b = this.c;
+};
+
+Test.prototype.test2 = function() {
+  this.c = this.d;
+  this.b = this.c;
+  this.a = this.b;
+};
+
+var t = new Test();
+
+t.test0();
+assertEquals(1, t.a);
+
+t.test1();
+assertEquals(2, t.a);
+assertEquals(2, t.b);
+
+t.test2();
+assertEquals(3, t.a);
+assertEquals(3, t.b);
+assertEquals(3, t.c);
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index 071183b..e7ecf47 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -90,6 +90,11 @@
       var json = event_data.toJSONProtocol();
       var msg = eval('(' + json + ')');
       assertTrue('context' in msg.body.script);
+
+      // Check that we pick script name from //@ sourceURL, iff present
+      assertEquals(current_source.indexOf('sourceURL') >= 0 ? 
+                     'myscript.js' : undefined,
+                   event_data.script().name());
     }
   } catch (e) {
     exception = e
@@ -109,6 +114,7 @@
 source_count += 2;  // Using eval causes additional compilation event.
 compileSource('JSON.parse(\'{"a":1,"b":2}\')');
 source_count++;  // Using JSON.parse causes additional compilation event.
+compileSource('x=1; //@ sourceURL=myscript.js');
 
 // Make sure that the debug event listener was invoked.
 assertFalse(exception, "exception in listener")
diff --git a/test/mjsunit/debug-evaluate.js b/test/mjsunit/debug-evaluate.js
index c477907..182e2ac 100644
--- a/test/mjsunit/debug-evaluate.js
+++ b/test/mjsunit/debug-evaluate.js
@@ -87,6 +87,37 @@
       testRequest(dcp, '{"expression":"a","global":true}', true, 1);
       testRequest(dcp, '{"expression":"this.a","global":true}', true, 1);
 
+      // Test that the whole string text is returned if maxStringLength
+      // parameter is passed.
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:-1}',
+          true,
+          longString);
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:' +
+              longString.length + '}',
+          true,
+          longString);
+      var truncatedStringSuffix = '... (length: ' + longString.length + ')';
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:0}',
+          true,
+          truncatedStringSuffix);
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true,maxStringLength:1}',
+          true,
+          longString.charAt(0) + truncatedStringSuffix);
+      // Test that by default string is truncated to first 80 chars.
+      testRequest(
+          dcp,
+          '{"expression":"this.longString","global":true}',
+          true,
+          longString.substring(0, 80) + truncatedStringSuffix);
+
       // Indicate that all was processed.
       listenerComplete = true;
     }
@@ -109,6 +140,12 @@
 
 a = 1;
 
+// String which is longer than 80 chars.
+var longString = "1234567890_";
+for (var i = 0; i < 4; i++) {
+  longString += longString;
+}
+
 // Set a break point at return in f and invoke g to hit the breakpoint.
 Debug.setBreakPoint(f, 2, 0);
 g();
diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js
index b3c77e1..1d352b5 100644
--- a/test/mjsunit/div-mod.js
+++ b/test/mjsunit/div-mod.js
@@ -154,4 +154,18 @@
       doTest(-a,-b);
     }
   }
-})()
+})();
+
+
+(function () {
+  // Edge cases
+  var zero = 0;
+  var minsmi32 = -0x40000000;
+  var minsmi64 = -0x80000000;
+  var somenum = 3532;
+  assertEquals(-0, zero / -1, "0 / -1");
+  assertEquals(1, minsmi32 / -0x40000000, "minsmi/minsmi-32");
+  assertEquals(1, minsmi64 / -0x80000000, "minsmi/minsmi-64");
+  assertEquals(somenum, somenum % -0x40000000, "%minsmi-32");
+  assertEquals(somenum, somenum % -0x80000000, "%minsmi-64");
+})();
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index d906eb8..e2f601e 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -27,6 +27,9 @@
 
 // Flags: --allow-natives-syntax
 
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
 function makeArguments() {
   var result = [ ];
   result.push(17);
@@ -74,13 +77,23 @@
   var func = makeFunction(name, argc);
   while (hasMore) {
     var argPool = makeArguments();
+    // When we have 5 or more arguments we lower the amount of tests cases
+    // by randomly removing kOnManyArgumentsRemove entries
+    var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+      kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+    if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+      for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+        var rand = Math.floor(Math.random() * (kArgObjects - i));
+        argPool.splice(rand,1);
+      }
+    }
     var current = type;
     var hasMore = false;
     var argList = [ ];
     for (var i = 0; i < argc; i++) {
-      var index = current % kArgObjects;
-      current = (current / kArgObjects) << 0;
-      if (index != (kArgObjects - 1))
+      var index = current % numArguments;
+      current = (current / numArguments) << 0;
+      if (index != (numArguments - 1))
         hasMore = true;
       argList.push(argPool[index]);
     }
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
new file mode 100644
index 0000000..6b3725b
--- /dev/null
+++ b/test/mjsunit/object-define-properties.js
@@ -0,0 +1,56 @@
+// 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.
+
+// Tests the Object.defineProperties method - ES 15.2.3.7
+// Note that the internal DefineOwnProperty method is tested through 
+// object-define-property.js, this file only contains tests specific for
+// Object.defineProperties. Also note that object-create.js contains
+// a range of indirect tests on this method since Object.create uses
+// Object.defineProperties as a step in setting up the object.
+
+// Try defining with null as descriptor:
+try {
+  Object.defineProperties({}, null);
+} catch(e) {
+  assertTrue(/null to object/.test(e));
+}
+
+// Try defining with null as object
+try {
+  Object.defineProperties(null, {});
+} catch(e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+
+var desc = {foo: {value: 10}, bar: {get: function() {return 42; }}};
+var obj = {};
+// Check that we actually get the object back as returnvalue
+var x = Object.defineProperties(obj, desc);
+
+assertEquals(x.foo, 10);
+assertEquals(x.bar, 42);
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
new file mode 100644
index 0000000..43b1c7f
--- /dev/null
+++ b/test/mjsunit/object-define-property.js
@@ -0,0 +1,499 @@
+// 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.
+
+// Tests the object.defineProperty method - ES 15.2.3.6
+
+// Flags: --allow-natives-syntax
+
+// Check that an exception is thrown when null is passed as object.
+try {
+  Object.defineProperty(null, null, null);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when undefined is passed as object.
+try {
+  Object.defineProperty(undefined, undefined, undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when non-object is passed as object.
+try {
+  Object.defineProperty(0, "foo", undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/called on non-object/.test(e));
+}
+
+// Object
+var obj1 = {};
+
+// Values
+var val1 = 0;
+var val2 = 0;
+var val3 = 0;
+
+// Descriptors
+var emptyDesc = {};
+
+var accessorConfigurable = { 
+    set: function() { val1++; },
+    get: function() { return val1; },
+    configurable: true
+};
+
+var accessorNoConfigurable = {
+    set: function() { val2++; },
+    get: function() { return val2; },
+    configurable: false 
+};
+
+var accessorOnlySet = {
+  set: function() { val3++; },
+  configurable: true
+};
+
+var accessorOnlyGet = {
+  get: function() { return val3; },
+  configurable: true
+};
+
+var accessorDefault = {set: function(){} };
+
+var dataConfigurable = { value: 1000, configurable: true };
+
+var dataNoConfigurable = { value: 2000, configurable: false };
+
+var dataWritable = { value: 3000, writable: true};
+
+
+// Check that we can't add property with undefined attributes.
+try {
+  Object.defineProperty(obj1, "foo", undefined);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/must be an object/.test(e));
+}
+
+// Make sure that we can add a property with an empty descriptor and
+// that it has the default descriptor values.
+Object.defineProperty(obj1, "foo", emptyDesc);
+
+// foo should be undefined as it has no get, set or value
+assertEquals(undefined, obj1.foo);
+
+// We should, however, be able to retrieve the propertydescriptor which should
+// have all default values (according to 8.6.1).
+var desc = Object.getOwnPropertyDescriptor(obj1, "foo");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertFalse(desc.writable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+assertEquals(desc.value, undefined);
+
+// Make sure that getOwnPropertyDescriptor does not return a descriptor
+// with default values if called with non existing property (otherwise
+// the test above is invalid).
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertEquals(desc, undefined);
+
+// Make sure that foo can't be reset (as configurable is false).
+try {
+  Object.defineProperty(obj1, "foo", accessorConfigurable);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Accessor properties
+
+Object.defineProperty(obj1, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(1, val1);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(2, obj1.bar);
+
+// Redefine bar with non configurable test
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(1, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(2, val2);
+assertEquals(2, obj1.bar);
+
+// Try to redefine bar again - should fail as configurable is false.
+try {
+  Object.defineProperty(obj1, "bar", accessorConfigurable);
+  assertTrue(false);
+} catch(e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try to redefine bar again using the data descriptor - should fail.
+try {
+  Object.defineProperty(obj1, "bar", dataConfigurable);
+  assertTrue(false);
+} catch(e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Redefine using same descriptor - should succeed.
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(3, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(4, val2);
+assertEquals(4, obj1.bar);
+
+// Define an accessor that has only a setter
+Object.defineProperty(obj1, "setOnly", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(desc.get, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(1, val3);
+
+// Add a getter - should not touch the setter
+Object.defineProperty(obj1, "setOnly", accessorOnlyGet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, accessorOnlyGet.get);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(2, val3);
+
+// The above should also work if redefining just a getter or setter on 
+// an existing property with both a getter and a setter.
+Object.defineProperty(obj1, "both", accessorConfigurable);
+
+Object.defineProperty(obj1, "both", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "both");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.both = 1);
+assertEquals(3, val3);
+
+
+// Data properties
+
+Object.defineProperty(obj1, "foobar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+//Try writing to non writable attribute - should remain 1000
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1000);
+
+
+// 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);
+assertEquals(desc.value, 3000);
+// Note that since dataWritable does not define configurable the configurable
+// setting from the redefined property (in this case true) is used.
+assertTrue(desc.configurable);
+assertTrue(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+// Writing to the property should now be allowed
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1001);
+
+
+// Redefine with non configurable data property.
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+// Try redefine again - shold fail because configurable is now false.
+try {
+  Object.defineProperty(obj1, "foobar", dataConfigurable);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try redefine again with accessor property - shold also fail.
+try {
+  Object.defineProperty(obj1, "foobar", dataConfigurable);
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Redifine with the same descriptor - should succeed (step 6).
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// New object
+var obj2 = {};
+
+// Make accessor - redefine to data
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+
+// Redefine to data property
+Object.defineProperty(obj2, "foo", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertEquals(obj2.foo, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefine back to accessor
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.foo = 1);
+assertEquals(3, val1);
+assertEquals(4, val2);
+assertEquals(3, obj2.foo);
+
+// Make data - redefine to accessor
+Object.defineProperty(obj2, "bar", dataConfigurable)
+
+// Redefine to accessor property
+Object.defineProperty(obj2, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.bar = 1);
+assertEquals(4, val1);
+assertEquals(4, val2);
+assertEquals(4, obj2.foo);
+
+// Redefine back to data property
+Object.defineProperty(obj2, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertEquals(obj2.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefinition of an accessor defined using __defineGetter__ and 
+// __defineSetter__
+function get(){return this.x}
+function set(x){this.x=x};
+
+var obj3 = {x:1000};
+obj3.__defineGetter__("foo", get);
+obj3.__defineSetter__("foo", set);
+
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, get);
+assertEquals(desc.set, set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(1, obj3.x);
+assertEquals(1, obj3.foo);
+
+// Redefine to accessor property (non configurable) - note that enumerable
+// which we do not redefine should remain the same (true).
+Object.defineProperty(obj3, "foo", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertFalse(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(5, val2);
+assertEquals(5, obj3.foo);
+
+
+obj3.__defineGetter__("bar", get);
+obj3.__defineSetter__("bar", set);
+
+
+// Redefine back to data property
+Object.defineProperty(obj3, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "bar");
+assertEquals(obj3.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertTrue(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+var obj4 = {};
+var func = function (){return 42;};
+obj4.bar = func;
+assertEquals(42, obj4.bar());
+
+Object.defineProperty(obj4, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj4, "bar");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj4.bar = 1);
+assertEquals(5, val1);
+assertEquals(5, obj4.bar);
+
+// Make sure an error is thrown when trying to access to redefined function
+try {
+  obj4.bar();
+  assertTrue(false);
+} catch (e) {
+  assertTrue(/is not a function/.test(e));
+}
+
+
+// Test runtime calls to DefineOrRedefineDataProperty and
+// DefineOrRedefineAccessorProperty - make sure we don't 
+// crash
+try {
+  %DefineOrRedefineAccessorProperty(0, 0, 0, 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(0, 0, 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(null, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineAccessorProperty(null, null, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty({}, null, null, null);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+// Defining properties null should fail even when we have
+// other allowed values
+try {
+  %DefineOrRedefineAccessorProperty(null, 'foo', 0, func, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
+
+try {
+  %DefineOrRedefineDataProperty(null, 'foo', 0, 0);
+} catch (e) {
+  assertTrue(/illegal access/.test(e));
+}
diff --git a/test/mjsunit/object-get-own-property-names.js b/test/mjsunit/object-get-own-property-names.js
index f52cee2..33aa85e 100644
--- a/test/mjsunit/object-get-own-property-names.js
+++ b/test/mjsunit/object-get-own-property-names.js
@@ -57,6 +57,8 @@
 assertEquals(3, propertyNames.length);
 assertEquals("0", propertyNames[0]);
 assertEquals("1", propertyNames[1]);
+assertEquals("string", typeof propertyNames[0]);
+assertEquals("string", typeof propertyNames[1]);
 assertEquals("length", propertyNames[2]);
 
 // Check that no proto properties are returned.
diff --git a/test/mjsunit/regress/regress-603.js b/test/mjsunit/regress/regress-603.js
new file mode 100644
index 0000000..7d4c322
--- /dev/null
+++ b/test/mjsunit/regress/regress-603.js
@@ -0,0 +1,49 @@
+// 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.
+
+// Calling non-objects directly or via Function.prototype.call should
+// not mess up the stack.
+// http://code.google.com/p/v8/issues/detail?id=603
+
+function test0() {
+  var re = /b../;
+  return re('abcdefghijklm') + 'z';
+}
+assertEquals('bcdz', test0());
+
+var re1 = /c../;
+re1.call = Function.prototype.call;
+var test1 = re1.call(null, 'abcdefghijklm') + 'z';
+assertEquals('cdez', test1);
+
+var re2 = /d../;
+var test2 = Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
+assertEquals('defz', test2);
+
+var re3 = /e../;
+var test3 = Function.prototype.call.apply(re3, [null, 'abcdefghijklm']) + 'z';
+assertEquals('efgz', test3);
diff --git a/test/mjsunit/regress/regress-612.js b/test/mjsunit/regress/regress-612.js
new file mode 100644
index 0000000..aee6d53
--- /dev/null
+++ b/test/mjsunit/regress/regress-612.js
@@ -0,0 +1,44 @@
+// 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.
+
+// Tests intercation between __defineGetter__/__defineSetter and fast and slow
+// mode of the objects due to series of assignments optimization.
+// (See http://code.google.com/p/v8/issues/detail?id=612)
+
+obj = {}
+
+// Define getter which currently moves object into slow mode.
+obj.__defineGetter__('foobar', function() { return 42; })
+
+// Starts initialization block mode.  And turns object into slow mode.
+obj.a = 1
+obj.b = 2;
+obj.c = 3;
+// Now object is turned into fast mode, but it has getter defined above...
+
+// Now assert is triggered.
+obj.__defineGetter__('foobar', function() { return 42; })
diff --git a/test/mjsunit/setter-on-constructor-prototype.js b/test/mjsunit/setter-on-constructor-prototype.js
new file mode 100644
index 0000000..d5718f9
--- /dev/null
+++ b/test/mjsunit/setter-on-constructor-prototype.js
@@ -0,0 +1,111 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 RunTest(ensure_fast_case) {
+  function C1() {
+    this.x = 23;
+  };
+  C1.prototype = { set x(value) { this.y = 23; } };
+  if (ensure_fast_case) {
+    %ToFastProperties(C1.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c1 = new C1();
+    assertEquals("undefined", typeof c1.x);
+    assertEquals(23, c1.y);
+  }
+  
+  
+  function C2() {
+    this.x = 23;
+  };
+  C2.prototype = { };
+  C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+  if (ensure_fast_case) {
+    %ToFastProperties(C2.prototype.__proto__)
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c2 = new C2();
+    assertEquals("undefined", typeof c2.x);
+    assertEquals(23, c2.y);
+  }
+  
+  
+  function C3() {
+    this.x = 23;
+  };
+  C3.prototype = { };
+  C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+  if (ensure_fast_case) {
+    %ToFastProperties(C3.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c3 = new C3();
+    assertEquals("undefined", typeof c3.x);
+    assertEquals(23, c3.y);
+  }
+  
+  
+  function C4() {
+    this.x = 23;
+  };
+  C4.prototype = { };
+  C4.prototype.__proto__ = {  };
+  C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+  if (ensure_fast_case) {
+    %ToFastProperties(C4.prototype.__proto__);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var c4 = new C4();
+    assertEquals("undefined", typeof c4.x);
+    assertEquals(23, c4.y);
+  }
+  
+  
+  function D() {
+    this.x = 23;
+  };
+  D.prototype = 1;
+  if (ensure_fast_case) {
+    %ToFastProperties(D.prototype);
+  }
+  
+  for (var i = 0; i < 10; i++) {
+    var d = new D();
+    assertEquals(23, d.x);
+    assertEquals("undefined", typeof d.y);
+  }
+}
+
+RunTest(false);
+RunTest(true);
diff --git a/test/mjsunit/substr.js b/test/mjsunit/substr.js
old mode 100644
new mode 100755
diff --git a/test/mjsunit/tools/tickprocessor-test-func-info.log b/test/mjsunit/tools/tickprocessor-test-func-info.log
new file mode 100644
index 0000000..29a12f6
--- /dev/null
+++ b/test/mjsunit/tools/tickprocessor-test-func-info.log
@@ -0,0 +1,13 @@
+shared-library,"shell",0x08048000,0x081ee000
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+profiler,"begin",1
+code-creation,Stub,0x424260,348,"CompareStub_GE"
+code-creation,LazyCompile,0x2a8100,18535,"DrawQube 3d-cube.js:188"
+function-creation,0x2d11b8,0x2a8100
+code-creation,LazyCompile,0x480100,3908,"DrawLine 3d-cube.js:17"
+function-creation,0x2d0f7c,0x480100
+tick,0x424284,0xbfffeea0,0x2d0f7c,0,0x2aaaa5
+tick,0x42429f,0xbfffed88,0x2d0f7c,0,0x2aacb4
+tick,0x48063d,0xbfffec7c,0x2d0f7c,0,0x2aaec6
+profiler,"end"