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

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
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/dart_api_state.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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() {
532 FinalizablePersistentHandle* handle; 567 FinalizablePersistentHandle* handle;
533 if (free_list_ != NULL) { 568 {
534 handle = free_list_; 569 MutexLocker ml(mutex_);
535 free_list_ = handle->Next(); 570 if (free_list_ != NULL) {
536 handle->set_raw(Object::null()); 571 handle = free_list_;
537 } else { 572 free_list_ = handle->Next();
538 handle = reinterpret_cast<FinalizablePersistentHandle*>( 573 handle->set_raw(Object::null());
574 return handle;
575 }
576 }
577
578 handle = reinterpret_cast<FinalizablePersistentHandle*>(
539 AllocateScopedHandle()); 579 AllocateScopedHandle());
540 handle->Clear(); 580 handle->Clear();
541 }
542 return handle; 581 return handle;
543 } 582 }
544 583
545 void FreeHandle(FinalizablePersistentHandle* handle) { 584 void FreeHandle(FinalizablePersistentHandle* handle) {
585 MutexLocker ml(mutex_);
546 handle->FreeHandle(free_list()); 586 handle->FreeHandle(free_list());
547 set_free_list(handle); 587 set_free_list(handle);
548 } 588 }
549 589
550 // Validate if passed in handle is a Persistent Handle. 590 // Validate if passed in handle is a Persistent Handle.
551 bool IsValidHandle(Dart_WeakPersistentHandle object) const { 591 bool IsValidHandle(Dart_WeakPersistentHandle object) const {
592 MutexLocker ml(mutex_);
552 return IsValidScopedHandle(reinterpret_cast<uword>(object)); 593 return IsValidScopedHandle(reinterpret_cast<uword>(object));
553 } 594 }
554 595
555 // Returns a count of active handles (used for testing purposes). 596 // Returns a count of active handles (used for testing purposes).
556 int CountHandles() const { 597 int CountHandles() const {
557 return CountScopedHandles(); 598 return CountScopedHandles();
558 } 599 }
559 600
560 private: 601 private:
561 FinalizablePersistentHandle* free_list_; 602 FinalizablePersistentHandle* free_list_;
603 Mutex* mutex_;
562 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); 604 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles);
563 }; 605 };
564 606
565 607
566 // Structure used for the implementation of local scopes used in dart_api. 608 // Structure used for the implementation of local scopes used in dart_api.
567 // These local scopes manage handles and memory allocated in the scope. 609 // These local scopes manage handles and memory allocated in the scope.
568 class ApiLocalScope { 610 class ApiLocalScope {
569 public: 611 public:
570 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : 612 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) :
571 previous_(previous), stack_marker_(stack_marker) { } 613 previous_(previous), stack_marker_(stack_marker) { }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 ref->set_peer(peer); 804 ref->set_peer(peer);
763 ref->set_callback(callback); 805 ref->set_callback(callback);
764 // This may trigger GC, so it must be called last. 806 // This may trigger GC, so it must be called last.
765 ref->SetExternalSize(external_size, isolate); 807 ref->SetExternalSize(external_size, isolate);
766 return ref; 808 return ref;
767 } 809 }
768 810
769 } // namespace dart 811 } // namespace dart
770 812
771 #endif // VM_DART_API_STATE_H_ 813 #endif // VM_DART_API_STATE_H_
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/dart_api_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698