| Index: test/cctest/test-heap.cc | 
| diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc | 
| index 9229a97125e681b69a502a967a5e52c5f9d429af..31dfc1fed51a4ee5f7fc523d6d29e24e41e61d0f 100644 | 
| --- a/test/cctest/test-heap.cc | 
| +++ b/test/cctest/test-heap.cc | 
| @@ -1966,3 +1966,60 @@ TEST(Regress2237) { | 
| HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 
| CHECK(SlicedString::cast(*slice)->parent()->IsSeqAsciiString()); | 
| } | 
| + | 
| + | 
| +TEST(Regress2211) { | 
| +  static const int kLoops = 16; | 
| +  InitializeVM(); | 
| +  v8::HandleScope scope; | 
| +  Handle<JSObject> object = v8::Utils::OpenHandle(*v8::Object::New()); | 
| +  Handle<String> key[kLoops]; | 
| +  Handle<String> val[kLoops]; | 
| + | 
| +  // Test adding entries and backing store size. | 
| +  for (int i = 0; i < kLoops; i++) { | 
| +    ScopedVector<char> key_string(8); | 
| +    ScopedVector<char> val_string(8); | 
| +    OS::SNPrintF(key_string, "key #%d", i); | 
| +    OS::SNPrintF(val_string, "val #%d", i); | 
| +    key[i] = v8::Utils::OpenHandle(*v8::String::New(key_string.start())); | 
| +    val[i] = v8::Utils::OpenHandle(*v8::String::New(val_string.start())); | 
| +    JSObject::SetHiddenProperty(object, key[i], val[i]); | 
| +    // Get size of backing store. | 
| +    DescriptorArray* descriptors = object->map()->instance_descriptors(); | 
| +    HiddenPropertiesArray* hidden = HiddenPropertiesArray::cast( | 
| +        object->FastPropertyAt(descriptors->GetFieldIndex(0))); | 
| +    int size = hidden->SizeFor(hidden->length()); | 
| +    printf("%d: %d\n", i, size); | 
| +    // Size is smaller than FixedArray header + twice the entries (key + value). | 
| +    CHECK(size < FixedArray::kHeaderSize + 2 * (2 * (i + 1)) * kPointerSize); | 
| +  } | 
| + | 
| +  // Test stored entries with new key strings. | 
| +  for (int i = 0; i < kLoops; i++) { | 
| +    ScopedVector<char> key_string(8); | 
| +    OS::SNPrintF(key_string, "key #%d", i); | 
| +    key[i] = v8::Utils::OpenHandle(*v8::String::New(key_string.start())); | 
| +    CHECK(String::cast(object->GetHiddenProperty(*key[i]))->Equals(*val[i])); | 
| +  } | 
| + | 
| +  // Test delete entry. | 
| +  object->DeleteHiddenProperty(*key[3]); | 
| + | 
| +  for (int i = 0; i < kLoops; i++) { | 
| +    if (i == 3) { | 
| +      CHECK(object->GetHiddenProperty(*key[i])->IsUndefined()); | 
| +    } else { | 
| +      CHECK(String::cast(object->GetHiddenProperty(*key[i]))->Equals(*val[i])); | 
| +    } | 
| +  } | 
| + | 
| +  // Test re-add entry. | 
| +  key[3] = v8::Utils::OpenHandle(*v8::String::New("re-add key")); | 
| +  val[3] = v8::Utils::OpenHandle(*v8::String::New("re-add val")); | 
| +  JSObject::SetHiddenProperty(object, key[3], val[3]); | 
| + | 
| +  for (int i = 0; i < kLoops; i++) { | 
| +    CHECK(String::cast(object->GetHiddenProperty(*key[i]))->Equals(*val[i])); | 
| +  } | 
| +} | 
|  |