Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/globals.h" | 6 #include "vm/globals.h" |
| 7 #include "vm/object_id_ring.h" | 7 #include "vm/object_id_ring.h" |
| 8 #include "vm/unit_test.h" | 8 #include "vm/unit_test.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 } | 38 } |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 | 41 |
| 42 // Test that serial number wrapping works. | 42 // Test that serial number wrapping works. |
| 43 TEST_CASE(ObjectIdRingSerialWrapTest) { | 43 TEST_CASE(ObjectIdRingSerialWrapTest) { |
| 44 Isolate* isolate = Isolate::Current(); | 44 Isolate* isolate = Isolate::Current(); |
| 45 ObjectIdRing* ring = isolate->object_id_ring(); | 45 ObjectIdRing* ring = isolate->object_id_ring(); |
| 46 ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4); | 46 ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4); |
| 47 intptr_t id; | 47 intptr_t id; |
| 48 ObjectIdRing::LookupResult kind; | |
| 48 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("0")); | 49 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("0")); |
| 49 EXPECT_EQ(0, id); | 50 EXPECT_EQ(0, id); |
| 50 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("1")); | 51 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("1")); |
| 51 EXPECT_EQ(1, id); | 52 EXPECT_EQ(1, id); |
| 52 // Test that id 1 gives us the "1" string. | 53 // Test that id 1 gives us the "1" string. |
| 53 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id), "1"); | 54 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "1"); |
|
turnidge
2014/08/27 16:13:56
Can you add checks that kind is the right value?
rmacnak
2014/08/27 18:09:59
Added
| |
| 54 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 55 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 55 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 56 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 56 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 57 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 57 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 58 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 58 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("2")); | 59 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("2")); |
| 59 EXPECT_EQ(2, id); | 60 EXPECT_EQ(2, id); |
| 60 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); | 61 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); |
| 61 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 62 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 62 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); | 63 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); |
| 63 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 64 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 64 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("3")); | 65 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("3")); |
| 65 EXPECT_EQ(3, id); | 66 EXPECT_EQ(3, id); |
| 66 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); | 67 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); |
| 67 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); | 68 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); |
| 68 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); | 69 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); |
| 69 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); | 70 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); |
| 70 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("4")); | 71 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("4")); |
| 71 EXPECT_EQ(0, id); | 72 EXPECT_EQ(0, id); |
| 72 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id), "4"); | 73 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "4"); |
| 73 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 74 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 74 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); | 75 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); |
| 75 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 76 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 76 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); | 77 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); |
| 77 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("5")); | 78 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("5")); |
| 78 EXPECT_EQ(1, id); | 79 EXPECT_EQ(1, id); |
| 79 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id), "5"); | 80 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "5"); |
| 80 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 81 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 81 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 82 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 82 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 83 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 83 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 84 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 84 } | 85 } |
| 85 | 86 |
| 86 | 87 |
| 87 // Test that the ring table is updated when the scavenger moves an object. | 88 // Test that the ring table is updated when the scavenger moves an object. |
| 88 TEST_CASE(ObjectIdRingScavengeMoveTest) { | 89 TEST_CASE(ObjectIdRingScavengeMoveTest) { |
| 89 const char* kScriptChars = | 90 const char* kScriptChars = |
| 90 "main() {\n" | 91 "main() {\n" |
| 91 " return [1, 2, 3];\n" | 92 " return [1, 2, 3];\n" |
| 92 "}\n"; | 93 "}\n"; |
| 93 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 94 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 94 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 95 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 95 intptr_t list_length = 0; | 96 intptr_t list_length = 0; |
| 96 EXPECT_VALID(result); | 97 EXPECT_VALID(result); |
| 97 EXPECT(!Dart_IsNull(result)); | 98 EXPECT(!Dart_IsNull(result)); |
| 98 EXPECT(Dart_IsList(result)); | 99 EXPECT(Dart_IsList(result)); |
| 99 EXPECT_VALID(Dart_ListLength(result, &list_length)); | 100 EXPECT_VALID(Dart_ListLength(result, &list_length)); |
| 100 EXPECT_EQ(3, list_length); | 101 EXPECT_EQ(3, list_length); |
| 101 Isolate* isolate = Isolate::Current(); | 102 Isolate* isolate = Isolate::Current(); |
| 102 Heap* heap = isolate->heap(); | 103 Heap* heap = isolate->heap(); |
| 103 ObjectIdRing* ring = isolate->object_id_ring(); | 104 ObjectIdRing* ring = isolate->object_id_ring(); |
| 105 ObjectIdRing::LookupResult kind; | |
| 104 RawObject* raw_obj = Api::UnwrapHandle(result); | 106 RawObject* raw_obj = Api::UnwrapHandle(result); |
| 105 // Located in new heap. | 107 // Located in new heap. |
| 106 EXPECT(raw_obj->IsNewObject()); | 108 EXPECT(raw_obj->IsNewObject()); |
| 107 EXPECT_NE(Object::null(), raw_obj); | 109 EXPECT_NE(Object::null(), raw_obj); |
| 108 intptr_t raw_obj_id1 = ring->GetIdForObject(raw_obj); | 110 intptr_t raw_obj_id1 = ring->GetIdForObject(raw_obj); |
| 109 EXPECT_EQ(0, raw_obj_id1); | 111 EXPECT_EQ(0, raw_obj_id1); |
| 110 intptr_t raw_obj_id2 = ring->GetIdForObject(raw_obj); | 112 intptr_t raw_obj_id2 = ring->GetIdForObject(raw_obj); |
| 111 EXPECT_EQ(1, raw_obj_id2); | 113 EXPECT_EQ(1, raw_obj_id2); |
| 112 intptr_t raw_obj_id3 = ring->GetIdForObject(Object::null()); | 114 intptr_t raw_obj_id3 = ring->GetIdForObject(Object::null()); |
| 113 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1); | 115 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 114 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2); | 116 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 115 RawObject* raw_obj3 = ring->GetObjectForId(raw_obj_id3); | 117 RawObject* raw_obj3 = ring->GetObjectForId(raw_obj_id3, &kind); |
| 116 EXPECT_NE(Object::null(), raw_obj1); | 118 EXPECT_NE(Object::null(), raw_obj1); |
| 117 EXPECT_NE(Object::null(), raw_obj2); | 119 EXPECT_NE(Object::null(), raw_obj2); |
| 118 EXPECT_EQ(Object::null(), raw_obj3); | 120 EXPECT_EQ(Object::null(), raw_obj3); |
| 119 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); | 121 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); |
| 120 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); | 122 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); |
| 121 // Force a scavenge. | 123 // Force a scavenge. |
| 122 heap->CollectGarbage(Heap::kNew); | 124 heap->CollectGarbage(Heap::kNew); |
| 123 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1); | 125 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 124 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2); | 126 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 125 RawObject* raw_object_moved3 = ring->GetObjectForId(raw_obj_id3); | 127 RawObject* raw_object_moved3 = ring->GetObjectForId(raw_obj_id3, &kind); |
| 126 EXPECT_NE(Object::null(), raw_object_moved1); | 128 EXPECT_NE(Object::null(), raw_object_moved1); |
| 127 EXPECT_NE(Object::null(), raw_object_moved2); | 129 EXPECT_NE(Object::null(), raw_object_moved2); |
| 128 EXPECT_EQ(Object::null(), raw_object_moved3); | 130 EXPECT_EQ(Object::null(), raw_object_moved3); |
| 129 EXPECT_EQ(RawObject::ToAddr(raw_object_moved1), | 131 EXPECT_EQ(RawObject::ToAddr(raw_object_moved1), |
| 130 RawObject::ToAddr(raw_object_moved2)); | 132 RawObject::ToAddr(raw_object_moved2)); |
| 131 // Test that objects have moved. | 133 // Test that objects have moved. |
| 132 EXPECT_NE(RawObject::ToAddr(raw_obj1), RawObject::ToAddr(raw_object_moved1)); | 134 EXPECT_NE(RawObject::ToAddr(raw_obj1), RawObject::ToAddr(raw_object_moved1)); |
| 133 EXPECT_NE(RawObject::ToAddr(raw_obj2), RawObject::ToAddr(raw_object_moved2)); | 135 EXPECT_NE(RawObject::ToAddr(raw_obj2), RawObject::ToAddr(raw_object_moved2)); |
| 134 // Test that we still point at the same list. | 136 // Test that we still point at the same list. |
| 135 Dart_Handle moved_handle = Api::NewHandle(isolate, raw_object_moved1); | 137 Dart_Handle moved_handle = Api::NewHandle(isolate, raw_object_moved1); |
| 136 EXPECT_VALID(moved_handle); | 138 EXPECT_VALID(moved_handle); |
| 137 EXPECT(!Dart_IsNull(moved_handle)); | 139 EXPECT(!Dart_IsNull(moved_handle)); |
| 138 EXPECT(Dart_IsList(moved_handle)); | 140 EXPECT(Dart_IsList(moved_handle)); |
| 139 EXPECT_VALID(Dart_ListLength(moved_handle, &list_length)); | 141 EXPECT_VALID(Dart_ListLength(moved_handle, &list_length)); |
| 140 EXPECT_EQ(3, list_length); | 142 EXPECT_EQ(3, list_length); |
| 141 } | 143 } |
| 142 | 144 |
| 143 | 145 |
| 144 // Test that the ring table is updated with nulls when the old GC collects. | 146 // Test that the ring table is updated with nulls when the old GC collects. |
| 145 TEST_CASE(ObjectIdRingOldGCTest) { | 147 TEST_CASE(ObjectIdRingOldGCTest) { |
| 146 Isolate* isolate = Isolate::Current(); | 148 Isolate* isolate = Isolate::Current(); |
| 147 Heap* heap = isolate->heap(); | 149 Heap* heap = isolate->heap(); |
| 148 ObjectIdRing* ring = isolate->object_id_ring(); | 150 ObjectIdRing* ring = isolate->object_id_ring(); |
| 149 | 151 |
| 152 ObjectIdRing::LookupResult kind; | |
| 150 intptr_t raw_obj_id1 = -1; | 153 intptr_t raw_obj_id1 = -1; |
| 151 intptr_t raw_obj_id2 = -1; | 154 intptr_t raw_obj_id2 = -1; |
| 152 { | 155 { |
| 153 Dart_EnterScope(); | 156 Dart_EnterScope(); |
| 154 Dart_Handle result; | 157 Dart_Handle result; |
| 155 // Create a string in the old heap. | 158 // Create a string in the old heap. |
| 156 result = Api::NewHandle(isolate, String::New("old", Heap::kOld)); | 159 result = Api::NewHandle(isolate, String::New("old", Heap::kOld)); |
| 157 EXPECT_VALID(result); | 160 EXPECT_VALID(result); |
| 158 intptr_t string_length = 0; | 161 intptr_t string_length = 0; |
| 159 // Inspect string. | 162 // Inspect string. |
| 160 EXPECT(!Dart_IsNull(result)); | 163 EXPECT(!Dart_IsNull(result)); |
| 161 EXPECT(Dart_IsString(result)); | 164 EXPECT(Dart_IsString(result)); |
| 162 EXPECT_VALID(Dart_StringLength(result, &string_length)); | 165 EXPECT_VALID(Dart_StringLength(result, &string_length)); |
| 163 EXPECT_EQ(3, string_length); | 166 EXPECT_EQ(3, string_length); |
| 164 RawObject* raw_obj = Api::UnwrapHandle(result); | 167 RawObject* raw_obj = Api::UnwrapHandle(result); |
| 165 // Verify that it is located in old heap. | 168 // Verify that it is located in old heap. |
| 166 EXPECT(raw_obj->IsOldObject()); | 169 EXPECT(raw_obj->IsOldObject()); |
| 167 EXPECT_NE(Object::null(), raw_obj); | 170 EXPECT_NE(Object::null(), raw_obj); |
| 168 raw_obj_id1 = ring->GetIdForObject(raw_obj); | 171 raw_obj_id1 = ring->GetIdForObject(raw_obj); |
| 169 EXPECT_EQ(0, raw_obj_id1); | 172 EXPECT_EQ(0, raw_obj_id1); |
| 170 raw_obj_id2 = ring->GetIdForObject(raw_obj); | 173 raw_obj_id2 = ring->GetIdForObject(raw_obj); |
| 171 EXPECT_EQ(1, raw_obj_id2); | 174 EXPECT_EQ(1, raw_obj_id2); |
| 172 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1); | 175 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 173 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2); | 176 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 174 EXPECT_NE(Object::null(), raw_obj1); | 177 EXPECT_NE(Object::null(), raw_obj1); |
| 175 EXPECT_NE(Object::null(), raw_obj2); | 178 EXPECT_NE(Object::null(), raw_obj2); |
| 176 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); | 179 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); |
| 177 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); | 180 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); |
| 178 // Exit scope. Freeing result handle. | 181 // Exit scope. Freeing result handle. |
| 179 Dart_ExitScope(); | 182 Dart_ExitScope(); |
| 180 } | 183 } |
| 181 // Force a GC. No reference exist to the old string anymore. It should be | 184 // Force a GC. No reference exist to the old string anymore. It should be |
| 182 // collected and the object id ring will now return the null object for | 185 // collected and the object id ring will now return the null object for |
| 183 // those ids. | 186 // those ids. |
| 184 heap->CollectGarbage(Heap::kOld); | 187 heap->CollectGarbage(Heap::kOld); |
| 185 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1); | 188 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 186 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2); | 189 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 187 // Objects should now be null. | 190 // Objects should now be null. |
| 188 EXPECT_EQ(Object::null(), raw_object_moved1); | 191 EXPECT_EQ(Object::null(), raw_object_moved1); |
| 189 EXPECT_EQ(Object::null(), raw_object_moved2); | 192 EXPECT_EQ(Object::null(), raw_object_moved2); |
| 190 } | 193 } |
| 191 | 194 |
| 192 } // namespace dart | 195 } // namespace dart |
| OLD | NEW |