Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: runtime/vm/dart_api_state.h

Issue 2012973002: Background finalization. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #ifndef VM_DART_API_STATE_H_ 5 #ifndef VM_DART_API_STATE_H_
6 #define VM_DART_API_STATE_H_ 6 #define VM_DART_API_STATE_H_
7 7
8 #include "include/dart_api.h" 8 #include "include/dart_api.h"
9 9
10 #include "platform/utils.h" 10 #include "platform/utils.h"
11 #include "vm/bitfield.h" 11 #include "vm/bitfield.h"
12 #include "vm/dart_api_impl.h" 12 #include "vm/dart_api_impl.h"
13 #include "vm/flags.h" 13 #include "vm/flags.h"
14 #include "vm/growable_array.h" 14 #include "vm/growable_array.h"
15 #include "vm/handles.h" 15 #include "vm/handles.h"
16 #include "vm/object.h" 16 #include "vm/object.h"
17 #include "vm/os.h" 17 #include "vm/os.h"
18 #include "vm/os_thread.h"
18 #include "vm/raw_object.h" 19 #include "vm/raw_object.h"
19 #include "vm/os_thread.h" 20 #include "vm/thread_pool.h"
20 #include "vm/visitor.h" 21 #include "vm/visitor.h"
21 #include "vm/weak_table.h" 22 #include "vm/weak_table.h"
22 23
23 #include "vm/handles_impl.h" 24 #include "vm/handles_impl.h"
24 25
25 namespace dart { 26 namespace dart {
26 27
28 class FinalizablePersistentHandle;
29 typedef MallocGrowableArray<FinalizablePersistentHandle*> FinalizationQueue;
30
31
32 class BackgroundFinalizer : public ThreadPool::Task {
33 public:
34 BackgroundFinalizer(Isolate* isolate, FinalizationQueue* queue);
35 virtual ~BackgroundFinalizer() { }
36
37 void Run();
38
39 private:
40 Isolate* isolate_;
41 FinalizationQueue* queue_;
42
43 DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundFinalizer);
44 };
45
46
27 // Implementation of Zone support for very fast allocation of small chunks 47 // Implementation of Zone support for very fast allocation of small chunks
28 // of memory. The chunks cannot be deallocated individually, but instead 48 // of memory. The chunks cannot be deallocated individually, but instead
29 // zones support deallocating all chunks in one fast operation when the 49 // zones support deallocating all chunks in one fast operation when the
30 // scope is exited. 50 // scope is exited.
31 class ApiZone { 51 class ApiZone {
32 public: 52 public:
33 // Create an empty zone. 53 // Create an empty zone.
34 ApiZone() : zone_() { 54 ApiZone() : zone_() {
35 Thread* thread = Thread::Current(); 55 Thread* thread = Thread::Current();
36 Zone* zone = thread != NULL ? thread->zone() : NULL; 56 Zone* zone = thread != NULL ? thread->zone() : NULL;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 void SetExternalSize(intptr_t size, Isolate* isolate) { 240 void SetExternalSize(intptr_t size, Isolate* isolate) {
221 ASSERT(size >= 0); 241 ASSERT(size >= 0);
222 set_external_size(Utils::RoundUp(size, kObjectAlignment)); 242 set_external_size(Utils::RoundUp(size, kObjectAlignment));
223 if (SpaceForExternal() == Heap::kNew) { 243 if (SpaceForExternal() == Heap::kNew) {
224 SetExternalNewSpaceBit(); 244 SetExternalNewSpaceBit();
225 } 245 }
226 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal()); 246 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal());
227 } 247 }
228 248
229 // Called when the referent becomes unreachable. 249 // Called when the referent becomes unreachable.
230 void UpdateUnreachable(Isolate* isolate) { 250 void UpdateUnreachable(Isolate* isolate, FinalizationQueue* queue) {
231 EnsureFreeExternal(isolate); 251 EnsureFreeExternal(isolate);
232 Finalize(isolate, this); 252 if (queue == NULL) {
253 Finalize(isolate, this);
254 } else {
255 MarkForFinalization();
256 queue->Add(this);
257 }
233 } 258 }
234 259
235 // Called when the referent has moved, potentially between generations. 260 // Called when the referent has moved, potentially between generations.
236 void UpdateRelocated(Isolate* isolate) { 261 void UpdateRelocated(Isolate* isolate) {
237 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) { 262 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) {
238 isolate->heap()->PromoteExternal(external_size()); 263 isolate->heap()->PromoteExternal(external_size());
239 ClearExternalNewSpaceBit(); 264 ClearExternalNewSpaceBit();
240 } 265 }
241 } 266 }
242 267
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 SetNext(free_list); 317 SetNext(free_list);
293 } 318 }
294 319
295 void Clear() { 320 void Clear() {
296 raw_ = Object::null(); 321 raw_ = Object::null();
297 peer_ = NULL; 322 peer_ = NULL;
298 external_data_ = 0; 323 external_data_ = 0;
299 callback_ = NULL; 324 callback_ = NULL;
300 } 325 }
301 326
327 void MarkForFinalization() {
328 raw_ = Object::null();
329 ASSERT(callback_ != NULL);
330 }
331
302 void set_raw(RawObject* raw) { raw_ = raw; } 332 void set_raw(RawObject* raw) { raw_ = raw; }
303 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } 333 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
304 void set_raw(const Object& object) { raw_ = object.raw(); } 334 void set_raw(const Object& object) { raw_ = object.raw(); }
305 335
306 void set_peer(void* peer) { peer_ = peer; } 336 void set_peer(void* peer) { peer_ = peer; }
307 337
308 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { 338 void set_callback(Dart_WeakPersistentHandleFinalizer callback) {
309 callback_ = callback; 339 callback_ = callback;
310 } 340 }
311 341
(...skipping 14 matching lines...) Expand all
326 external_data_ = ExternalNewSpaceBit::update(false, external_data_); 356 external_data_ = ExternalNewSpaceBit::update(false, external_data_);
327 } 357 }
328 358
329 // Returns the space to charge for the external size. 359 // Returns the space to charge for the external size.
330 Heap::Space SpaceForExternal() const { 360 Heap::Space SpaceForExternal() const {
331 // Non-heap and VM-heap objects count as old space here. 361 // Non-heap and VM-heap objects count as old space here.
332 return (raw_->IsHeapObject() && raw_->IsNewObject()) ? 362 return (raw_->IsHeapObject() && raw_->IsNewObject()) ?
333 Heap::kNew : Heap::kOld; 363 Heap::kNew : Heap::kOld;
334 } 364 }
335 365
366 friend class BackgroundFinalizer;
367
336 RawObject* raw_; 368 RawObject* raw_;
337 void* peer_; 369 void* peer_;
338 uword external_data_; 370 uword external_data_;
339 Dart_WeakPersistentHandleFinalizer callback_; 371 Dart_WeakPersistentHandleFinalizer callback_;
372
340 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. 373 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
341 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); 374 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle);
342 }; 375 };
343 376
344 377
345 // Local handles repository structure. 378 // Local handles repository structure.
346 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; 379 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize;
347 static const int kLocalHandlesPerChunk = 64; 380 static const int kLocalHandlesPerChunk = 64;
348 static const int kOffsetOfRawPtrInLocalHandle = 0; 381 static const int kOffsetOfRawPtrInLocalHandle = 0;
349 class LocalHandles : Handles<kLocalHandleSizeInWords, 382 class LocalHandles : Handles<kLocalHandleSizeInWords,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0; 527 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0;
495 class FinalizablePersistentHandles 528 class FinalizablePersistentHandles
496 : Handles<kFinalizablePersistentHandleSizeInWords, 529 : Handles<kFinalizablePersistentHandleSizeInWords,
497 kFinalizablePersistentHandlesPerChunk, 530 kFinalizablePersistentHandlesPerChunk,
498 kOffsetOfRawPtrInFinalizablePersistentHandle> { 531 kOffsetOfRawPtrInFinalizablePersistentHandle> {
499 public: 532 public:
500 FinalizablePersistentHandles() 533 FinalizablePersistentHandles()
501 : Handles<kFinalizablePersistentHandleSizeInWords, 534 : Handles<kFinalizablePersistentHandleSizeInWords,
502 kFinalizablePersistentHandlesPerChunk, 535 kFinalizablePersistentHandlesPerChunk,
503 kOffsetOfRawPtrInFinalizablePersistentHandle>(), 536 kOffsetOfRawPtrInFinalizablePersistentHandle>(),
504 free_list_(NULL) { } 537 free_list_(NULL), mutex_(new Mutex()) { }
505 ~FinalizablePersistentHandles() { 538 ~FinalizablePersistentHandles() {
506 free_list_ = NULL; 539 free_list_ = NULL;
540 delete mutex_;
541 mutex_ = NULL;
507 } 542 }
508 543
509 // Accessors. 544 // Accessors.
510 FinalizablePersistentHandle* free_list() const { return free_list_; } 545 FinalizablePersistentHandle* free_list() const { return free_list_; }
511 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } 546 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; }
512 547
513 // Visit all handles stored in the various handle blocks. 548 // Visit all handles stored in the various handle blocks.
514 void VisitHandles(HandleVisitor* visitor) { 549 void VisitHandles(HandleVisitor* visitor) {
515 Handles<kFinalizablePersistentHandleSizeInWords, 550 Handles<kFinalizablePersistentHandleSizeInWords,
516 kFinalizablePersistentHandlesPerChunk, 551 kFinalizablePersistentHandlesPerChunk,
517 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit( 552 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(
518 visitor); 553 visitor);
519 } 554 }
520 555
521 // Visit all object pointers stored in the various handles. 556 // Visit all object pointers stored in the various handles.
522 void VisitObjectPointers(ObjectPointerVisitor* visitor) { 557 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
523 Handles<kFinalizablePersistentHandleSizeInWords, 558 Handles<kFinalizablePersistentHandleSizeInWords,
524 kFinalizablePersistentHandlesPerChunk, 559 kFinalizablePersistentHandlesPerChunk,
525 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers( 560 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers(
526 visitor); 561 visitor);
527 } 562 }
528 563
529 // Allocates a persistent handle, these have to be destroyed explicitly 564 // Allocates a persistent handle, these have to be destroyed explicitly
530 // by calling FreeHandle. 565 // by calling FreeHandle.
531 FinalizablePersistentHandle* AllocateHandle() { 566 FinalizablePersistentHandle* AllocateHandle() {
567 MutexLocker ml(mutex_);
532 FinalizablePersistentHandle* handle; 568 FinalizablePersistentHandle* handle;
533 if (free_list_ != NULL) { 569 if (free_list_ != NULL) {
534 handle = free_list_; 570 handle = free_list_;
535 free_list_ = handle->Next(); 571 free_list_ = handle->Next();
536 handle->set_raw(Object::null()); 572 handle->set_raw(Object::null());
537 } else { 573 } else {
538 handle = reinterpret_cast<FinalizablePersistentHandle*>( 574 handle = reinterpret_cast<FinalizablePersistentHandle*>(
539 AllocateScopedHandle()); 575 AllocateScopedHandle());
540 handle->Clear(); 576 handle->Clear();
541 } 577 }
542 return handle; 578 return handle;
siva 2016/06/06 21:25:31 I am wondering if we should write this as : { M
rmacnak 2016/06/07 21:36:48 Done.
543 } 579 }
544 580
545 void FreeHandle(FinalizablePersistentHandle* handle) { 581 void FreeHandle(FinalizablePersistentHandle* handle) {
582 MutexLocker ml(mutex_);
546 handle->FreeHandle(free_list()); 583 handle->FreeHandle(free_list());
547 set_free_list(handle); 584 set_free_list(handle);
548 } 585 }
549 586
550 // Validate if passed in handle is a Persistent Handle. 587 // Validate if passed in handle is a Persistent Handle.
551 bool IsValidHandle(Dart_WeakPersistentHandle object) const { 588 bool IsValidHandle(Dart_WeakPersistentHandle object) const {
589 MutexLocker ml(mutex_);
552 return IsValidScopedHandle(reinterpret_cast<uword>(object)); 590 return IsValidScopedHandle(reinterpret_cast<uword>(object));
553 } 591 }
554 592
555 // Returns a count of active handles (used for testing purposes). 593 // Returns a count of active handles (used for testing purposes).
556 int CountHandles() const { 594 int CountHandles() const {
557 return CountScopedHandles(); 595 return CountScopedHandles();
558 } 596 }
559 597
560 private: 598 private:
561 FinalizablePersistentHandle* free_list_; 599 FinalizablePersistentHandle* free_list_;
600 Mutex* mutex_;
562 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); 601 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles);
563 }; 602 };
564 603
565 604
566 // Structure used for the implementation of local scopes used in dart_api. 605 // Structure used for the implementation of local scopes used in dart_api.
567 // These local scopes manage handles and memory allocated in the scope. 606 // These local scopes manage handles and memory allocated in the scope.
568 class ApiLocalScope { 607 class ApiLocalScope {
569 public: 608 public:
570 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : 609 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) :
571 previous_(previous), stack_marker_(stack_marker) { } 610 previous_(previous), stack_marker_(stack_marker) { }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 ref->set_peer(peer); 801 ref->set_peer(peer);
763 ref->set_callback(callback); 802 ref->set_callback(callback);
764 // This may trigger GC, so it must be called last. 803 // This may trigger GC, so it must be called last.
765 ref->SetExternalSize(external_size, isolate); 804 ref->SetExternalSize(external_size, isolate);
766 return ref; 805 return ref;
767 } 806 }
768 807
769 } // namespace dart 808 } // namespace dart
770 809
771 #endif // VM_DART_API_STATE_H_ 810 #endif // VM_DART_API_STATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698