| 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" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 | 14 |
| 15 class ObjectIdRingTestHelper { | 15 class ObjectIdRingTestHelper { |
| 16 public: | 16 public: |
| 17 static void SetCapacityAndMaxSerial(ObjectIdRing* ring, int32_t capacity, | 17 static void SetCapacityAndMaxSerial(ObjectIdRing* ring, int32_t capacity, |
| 18 int32_t max_serial) { | 18 int32_t max_serial) { |
| 19 ring->SetCapacityAndMaxSerial(capacity, max_serial); | 19 ring->SetCapacityAndMaxSerial(capacity, max_serial); |
| 20 } | 20 } |
| 21 | 21 |
| 22 static void ExpectIdIsValid(ObjectIdRing* ring, intptr_t id) { | 22 static void ExpectIdIsValid(ObjectIdRing* ring, intptr_t id) { |
| 23 EXPECT(ring->IsValidId(id)); | 23 EXPECT(ring->IsValidId(id)); |
| 24 } | 24 } |
| 25 | 25 |
| 26 static void ExpectIdIsInvalid(ObjectIdRing* ring, intptr_t id) { | 26 static void ExpectIdIsInvalid(ObjectIdRing* ring, intptr_t id) { |
| 27 EXPECT(!ring->IsValidId(id)); | 27 EXPECT(!ring->IsValidId(id)); |
| 28 } | 28 } |
| 29 | 29 |
| 30 static void ExpectIndexId(ObjectIdRing* ring, intptr_t index, intptr_t id) { |
| 31 EXPECT_EQ(id, ring->IdOfIndex(index)); |
| 32 } |
| 33 |
| 34 static void ExpectInvalidIndex(ObjectIdRing* ring, intptr_t index) { |
| 35 EXPECT_EQ(-1, ring->IdOfIndex(index)); |
| 36 } |
| 37 |
| 30 static RawObject* MakeString(const char* s) { | 38 static RawObject* MakeString(const char* s) { |
| 31 return String::New(s); | 39 return Symbols::New(s); |
| 32 } | 40 } |
| 33 | 41 |
| 34 static void ExpectString(RawObject* obj, const char* s) { | 42 static void ExpectString(RawObject* obj, const char* s) { |
| 35 String& str = String::Handle(); | 43 String& str = String::Handle(); |
| 36 str ^= obj; | 44 str ^= obj; |
| 37 EXPECT(str.Equals(s)); | 45 EXPECT(str.Equals(s)); |
| 38 } | 46 } |
| 39 }; | 47 }; |
| 40 | 48 |
| 41 | 49 |
| 42 // Test that serial number wrapping works. | 50 // Test that serial number wrapping works. |
| 43 TEST_CASE(ObjectIdRingSerialWrapTest) { | 51 TEST_CASE(ObjectIdRingSerialWrapTest) { |
| 44 Isolate* isolate = Isolate::Current(); | 52 Isolate* isolate = Isolate::Current(); |
| 45 ObjectIdRing* ring = isolate->object_id_ring(); | 53 ObjectIdRing* ring = isolate->object_id_ring(); |
| 46 ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4); | 54 ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4); |
| 47 intptr_t id; | 55 intptr_t id; |
| 48 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; | 56 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; |
| 49 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("0")); | 57 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("0")); |
| 50 EXPECT_EQ(0, id); | 58 EXPECT_EQ(0, id); |
| 59 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 0); |
| 60 ObjectIdRingTestHelper::ExpectInvalidIndex(ring, 1); |
| 51 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("1")); | 61 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("1")); |
| 52 EXPECT_EQ(1, id); | 62 EXPECT_EQ(1, id); |
| 63 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 0); |
| 64 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 1); |
| 53 // Test that id 1 gives us the "1" string. | 65 // Test that id 1 gives us the "1" string. |
| 54 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "1"); | 66 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "1"); |
| 55 EXPECT_EQ(ObjectIdRing::kValid, kind); | 67 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 56 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 68 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 69 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 0); |
| 57 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 70 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 71 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 1); |
| 58 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 72 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 59 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 73 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 74 // We have wrapped, index 0 is being reused. |
| 60 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("2")); | 75 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("2")); |
| 61 EXPECT_EQ(2, id); | 76 EXPECT_EQ(2, id); |
| 62 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); | 77 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); |
| 63 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 78 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 79 // Index 0 has id 2. |
| 80 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 2); |
| 64 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); | 81 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); |
| 82 // Index 1 has id 1. |
| 83 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 1); |
| 65 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 84 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 66 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("3")); | 85 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("3")); |
| 67 EXPECT_EQ(3, id); | 86 EXPECT_EQ(3, id); |
| 87 // Index 0 has id 2. |
| 88 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 2); |
| 89 // Index 1 has id 3. |
| 90 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 3); |
| 68 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); | 91 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 0); |
| 69 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); | 92 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); |
| 70 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); | 93 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 2); |
| 71 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); | 94 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); |
| 72 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("4")); | 95 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("4")); |
| 73 EXPECT_EQ(0, id); | 96 EXPECT_EQ(0, id); |
| 97 // Index 0 has id 0. |
| 98 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 0); |
| 99 // Index 1 has id 3. |
| 100 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 3); |
| 74 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "4"); | 101 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "4"); |
| 75 EXPECT_EQ(ObjectIdRing::kValid, kind); | 102 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 76 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 103 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 77 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); | 104 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 1); |
| 78 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 105 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 79 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); | 106 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 3); |
| 80 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("5")); | 107 id = ring->GetIdForObject(ObjectIdRingTestHelper::MakeString("5")); |
| 81 EXPECT_EQ(1, id); | 108 EXPECT_EQ(1, id); |
| 109 // Index 0 has id 0. |
| 110 ObjectIdRingTestHelper::ExpectIndexId(ring, 0, 0); |
| 111 // Index 1 has id 1. |
| 112 ObjectIdRingTestHelper::ExpectIndexId(ring, 1, 1); |
| 82 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "5"); | 113 ObjectIdRingTestHelper::ExpectString(ring->GetObjectForId(id, &kind), "5"); |
| 83 EXPECT_EQ(ObjectIdRing::kValid, kind); | 114 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 84 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); | 115 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 0); |
| 85 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); | 116 ObjectIdRingTestHelper::ExpectIdIsValid(ring, 1); |
| 86 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); | 117 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 2); |
| 87 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); | 118 ObjectIdRingTestHelper::ExpectIdIsInvalid(ring, 3); |
| 88 } | 119 } |
| 89 | 120 |
| 90 | 121 |
| 91 // Test that the ring table is updated when the scavenger moves an object. | 122 // Test that the ring table is updated when the scavenger moves an object. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 105 Isolate* isolate = Isolate::Current(); | 136 Isolate* isolate = Isolate::Current(); |
| 106 Heap* heap = isolate->heap(); | 137 Heap* heap = isolate->heap(); |
| 107 ObjectIdRing* ring = isolate->object_id_ring(); | 138 ObjectIdRing* ring = isolate->object_id_ring(); |
| 108 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; | 139 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; |
| 109 RawObject* raw_obj = Api::UnwrapHandle(result); | 140 RawObject* raw_obj = Api::UnwrapHandle(result); |
| 110 // Located in new heap. | 141 // Located in new heap. |
| 111 EXPECT(raw_obj->IsNewObject()); | 142 EXPECT(raw_obj->IsNewObject()); |
| 112 EXPECT_NE(Object::null(), raw_obj); | 143 EXPECT_NE(Object::null(), raw_obj); |
| 113 intptr_t raw_obj_id1 = ring->GetIdForObject(raw_obj); | 144 intptr_t raw_obj_id1 = ring->GetIdForObject(raw_obj); |
| 114 EXPECT_EQ(0, raw_obj_id1); | 145 EXPECT_EQ(0, raw_obj_id1); |
| 146 // Get id 0 again. |
| 147 EXPECT_EQ(raw_obj_id1, |
| 148 ring->GetIdForObject(raw_obj, ObjectIdRing::kReuseId)); |
| 149 // Add to ring a second time. |
| 115 intptr_t raw_obj_id2 = ring->GetIdForObject(raw_obj); | 150 intptr_t raw_obj_id2 = ring->GetIdForObject(raw_obj); |
| 116 EXPECT_EQ(1, raw_obj_id2); | 151 EXPECT_EQ(1, raw_obj_id2); |
| 152 // Get id 0 again. |
| 153 EXPECT_EQ(raw_obj_id1, |
| 154 ring->GetIdForObject(raw_obj, ObjectIdRing::kReuseId)); |
| 117 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind); | 155 RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 118 EXPECT_EQ(ObjectIdRing::kValid, kind); | 156 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 119 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind); | 157 RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 120 EXPECT_EQ(ObjectIdRing::kValid, kind); | 158 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 121 EXPECT_NE(Object::null(), raw_obj1); | 159 EXPECT_NE(Object::null(), raw_obj1); |
| 122 EXPECT_NE(Object::null(), raw_obj2); | 160 EXPECT_NE(Object::null(), raw_obj2); |
| 123 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); | 161 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1)); |
| 124 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); | 162 EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2)); |
| 125 // Force a scavenge. | 163 // Force a scavenge. |
| 126 heap->CollectGarbage(Heap::kNew); | 164 heap->CollectGarbage(Heap::kNew); |
| 127 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind); | 165 RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind); |
| 128 EXPECT_EQ(ObjectIdRing::kValid, kind); | 166 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 129 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind); | 167 RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind); |
| 130 EXPECT_EQ(ObjectIdRing::kValid, kind); | 168 EXPECT_EQ(ObjectIdRing::kValid, kind); |
| 131 EXPECT_NE(Object::null(), raw_object_moved1); | 169 EXPECT_NE(Object::null(), raw_object_moved1); |
| 132 EXPECT_NE(Object::null(), raw_object_moved2); | 170 EXPECT_NE(Object::null(), raw_object_moved2); |
| 133 EXPECT_EQ(RawObject::ToAddr(raw_object_moved1), | 171 EXPECT_EQ(RawObject::ToAddr(raw_object_moved1), |
| 134 RawObject::ToAddr(raw_object_moved2)); | 172 RawObject::ToAddr(raw_object_moved2)); |
| 135 // Test that objects have moved. | 173 // Test that objects have moved. |
| 136 EXPECT_NE(RawObject::ToAddr(raw_obj1), RawObject::ToAddr(raw_object_moved1)); | 174 EXPECT_NE(RawObject::ToAddr(raw_obj1), RawObject::ToAddr(raw_object_moved1)); |
| 137 EXPECT_NE(RawObject::ToAddr(raw_obj2), RawObject::ToAddr(raw_object_moved2)); | 175 EXPECT_NE(RawObject::ToAddr(raw_obj2), RawObject::ToAddr(raw_object_moved2)); |
| 138 // Test that we still point at the same list. | 176 // Test that we still point at the same list. |
| 139 Dart_Handle moved_handle = Api::NewHandle(isolate, raw_object_moved1); | 177 Dart_Handle moved_handle = Api::NewHandle(isolate, raw_object_moved1); |
| 140 EXPECT_VALID(moved_handle); | 178 EXPECT_VALID(moved_handle); |
| 141 EXPECT(!Dart_IsNull(moved_handle)); | 179 EXPECT(!Dart_IsNull(moved_handle)); |
| 142 EXPECT(Dart_IsList(moved_handle)); | 180 EXPECT(Dart_IsList(moved_handle)); |
| 143 EXPECT_VALID(Dart_ListLength(moved_handle, &list_length)); | 181 EXPECT_VALID(Dart_ListLength(moved_handle, &list_length)); |
| 144 EXPECT_EQ(3, list_length); | 182 EXPECT_EQ(3, list_length); |
| 183 // Test id reuse. |
| 184 EXPECT_EQ(raw_obj_id1, |
| 185 ring->GetIdForObject(raw_object_moved1, ObjectIdRing::kReuseId)); |
| 145 } | 186 } |
| 146 | 187 |
| 147 | 188 |
| 148 // Test that the ring table is updated with nulls when the old GC collects. | 189 // Test that the ring table is updated with nulls when the old GC collects. |
| 149 TEST_CASE(ObjectIdRingOldGCTest) { | 190 TEST_CASE(ObjectIdRingOldGCTest) { |
| 150 Isolate* isolate = Isolate::Current(); | 191 Isolate* isolate = Isolate::Current(); |
| 151 Heap* heap = isolate->heap(); | 192 Heap* heap = isolate->heap(); |
| 152 ObjectIdRing* ring = isolate->object_id_ring(); | 193 ObjectIdRing* ring = isolate->object_id_ring(); |
| 153 | 194 |
| 154 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; | 195 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 } | 265 } |
| 225 | 266 |
| 226 // Check our first entry reports it has expired. | 267 // Check our first entry reports it has expired. |
| 227 obj_lookup = ring->GetObjectForId(obj_id, &kind); | 268 obj_lookup = ring->GetObjectForId(obj_id, &kind); |
| 228 EXPECT_EQ(ObjectIdRing::kExpired, kind); | 269 EXPECT_EQ(ObjectIdRing::kExpired, kind); |
| 229 EXPECT_NE(obj.raw(), obj_lookup); | 270 EXPECT_NE(obj.raw(), obj_lookup); |
| 230 EXPECT_EQ(Object::null(), obj_lookup); | 271 EXPECT_EQ(Object::null(), obj_lookup); |
| 231 } | 272 } |
| 232 | 273 |
| 233 } // namespace dart | 274 } // namespace dart |
| OLD | NEW |