OLD | NEW |
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/raw_object.h" | 18 #include "vm/raw_object.h" |
19 #include "vm/os_thread.h" | 19 #include "vm/os_thread.h" |
20 #include "vm/visitor.h" | 20 #include "vm/visitor.h" |
21 #include "vm/weak_table.h" | 21 #include "vm/weak_table.h" |
22 | 22 |
23 #include "vm/handles_impl.h" | 23 #include "vm/handles_impl.h" |
24 | 24 |
25 namespace dart { | 25 namespace dart { |
26 | 26 |
27 DECLARE_DEBUG_FLAG(bool, trace_zones); | |
28 DECLARE_DEBUG_FLAG(bool, trace_handles); | |
29 | |
30 // Implementation of Zone support for very fast allocation of small chunks | 27 // Implementation of Zone support for very fast allocation of small chunks |
31 // of memory. The chunks cannot be deallocated individually, but instead | 28 // of memory. The chunks cannot be deallocated individually, but instead |
32 // zones support deallocating all chunks in one fast operation when the | 29 // zones support deallocating all chunks in one fast operation when the |
33 // scope is exited. | 30 // scope is exited. |
34 class ApiZone { | 31 class ApiZone { |
35 public: | 32 public: |
36 // Create an empty zone. | 33 // Create an empty zone. |
37 ApiZone() : zone_() { | 34 ApiZone() : zone_() { |
38 Thread* thread = Thread::Current(); | 35 Thread* thread = Thread::Current(); |
39 Zone* zone = thread != NULL ? thread->zone() : NULL; | 36 Zone* zone = thread != NULL ? thread->zone() : NULL; |
40 zone_.Link(zone); | 37 zone_.Link(zone); |
41 if (thread != NULL) { | 38 if (thread != NULL) { |
42 thread->set_zone(&zone_); | 39 thread->set_zone(&zone_); |
43 } | 40 } |
44 #ifdef DEBUG | |
45 if (FLAG_trace_zones) { | 41 if (FLAG_trace_zones) { |
46 OS::PrintErr("*** Starting a new Api zone 0x%" Px "(0x%" Px ")\n", | 42 OS::PrintErr("*** Starting a new Api zone 0x%" Px "(0x%" Px ")\n", |
47 reinterpret_cast<intptr_t>(this), | 43 reinterpret_cast<intptr_t>(this), |
48 reinterpret_cast<intptr_t>(&zone_)); | 44 reinterpret_cast<intptr_t>(&zone_)); |
49 } | 45 } |
50 #endif | |
51 } | 46 } |
52 | 47 |
53 // Delete all memory associated with the zone. | 48 // Delete all memory associated with the zone. |
54 ~ApiZone() { | 49 ~ApiZone() { |
55 Thread* thread = Thread::Current(); | 50 Thread* thread = Thread::Current(); |
56 #if defined(DEBUG) | 51 #if defined(DEBUG) |
57 if (thread == NULL) { | 52 if (thread == NULL) { |
58 ASSERT(zone_.handles()->CountScopedHandles() == 0); | 53 ASSERT(zone_.handles()->CountScopedHandles() == 0); |
59 ASSERT(zone_.handles()->CountZoneHandles() == 0); | 54 ASSERT(zone_.handles()->CountZoneHandles() == 0); |
60 } | 55 } |
61 #endif | 56 #endif |
62 if ((thread != NULL) && (thread->zone() == &zone_)) { | 57 if ((thread != NULL) && (thread->zone() == &zone_)) { |
63 thread->set_zone(zone_.previous_); | 58 thread->set_zone(zone_.previous_); |
64 } | 59 } |
65 #ifdef DEBUG | |
66 if (FLAG_trace_zones) { | 60 if (FLAG_trace_zones) { |
67 OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n", | 61 OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n", |
68 reinterpret_cast<intptr_t>(this), | 62 reinterpret_cast<intptr_t>(this), |
69 reinterpret_cast<intptr_t>(&zone_)); | 63 reinterpret_cast<intptr_t>(&zone_)); |
70 } | 64 } |
71 #endif | |
72 } | 65 } |
73 | 66 |
74 // Allocates an array sized to hold 'len' elements of type | 67 // Allocates an array sized to hold 'len' elements of type |
75 // 'ElementType'. Checks for integer overflow when performing the | 68 // 'ElementType'. Checks for integer overflow when performing the |
76 // size computation. | 69 // size computation. |
77 template <class ElementType> | 70 template <class ElementType> |
78 ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } | 71 ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } |
79 | 72 |
80 // Allocates an array sized to hold 'len' elements of type | 73 // Allocates an array sized to hold 'len' elements of type |
81 // 'ElementType'. The new array is initialized from the memory of | 74 // 'ElementType'. The new array is initialized from the memory of |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 346 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
354 static const int kLocalHandlesPerChunk = 64; | 347 static const int kLocalHandlesPerChunk = 64; |
355 static const int kOffsetOfRawPtrInLocalHandle = 0; | 348 static const int kOffsetOfRawPtrInLocalHandle = 0; |
356 class LocalHandles : Handles<kLocalHandleSizeInWords, | 349 class LocalHandles : Handles<kLocalHandleSizeInWords, |
357 kLocalHandlesPerChunk, | 350 kLocalHandlesPerChunk, |
358 kOffsetOfRawPtrInLocalHandle> { | 351 kOffsetOfRawPtrInLocalHandle> { |
359 public: | 352 public: |
360 LocalHandles() : Handles<kLocalHandleSizeInWords, | 353 LocalHandles() : Handles<kLocalHandleSizeInWords, |
361 kLocalHandlesPerChunk, | 354 kLocalHandlesPerChunk, |
362 kOffsetOfRawPtrInLocalHandle>() { | 355 kOffsetOfRawPtrInLocalHandle>() { |
363 #ifdef DEBUG | |
364 if (FLAG_trace_handles) { | 356 if (FLAG_trace_handles) { |
365 OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n", | 357 OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n", |
366 reinterpret_cast<intptr_t>(this)); | 358 reinterpret_cast<intptr_t>(this)); |
367 } | 359 } |
368 #endif | |
369 } | 360 } |
370 ~LocalHandles() { | 361 ~LocalHandles() { |
371 #ifdef DEBUG | |
372 if (FLAG_trace_handles) { | 362 if (FLAG_trace_handles) { |
373 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", | 363 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", |
374 reinterpret_cast<intptr_t>(this), | 364 reinterpret_cast<intptr_t>(this), |
375 CountHandles()); | 365 CountHandles()); |
376 OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n", | 366 OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n", |
377 reinterpret_cast<intptr_t>(this)); | 367 reinterpret_cast<intptr_t>(this)); |
378 } | 368 } |
379 #endif | |
380 } | 369 } |
381 | 370 |
382 | 371 |
383 // Visit all object pointers stored in the various handles. | 372 // Visit all object pointers stored in the various handles. |
384 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 373 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
385 Handles<kLocalHandleSizeInWords, | 374 Handles<kLocalHandleSizeInWords, |
386 kLocalHandlesPerChunk, | 375 kLocalHandlesPerChunk, |
387 kOffsetOfRawPtrInLocalHandle>::VisitObjectPointers(visitor); | 376 kOffsetOfRawPtrInLocalHandle>::VisitObjectPointers(visitor); |
388 } | 377 } |
389 | 378 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 static const int kPersistentHandlesPerChunk = 64; | 411 static const int kPersistentHandlesPerChunk = 64; |
423 static const int kOffsetOfRawPtrInPersistentHandle = 0; | 412 static const int kOffsetOfRawPtrInPersistentHandle = 0; |
424 class PersistentHandles : Handles<kPersistentHandleSizeInWords, | 413 class PersistentHandles : Handles<kPersistentHandleSizeInWords, |
425 kPersistentHandlesPerChunk, | 414 kPersistentHandlesPerChunk, |
426 kOffsetOfRawPtrInPersistentHandle> { | 415 kOffsetOfRawPtrInPersistentHandle> { |
427 public: | 416 public: |
428 PersistentHandles() : Handles<kPersistentHandleSizeInWords, | 417 PersistentHandles() : Handles<kPersistentHandleSizeInWords, |
429 kPersistentHandlesPerChunk, | 418 kPersistentHandlesPerChunk, |
430 kOffsetOfRawPtrInPersistentHandle>(), | 419 kOffsetOfRawPtrInPersistentHandle>(), |
431 free_list_(NULL) { | 420 free_list_(NULL) { |
432 #ifdef DEBUG | |
433 if (FLAG_trace_handles) { | 421 if (FLAG_trace_handles) { |
434 OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n", | 422 OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n", |
435 reinterpret_cast<intptr_t>(this)); | 423 reinterpret_cast<intptr_t>(this)); |
436 } | 424 } |
437 #endif | |
438 } | 425 } |
439 ~PersistentHandles() { | 426 ~PersistentHandles() { |
440 free_list_ = NULL; | 427 free_list_ = NULL; |
441 #ifdef DEBUG | |
442 if (FLAG_trace_handles) { | 428 if (FLAG_trace_handles) { |
443 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", | 429 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", |
444 reinterpret_cast<intptr_t>(this), | 430 reinterpret_cast<intptr_t>(this), |
445 CountHandles()); | 431 CountHandles()); |
446 OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n", | 432 OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n", |
447 reinterpret_cast<intptr_t>(this)); | 433 reinterpret_cast<intptr_t>(this)); |
448 } | 434 } |
449 #endif | |
450 } | 435 } |
451 | 436 |
452 // Accessors. | 437 // Accessors. |
453 PersistentHandle* free_list() const { return free_list_; } | 438 PersistentHandle* free_list() const { return free_list_; } |
454 void set_free_list(PersistentHandle* value) { free_list_ = value; } | 439 void set_free_list(PersistentHandle* value) { free_list_ = value; } |
455 | 440 |
456 // Visit all object pointers stored in the various handles. | 441 // Visit all object pointers stored in the various handles. |
457 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 442 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
458 Handles<kPersistentHandleSizeInWords, | 443 Handles<kPersistentHandleSizeInWords, |
459 kPersistentHandlesPerChunk, | 444 kPersistentHandlesPerChunk, |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 ref->set_peer(peer); | 755 ref->set_peer(peer); |
771 ref->set_callback(callback); | 756 ref->set_callback(callback); |
772 // This may trigger GC, so it must be called last. | 757 // This may trigger GC, so it must be called last. |
773 ref->SetExternalSize(external_size, isolate); | 758 ref->SetExternalSize(external_size, isolate); |
774 return ref; | 759 return ref; |
775 } | 760 } |
776 | 761 |
777 } // namespace dart | 762 } // namespace dart |
778 | 763 |
779 #endif // VM_DART_API_STATE_H_ | 764 #endif // VM_DART_API_STATE_H_ |
OLD | NEW |