Index: test/cctest/test-api.cc |
=================================================================== |
--- test/cctest/test-api.cc (revision 1540) |
+++ test/cctest/test-api.cc (working copy) |
@@ -1255,6 +1255,78 @@ |
} |
+THREADED_TEST(IdentityHash) { |
+ v8::HandleScope scope; |
+ LocalContext env; |
+ |
+ // Ensure that the test starts with an fresh heap to test whether the hash |
+ // code is based on the address. |
+ i::Heap::CollectAllGarbage(); |
+ Local<v8::Object> obj = v8::Object::New(); |
+ int hash = obj->GetIdentityHash(); |
+ int hash1 = obj->GetIdentityHash(); |
+ CHECK_EQ(hash, hash1); |
+ int hash2 = v8::Object::New()->GetIdentityHash(); |
+ // Since the identity hash is essentially a random number two consecutive |
+ // objects should not be assigned the same hash code. If the test below fails |
+ // the random number generator should be evaluated. |
+ CHECK_NE(hash, hash2); |
+ i::Heap::CollectAllGarbage(); |
+ int hash3 = v8::Object::New()->GetIdentityHash(); |
+ // Make sure that the identity hash is not based on the initial address of |
+ // the object alone. If the test below fails the random number generator |
+ // should be evaluated. |
+ CHECK_NE(hash, hash3); |
+ int hash4 = obj->GetIdentityHash(); |
+ CHECK_EQ(hash, hash4); |
+} |
+ |
+ |
+THREADED_TEST(HiddenProperties) { |
+ v8::HandleScope scope; |
+ LocalContext env; |
+ |
+ v8::Local<v8::Object> obj = v8::Object::New(); |
+ v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
+ v8::Local<v8::String> empty = v8_str(""); |
+ v8::Local<v8::String> prop_name = v8_str("prop_name"); |
+ |
+ i::Heap::CollectAllGarbage(); |
+ |
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); |
+ CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ |
+ i::Heap::CollectAllGarbage(); |
+ |
+ // Make sure we do not find the hidden property. |
+ CHECK(!obj->Has(empty)); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK(obj->Get(empty)->IsUndefined()); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK(obj->Set(empty, v8::Integer::New(2003))); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK_EQ(2003, obj->Get(empty)->Int32Value()); |
+ |
+ i::Heap::CollectAllGarbage(); |
+ |
+ // Add another property and delete it afterwards to force the object in |
+ // slow case. |
+ CHECK(obj->Set(prop_name, v8::Integer::New(2008))); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ CHECK(obj->Delete(prop_name)); |
+ CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
+ |
+ i::Heap::CollectAllGarbage(); |
+ |
+ CHECK(obj->DeleteHiddenValue(key)); |
+ CHECK(obj->GetHiddenValue(key).IsEmpty()); |
+} |
+ |
+ |
THREADED_TEST(External) { |
v8::HandleScope scope; |
int x = 3; |