Merged r18754 into 3.22 branch.

Ensure we don't overwrite transitions in SetPropertyIgnoreAttributes.

BUG=326155
LOG=N
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/140673004

git-svn-id: http://v8.googlecode.com/svn/branches/3.22@18914 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/objects-inl.h b/src/objects-inl.h
index deb3365..929ad11 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4422,6 +4422,17 @@
   // When there is another reference to the array somewhere (e.g. a handle),
   // not zapping turns from a waste of memory into a source of crashes.
   if (HasTransitionArray()) {
+#ifdef DEBUG
+    for (int i = 0; i < transitions()->number_of_transitions(); i++) {
+      Map* target = transitions()->GetTarget(i);
+      if (target->instance_descriptors() == instance_descriptors()) {
+        Name* key = transitions()->GetKey(i);
+        int new_target_index = transition_array->Search(key);
+        ASSERT(new_target_index != TransitionArray::kNotFound);
+        ASSERT(transition_array->GetTarget(new_target_index) == target);
+      }
+    }
+#endif
     ASSERT(transitions() != transition_array);
     ZapTransitions();
   }
diff --git a/src/objects.cc b/src/objects.cc
index cf51024..9fddb83 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4186,9 +4186,12 @@
 
   // Check for accessor in prototype chain removed here in clone.
   if (!lookup.IsFound()) {
+    object->map()->LookupTransition(*object, *name, &lookup);
+    TransitionFlag flag = lookup.IsFound()
+        ? OMIT_TRANSITION : INSERT_TRANSITION;
     // Neither properties nor transitions found.
     return AddProperty(object, name, value, attributes, kNonStrictMode,
-        MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
+        MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
   }
 
   Handle<Object> old_value = isolate->factory()->the_hole_value();
diff --git a/src/version.cc b/src/version.cc
index fa89770..cecdee4 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     22
 #define BUILD_NUMBER      24
-#define PATCH_LEVEL       19
+#define PATCH_LEVEL       20
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index d5e838e..d6fce3e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1938,6 +1938,21 @@
 }
 
 
+THREADED_TEST(EmptyInterceptorBreakTransitions) {
+  v8::HandleScope scope(CcTest::isolate());
+  Handle<FunctionTemplate> templ = FunctionTemplate::New();
+  AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+  LocalContext env;
+  env->Global()->Set(v8_str("Constructor"), templ->GetFunction());
+  CompileRun("var o1 = new Constructor;"
+             "o1.a = 1;"  // Ensure a and x share the descriptor array.
+             "Object.defineProperty(o1, 'x', {value: 10});");
+  CompileRun("var o2 = new Constructor;"
+             "o2.a = 1;"
+             "Object.defineProperty(o2, 'x', {value: 10});");
+}
+
+
 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
   v8::HandleScope scope(CcTest::isolate());
   Handle<FunctionTemplate> parent = FunctionTemplate::New();