| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 "vm/become.h" | 5 #include "vm/become.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 | 9 |
| 10 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
| 11 #include "vm/isolate_reload.h" | 11 #include "vm/isolate_reload.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
| 14 #include "vm/safepoint.h" | 14 #include "vm/safepoint.h" |
| 15 #include "vm/timeline.h" | 15 #include "vm/timeline.h" |
| 16 #include "vm/visitor.h" | 16 #include "vm/visitor.h" |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 | 19 |
| 20 DECLARE_FLAG(bool, trace_reload); | |
| 21 | |
| 22 | |
| 23 ForwardingCorpse* ForwardingCorpse::AsForwarder(uword addr, intptr_t size) { | 20 ForwardingCorpse* ForwardingCorpse::AsForwarder(uword addr, intptr_t size) { |
| 24 ASSERT(size >= kObjectAlignment); | 21 ASSERT(size >= kObjectAlignment); |
| 25 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 22 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 26 | 23 |
| 27 ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr); | 24 ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr); |
| 28 | 25 |
| 29 uword tags = 0; | 26 uword tags = 0; |
| 30 tags = RawObject::SizeTag::update(size, tags); | 27 tags = RawObject::SizeTag::update(size, tags); |
| 31 tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags); | 28 tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags); |
| 32 | 29 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 | 141 |
| 145 intptr_t count() const { return count_; } | 142 intptr_t count() const { return count_; } |
| 146 | 143 |
| 147 private: | 144 private: |
| 148 int count_; | 145 int count_; |
| 149 | 146 |
| 150 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor); | 147 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor); |
| 151 }; | 148 }; |
| 152 | 149 |
| 153 | 150 |
| 154 #if defined(DEBUG) | |
| 155 class NoForwardingCorpseTargetsVisitor : public ObjectPointerVisitor { | |
| 156 public: | |
| 157 explicit NoForwardingCorpseTargetsVisitor(Isolate* isolate) | |
| 158 : ObjectPointerVisitor(isolate) { } | |
| 159 | |
| 160 virtual void VisitPointers(RawObject** first, RawObject** last) { | |
| 161 for (RawObject** p = first; p <= last; p++) { | |
| 162 RawObject* target = *p; | |
| 163 if (target->IsHeapObject()) { | |
| 164 ASSERT(!target->IsForwardingCorpse()); | |
| 165 } | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 private: | |
| 170 DISALLOW_COPY_AND_ASSIGN(NoForwardingCorpseTargetsVisitor); | |
| 171 }; | |
| 172 #endif | |
| 173 | |
| 174 | |
| 175 void Become::ElementsForwardIdentity(const Array& before, const Array& after) { | 151 void Become::ElementsForwardIdentity(const Array& before, const Array& after) { |
| 176 Thread* thread = Thread::Current(); | 152 Thread* thread = Thread::Current(); |
| 177 Isolate* isolate = thread->isolate(); | 153 Isolate* isolate = thread->isolate(); |
| 178 Heap* heap = isolate->heap(); | 154 Heap* heap = isolate->heap(); |
| 179 | 155 |
| 180 { | |
| 181 // TODO(rmacnak): Investigate why this is necessary. | |
| 182 heap->CollectGarbage(Heap::kNew); | |
| 183 } | |
| 184 | |
| 185 TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity"); | 156 TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity"); |
| 186 HeapIterationScope his; | 157 HeapIterationScope his; |
| 187 | 158 |
| 188 #if defined(DEBUG) | |
| 189 { | |
| 190 // There should be no pointers to free list elements / forwarding corpses. | |
| 191 NoForwardingCorpseTargetsVisitor visitor(isolate); | |
| 192 isolate->VisitObjectPointers(&visitor, true); | |
| 193 heap->VisitObjectPointers(&visitor); | |
| 194 } | |
| 195 #endif | |
| 196 | |
| 197 // Setup forwarding pointers. | 159 // Setup forwarding pointers. |
| 198 ASSERT(before.Length() == after.Length()); | 160 ASSERT(before.Length() == after.Length()); |
| 199 for (intptr_t i = 0; i < before.Length(); i++) { | 161 for (intptr_t i = 0; i < before.Length(); i++) { |
| 200 RawObject* before_obj = before.At(i); | 162 RawObject* before_obj = before.At(i); |
| 201 RawObject* after_obj = after.At(i); | 163 RawObject* after_obj = after.At(i); |
| 202 | 164 |
| 203 if (before_obj == after_obj) { | 165 if (before_obj == after_obj) { |
| 204 FATAL("become: Cannot self-forward"); | 166 FATAL("become: Cannot self-forward"); |
| 205 } | 167 } |
| 206 if (!before_obj->IsHeapObject()) { | 168 if (!before_obj->IsHeapObject()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 234 | 196 |
| 235 // Weak persistent handles. | 197 // Weak persistent handles. |
| 236 ForwardHeapPointersHandleVisitor handle_visitor; | 198 ForwardHeapPointersHandleVisitor handle_visitor; |
| 237 isolate->VisitWeakPersistentHandles(&handle_visitor); | 199 isolate->VisitWeakPersistentHandles(&handle_visitor); |
| 238 | 200 |
| 239 // Heap pointers (may require updating the remembered set) | 201 // Heap pointers (may require updating the remembered set) |
| 240 ForwardHeapPointersVisitor object_visitor(&pointer_visitor); | 202 ForwardHeapPointersVisitor object_visitor(&pointer_visitor); |
| 241 heap->VisitObjects(&object_visitor); | 203 heap->VisitObjects(&object_visitor); |
| 242 pointer_visitor.VisitingObject(NULL); | 204 pointer_visitor.VisitingObject(NULL); |
| 243 | 205 |
| 244 TIR_Print("Performed %" Pd " heap and %" Pd " handle replacements\n", | 206 #if !defined(PRODUCT) |
| 245 pointer_visitor.count(), | 207 tds.SetNumArguments(2); |
| 246 handle_visitor.count()); | 208 tds.FormatArgument(0, "Remapped objects", "%" Pd, before.Length()); |
| 209 tds.FormatArgument(1, "Remapped references", "%" Pd, |
| 210 pointer_visitor.count() + handle_visitor.count()); |
| 211 #endif |
| 247 } | 212 } |
| 248 | 213 |
| 249 #if defined(DEBUG) | 214 #if defined(DEBUG) |
| 250 for (intptr_t i = 0; i < before.Length(); i++) { | 215 for (intptr_t i = 0; i < before.Length(); i++) { |
| 251 ASSERT(before.At(i) == after.At(i)); | 216 ASSERT(before.At(i) == after.At(i)); |
| 252 } | 217 } |
| 253 | |
| 254 { | |
| 255 // There should be no pointers to forwarding corpses. | |
| 256 NoForwardingCorpseTargetsVisitor visitor(isolate); | |
| 257 isolate->VisitObjectPointers(&visitor, true); | |
| 258 heap->VisitObjectPointers(&visitor); | |
| 259 } | |
| 260 #endif | 218 #endif |
| 261 } | 219 } |
| 262 | 220 |
| 263 } // namespace dart | 221 } // namespace dart |
| OLD | NEW |