| Index: runtime/vm/thread.cc
|
| diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
|
| index 7bdcff11e4c03a9f6afc8431aa983ad334fecc8d..3400af3ce750c5b162ab166d1e307052d8f30948 100644
|
| --- a/runtime/vm/thread.cc
|
| +++ b/runtime/vm/thread.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "vm/thread.h"
|
|
|
| +#include "vm/dart_api_state.h"
|
| #include "vm/growable_array.h"
|
| #include "vm/isolate.h"
|
| #include "vm/lockers.h"
|
| @@ -43,6 +44,8 @@ Thread::Thread(Isolate* isolate)
|
| isolate_(NULL),
|
| heap_(NULL),
|
| zone_(NULL),
|
| + api_reusable_scope_(NULL),
|
| + api_top_scope_(NULL),
|
| top_exit_frame_info_(0),
|
| top_resource_(NULL),
|
| long_jump_base_(NULL),
|
| @@ -274,10 +277,18 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
| // Visit objects in thread specific handles area.
|
| reusable_handles_.VisitObjectPointers(visitor);
|
|
|
| + // Visit the pending functions.
|
| if (pending_functions_ != GrowableObjectArray::null()) {
|
| visitor->VisitPointer(
|
| reinterpret_cast<RawObject**>(&pending_functions_));
|
| }
|
| +
|
| + // Visit the api local scope as it has all the api local handles.
|
| + ApiLocalScope* scope = api_top_scope_;
|
| + while (scope != NULL) {
|
| + scope->local_handles()->VisitObjectPointers(visitor);
|
| + scope = scope->previous();
|
| + }
|
| }
|
|
|
|
|
| @@ -333,6 +344,54 @@ LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET)
|
| }
|
|
|
|
|
| +bool Thread::IsValidLocalHandle(Dart_Handle object) const {
|
| + ApiLocalScope* scope = api_top_scope_;
|
| + while (scope != NULL) {
|
| + if (scope->local_handles()->IsValidHandle(object)) {
|
| + return true;
|
| + }
|
| + scope = scope->previous();
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +int Thread::CountLocalHandles() const {
|
| + int total = 0;
|
| + ApiLocalScope* scope = api_top_scope_;
|
| + while (scope != NULL) {
|
| + total += scope->local_handles()->CountHandles();
|
| + scope = scope->previous();
|
| + }
|
| + return total;
|
| +}
|
| +
|
| +
|
| +int Thread::ZoneSizeInBytes() const {
|
| + int total = 0;
|
| + ApiLocalScope* scope = api_top_scope_;
|
| + while (scope != NULL) {
|
| + total += scope->zone()->SizeInBytes();
|
| + scope = scope->previous();
|
| + }
|
| + return total;
|
| +}
|
| +
|
| +
|
| +void Thread::UnwindScopes(uword stack_marker) {
|
| + // Unwind all scopes using the same stack_marker, i.e. all scopes allocated
|
| + // under the same top_exit_frame_info.
|
| + ApiLocalScope* scope = api_top_scope_;
|
| + while (scope != NULL &&
|
| + scope->stack_marker() != 0 &&
|
| + scope->stack_marker() == stack_marker) {
|
| + api_top_scope_ = scope->previous();
|
| + delete scope;
|
| + scope = api_top_scope_;
|
| + }
|
| +}
|
| +
|
| +
|
| DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
|
| : StackResource(thread) {
|
| if (thread != NULL) {
|
|
|