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/thread.h" | 10 #include "platform/thread.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 } | 113 } |
114 | 114 |
115 RawObject* raw_; | 115 RawObject* raw_; |
116 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 116 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
117 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); | 117 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
118 }; | 118 }; |
119 | 119 |
120 | 120 |
121 // Implementation of persistent handles which are handed out through the | 121 // Implementation of persistent handles which are handed out through the |
122 // dart API. | 122 // dart API. |
123 class WeakPersistentHandle { | 123 class FinalizablePersistentHandle { |
124 public: | 124 public: |
125 // Accessors. | 125 // Accessors. |
126 RawObject* raw() const { return raw_; } | 126 RawObject* raw() const { return raw_; } |
127 void set_raw(RawObject* raw) { raw_ = raw; } | 127 void set_raw(RawObject* raw) { raw_ = raw; } |
128 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } | 128 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
129 void set_raw(const Object& object) { raw_ = object.raw(); } | 129 void set_raw(const Object& object) { raw_ = object.raw(); } |
130 static intptr_t raw_offset() { return OFFSET_OF(WeakPersistentHandle, raw_); } | 130 static intptr_t raw_offset() { |
| 131 return OFFSET_OF(FinalizablePersistentHandle, raw_); |
| 132 } |
131 void* peer() const { return peer_; } | 133 void* peer() const { return peer_; } |
132 void set_peer(void* peer) { peer_ = peer; } | 134 void set_peer(void* peer) { peer_ = peer; } |
133 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; } | 135 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; } |
134 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { | 136 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { |
135 callback_ = callback; | 137 callback_ = callback; |
136 } | 138 } |
137 | 139 |
138 static void Finalize(WeakPersistentHandle* handle) { | 140 static void Finalize(FinalizablePersistentHandle* handle) { |
139 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); | 141 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); |
140 if (callback != NULL) { | 142 if (callback != NULL) { |
141 void* peer = handle->peer(); | 143 void* peer = handle->peer(); |
142 handle->Clear(); | 144 handle->Clear(); |
143 (*callback)(reinterpret_cast<Dart_Handle>(handle), peer); | 145 (*callback)(reinterpret_cast<Dart_Handle>(handle), peer); |
144 } else { | 146 } else { |
145 handle->Clear(); | 147 handle->Clear(); |
146 } | 148 } |
147 } | 149 } |
148 | 150 |
149 private: | 151 private: |
150 friend class WeakPersistentHandles; | 152 friend class FinalizablePersistentHandles; |
151 | 153 |
152 WeakPersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } | 154 FinalizablePersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } |
153 ~WeakPersistentHandle() { } | 155 ~FinalizablePersistentHandle() { } |
154 | 156 |
155 // Overload the raw_ field as a next pointer when adding freed | 157 // Overload the raw_ field as a next pointer when adding freed |
156 // handles to the free list. | 158 // handles to the free list. |
157 WeakPersistentHandle* Next() { | 159 FinalizablePersistentHandle* Next() { |
158 return reinterpret_cast<WeakPersistentHandle*>(raw_); | 160 return reinterpret_cast<FinalizablePersistentHandle*>(raw_); |
159 } | 161 } |
160 void SetNext(WeakPersistentHandle* free_list) { | 162 void SetNext(FinalizablePersistentHandle* free_list) { |
161 raw_ = reinterpret_cast<RawObject*>(free_list); | 163 raw_ = reinterpret_cast<RawObject*>(free_list); |
162 ASSERT(!raw_->IsHeapObject()); | 164 ASSERT(!raw_->IsHeapObject()); |
163 } | 165 } |
164 void FreeHandle(WeakPersistentHandle* free_list) { | 166 void FreeHandle(FinalizablePersistentHandle* free_list) { |
165 SetNext(free_list); | 167 SetNext(free_list); |
166 } | 168 } |
167 | 169 |
168 void Clear() { | 170 void Clear() { |
169 raw_ = Object::null(); | 171 raw_ = Object::null(); |
170 peer_ = NULL; | 172 peer_ = NULL; |
171 callback_ = NULL; | 173 callback_ = NULL; |
172 } | 174 } |
173 | 175 |
174 RawObject* raw_; | 176 RawObject* raw_; |
175 void* peer_; | 177 void* peer_; |
176 Dart_WeakPersistentHandleFinalizer callback_; | 178 Dart_WeakPersistentHandleFinalizer callback_; |
177 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 179 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
178 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandle); | 180 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); |
179 }; | 181 }; |
180 | 182 |
181 | 183 |
182 // Local handles repository structure. | 184 // Local handles repository structure. |
183 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 185 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
184 static const int kLocalHandlesPerChunk = 64; | 186 static const int kLocalHandlesPerChunk = 64; |
185 static const int kOffsetOfRawPtrInLocalHandle = 0; | 187 static const int kOffsetOfRawPtrInLocalHandle = 0; |
186 class LocalHandles : Handles<kLocalHandleSizeInWords, | 188 class LocalHandles : Handles<kLocalHandleSizeInWords, |
187 kLocalHandlesPerChunk, | 189 kLocalHandlesPerChunk, |
188 kOffsetOfRawPtrInLocalHandle> { | 190 kOffsetOfRawPtrInLocalHandle> { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 int CountHandles() const { | 280 int CountHandles() const { |
279 return CountScopedHandles(); | 281 return CountScopedHandles(); |
280 } | 282 } |
281 | 283 |
282 private: | 284 private: |
283 PersistentHandle* free_list_; | 285 PersistentHandle* free_list_; |
284 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); | 286 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); |
285 }; | 287 }; |
286 | 288 |
287 | 289 |
288 // Weak persistent handles repository structure. | 290 // Finalizable persistent handles repository structure. |
289 static const int kWeakPersistentHandleSizeInWords = | 291 static const int kFinalizablePersistentHandleSizeInWords = |
290 sizeof(WeakPersistentHandle) / kWordSize; | 292 sizeof(FinalizablePersistentHandle) / kWordSize; |
291 static const int kWeakPersistentHandlesPerChunk = 64; | 293 static const int kFinalizablePersistentHandlesPerChunk = 64; |
292 static const int kOffsetOfRawPtrInWeakPersistentHandle = 0; | 294 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0; |
293 class WeakPersistentHandles : Handles<kWeakPersistentHandleSizeInWords, | 295 class FinalizablePersistentHandles |
294 kWeakPersistentHandlesPerChunk, | 296 : Handles<kFinalizablePersistentHandleSizeInWords, |
295 kOffsetOfRawPtrInWeakPersistentHandle> { | 297 kFinalizablePersistentHandlesPerChunk, |
| 298 kOffsetOfRawPtrInFinalizablePersistentHandle> { |
296 public: | 299 public: |
297 WeakPersistentHandles() : Handles<kWeakPersistentHandleSizeInWords, | 300 FinalizablePersistentHandles() |
298 kWeakPersistentHandlesPerChunk, | 301 : Handles<kFinalizablePersistentHandleSizeInWords, |
299 kOffsetOfRawPtrInWeakPersistentHandle>(), | 302 kFinalizablePersistentHandlesPerChunk, |
300 free_list_(NULL) { } | 303 kOffsetOfRawPtrInFinalizablePersistentHandle>(), |
301 ~WeakPersistentHandles() { | 304 free_list_(NULL) { } |
| 305 ~FinalizablePersistentHandles() { |
302 free_list_ = NULL; | 306 free_list_ = NULL; |
303 } | 307 } |
304 | 308 |
305 // Accessors. | 309 // Accessors. |
306 WeakPersistentHandle* free_list() const { return free_list_; } | 310 FinalizablePersistentHandle* free_list() const { return free_list_; } |
307 void set_free_list(WeakPersistentHandle* value) { free_list_ = value; } | 311 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } |
308 | 312 |
309 // Visit all handles stored in the various handle blocks. | 313 // Visit all handles stored in the various handle blocks. |
310 void VisitWeakPersistentHandles(HandleVisitor* visitor) { | 314 void VisitHandles(HandleVisitor* visitor) { |
311 Handles<kWeakPersistentHandleSizeInWords, | 315 Handles<kFinalizablePersistentHandleSizeInWords, |
312 kWeakPersistentHandlesPerChunk, | 316 kFinalizablePersistentHandlesPerChunk, |
313 kOffsetOfRawPtrInWeakPersistentHandle>::Visit(visitor); | 317 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(visitor); |
| 318 } |
| 319 |
| 320 // Visit all object pointers stored in the various handles. |
| 321 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 322 Handles<kFinalizablePersistentHandleSizeInWords, |
| 323 kFinalizablePersistentHandlesPerChunk, |
| 324 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers( |
| 325 visitor); |
314 } | 326 } |
315 | 327 |
316 // Allocates a persistent handle, these have to be destroyed explicitly | 328 // Allocates a persistent handle, these have to be destroyed explicitly |
317 // by calling FreeHandle. | 329 // by calling FreeHandle. |
318 WeakPersistentHandle* AllocateHandle() { | 330 FinalizablePersistentHandle* AllocateHandle() { |
319 WeakPersistentHandle* handle; | 331 FinalizablePersistentHandle* handle; |
320 if (free_list_ != NULL) { | 332 if (free_list_ != NULL) { |
321 handle = free_list_; | 333 handle = free_list_; |
322 free_list_ = handle->Next(); | 334 free_list_ = handle->Next(); |
323 } else { | 335 } else { |
324 handle = reinterpret_cast<WeakPersistentHandle*>(AllocateScopedHandle()); | 336 handle = reinterpret_cast<FinalizablePersistentHandle*>( |
| 337 AllocateScopedHandle()); |
325 } | 338 } |
326 handle->set_callback(NULL); | 339 handle->set_callback(NULL); |
327 return handle; | 340 return handle; |
328 } | 341 } |
329 | 342 |
330 void FreeHandle(WeakPersistentHandle* handle) { | 343 void FreeHandle(FinalizablePersistentHandle* handle) { |
331 handle->FreeHandle(free_list()); | 344 handle->FreeHandle(free_list()); |
332 set_free_list(handle); | 345 set_free_list(handle); |
333 } | 346 } |
334 | 347 |
335 // Validate if passed in handle is a Persistent Handle. | 348 // Validate if passed in handle is a Persistent Handle. |
336 bool IsValidHandle(Dart_Handle object) const { | 349 bool IsValidHandle(Dart_Handle object) const { |
337 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 350 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
338 } | 351 } |
339 | 352 |
340 // Returns a count of active handles (used for testing purposes). | 353 // Returns a count of active handles (used for testing purposes). |
341 int CountHandles() const { | 354 int CountHandles() const { |
342 return CountScopedHandles(); | 355 return CountScopedHandles(); |
343 } | 356 } |
344 | 357 |
345 private: | 358 private: |
346 WeakPersistentHandle* free_list_; | 359 FinalizablePersistentHandle* free_list_; |
347 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandles); | 360 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); |
348 }; | 361 }; |
349 | 362 |
350 | 363 |
351 class WeakReference { | 364 class WeakReference { |
352 public: | 365 public: |
353 WeakReference(Dart_Handle* keys, intptr_t keys_length, | 366 WeakReference(Dart_Handle* keys, intptr_t keys_length, |
354 Dart_Handle* values, intptr_t values_length) | 367 Dart_Handle* values, intptr_t values_length) |
355 : next_(NULL), | 368 : next_(NULL), |
356 keys_(keys), num_keys_(keys_length), | 369 keys_(keys), num_keys_(keys_length), |
357 values_(values), num_values_(values_length) { | 370 values_(values), num_values_(values_length) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 464 } |
452 if (false_ != NULL) { | 465 if (false_ != NULL) { |
453 persistent_handles().FreeHandle(false_); | 466 persistent_handles().FreeHandle(false_); |
454 false_ = NULL; | 467 false_ = NULL; |
455 } | 468 } |
456 } | 469 } |
457 | 470 |
458 // Accessors. | 471 // Accessors. |
459 ApiLocalScope* top_scope() const { return top_scope_; } | 472 ApiLocalScope* top_scope() const { return top_scope_; } |
460 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } | 473 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } |
| 474 |
461 PersistentHandles& persistent_handles() { return persistent_handles_; } | 475 PersistentHandles& persistent_handles() { return persistent_handles_; } |
462 WeakPersistentHandles& weak_persistent_handles() { | 476 |
| 477 FinalizablePersistentHandles& weak_persistent_handles() { |
463 return weak_persistent_handles_; | 478 return weak_persistent_handles_; |
464 } | 479 } |
| 480 |
| 481 FinalizablePersistentHandles& prologue_weak_persistent_handles() { |
| 482 return prologue_weak_persistent_handles_; |
| 483 } |
| 484 |
465 WeakReference* delayed_weak_references() { return delayed_weak_references_; } | 485 WeakReference* delayed_weak_references() { return delayed_weak_references_; } |
466 void set_delayed_weak_references(WeakReference* reference) { | 486 void set_delayed_weak_references(WeakReference* reference) { |
467 delayed_weak_references_ = reference; | 487 delayed_weak_references_ = reference; |
468 } | 488 } |
| 489 |
469 void UnwindScopes(uword sp) { | 490 void UnwindScopes(uword sp) { |
470 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { | 491 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { |
471 ApiLocalScope* scope = top_scope_; | 492 ApiLocalScope* scope = top_scope_; |
472 top_scope_ = top_scope_->previous(); | 493 top_scope_ = top_scope_->previous(); |
473 delete scope; | 494 delete scope; |
474 } | 495 } |
475 } | 496 } |
476 | 497 |
477 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 498 void VisitObjectPointers(ObjectPointerVisitor* visitor, |
| 499 bool visit_prologue_weak_handles) { |
478 ApiLocalScope* scope = top_scope_; | 500 ApiLocalScope* scope = top_scope_; |
479 while (scope != NULL) { | 501 while (scope != NULL) { |
480 scope->local_handles()->VisitObjectPointers(visitor); | 502 scope->local_handles()->VisitObjectPointers(visitor); |
481 scope = scope->previous(); | 503 scope = scope->previous(); |
482 } | 504 } |
483 persistent_handles().VisitObjectPointers(visitor); | 505 persistent_handles().VisitObjectPointers(visitor); |
| 506 if (visit_prologue_weak_handles) { |
| 507 prologue_weak_persistent_handles().VisitObjectPointers(visitor); |
| 508 } |
484 } | 509 } |
485 | 510 |
486 void VisitWeakHandles(HandleVisitor* visitor) { | 511 void VisitWeakHandles(HandleVisitor* visitor, |
487 weak_persistent_handles().VisitWeakPersistentHandles(visitor); | 512 bool visit_prologue_weak_handles) { |
| 513 weak_persistent_handles().VisitHandles(visitor); |
| 514 if (visit_prologue_weak_handles) { |
| 515 prologue_weak_persistent_handles().VisitHandles(visitor); |
| 516 } |
488 } | 517 } |
489 | 518 |
490 bool IsValidLocalHandle(Dart_Handle object) const { | 519 bool IsValidLocalHandle(Dart_Handle object) const { |
491 ApiLocalScope* scope = top_scope_; | 520 ApiLocalScope* scope = top_scope_; |
492 while (scope != NULL) { | 521 while (scope != NULL) { |
493 if (scope->local_handles()->IsValidHandle(object)) { | 522 if (scope->local_handles()->IsValidHandle(object)) { |
494 return true; | 523 return true; |
495 } | 524 } |
496 scope = scope->previous(); | 525 scope = scope->previous(); |
497 } | 526 } |
498 return false; | 527 return false; |
499 } | 528 } |
500 | 529 |
501 bool IsValidPersistentHandle(Dart_Handle object) const { | 530 bool IsValidPersistentHandle(Dart_Handle object) const { |
502 return persistent_handles_.IsValidHandle(object); | 531 return persistent_handles_.IsValidHandle(object); |
503 } | 532 } |
504 | 533 |
505 bool IsValidWeakPersistentHandle(Dart_Handle object) const { | 534 bool IsValidWeakPersistentHandle(Dart_Handle object) const { |
506 return weak_persistent_handles_.IsValidHandle(object); | 535 return weak_persistent_handles_.IsValidHandle(object); |
507 } | 536 } |
508 | 537 |
| 538 bool IsValidPrologueWeakPersistentHandle(Dart_Handle object) const { |
| 539 return prologue_weak_persistent_handles_.IsValidHandle(object); |
| 540 } |
| 541 |
509 bool IsProtectedHandle(PersistentHandle* object) const { | 542 bool IsProtectedHandle(PersistentHandle* object) const { |
510 if (object == NULL) return false; | 543 if (object == NULL) return false; |
511 return object == null_ || object == true_ || object == false_; | 544 return object == null_ || object == true_ || object == false_; |
512 } | 545 } |
513 | 546 |
514 int CountLocalHandles() const { | 547 int CountLocalHandles() const { |
515 int total = 0; | 548 int total = 0; |
516 ApiLocalScope* scope = top_scope_; | 549 ApiLocalScope* scope = top_scope_; |
517 while (scope != NULL) { | 550 while (scope != NULL) { |
518 total += scope->local_handles()->CountHandles(); | 551 total += scope->local_handles()->CountHandles(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 } | 595 } |
563 return false_; | 596 return false_; |
564 } | 597 } |
565 | 598 |
566 void DelayWeakReference(WeakReference* reference) { | 599 void DelayWeakReference(WeakReference* reference) { |
567 WeakReference::Push(reference, &delayed_weak_references_); | 600 WeakReference::Push(reference, &delayed_weak_references_); |
568 } | 601 } |
569 | 602 |
570 private: | 603 private: |
571 PersistentHandles persistent_handles_; | 604 PersistentHandles persistent_handles_; |
572 WeakPersistentHandles weak_persistent_handles_; | 605 FinalizablePersistentHandles weak_persistent_handles_; |
| 606 FinalizablePersistentHandles prologue_weak_persistent_handles_; |
573 ApiLocalScope* top_scope_; | 607 ApiLocalScope* top_scope_; |
574 WeakReference* delayed_weak_references_; | 608 WeakReference* delayed_weak_references_; |
575 | 609 |
576 // Persistent handles to important objects. | 610 // Persistent handles to important objects. |
577 PersistentHandle* null_; | 611 PersistentHandle* null_; |
578 PersistentHandle* true_; | 612 PersistentHandle* true_; |
579 PersistentHandle* false_; | 613 PersistentHandle* false_; |
580 | 614 |
581 DISALLOW_COPY_AND_ASSIGN(ApiState); | 615 DISALLOW_COPY_AND_ASSIGN(ApiState); |
582 }; | 616 }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 655 ApiNativeScope::Current()->zone()->GetBaseZone()) {} |
622 ApiGrowableArray() | 656 ApiGrowableArray() |
623 : BaseGrowableArray<T, ValueObject>( | 657 : BaseGrowableArray<T, ValueObject>( |
624 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 658 ApiNativeScope::Current()->zone()->GetBaseZone()) {} |
625 }; | 659 }; |
626 | 660 |
627 | 661 |
628 } // namespace dart | 662 } // namespace dart |
629 | 663 |
630 #endif // VM_DART_API_STATE_H_ | 664 #endif // VM_DART_API_STATE_H_ |
OLD | NEW |