Index: runtime/vm/isolate.cc |
=================================================================== |
--- runtime/vm/isolate.cc (revision 2291) |
+++ runtime/vm/isolate.cc (working copy) |
@@ -61,7 +61,9 @@ |
debugger_(NULL), |
long_jump_base_(NULL), |
timer_list_(), |
+ mutex_(new Mutex()), |
stack_limit_(0), |
+ saved_stack_limit_(0), |
ast_node_id_(AstNode::kNoId) { |
} |
@@ -75,6 +77,8 @@ |
delete api_state_; |
delete stub_code_; |
delete code_index_table_; |
+ delete mutex_; |
+ mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate. |
} |
@@ -151,10 +155,37 @@ |
void Isolate::SetStackLimit(uword limit) { |
+ MutexLocker ml(mutex_); |
stack_limit_ = limit; |
+ saved_stack_limit_ = limit; |
} |
+void Isolate::ScheduleInterrupts(uword interrupt_bits) { |
+ // TODO(turnidge): Can't use MutexLocker here because MutexLocker is |
+ // a StackResource, which requires a current isolate. Should |
+ // MutexLocker really be a StackResource? |
+ mutex_->Lock(); |
+ ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. |
+ if (stack_limit_ == saved_stack_limit_) { |
+ stack_limit_ = ((uword) -1) & ~kInterruptsMask; |
+ } |
+ stack_limit_ |= interrupt_bits; |
+ mutex_->Unlock(); |
+} |
+ |
+ |
+uword Isolate::GetAndClearInterrupts() { |
+ MutexLocker ml(mutex_); |
+ if (stack_limit_ == saved_stack_limit_) { |
+ return 0; // No interrupt was requested. |
+ } |
+ uword interrupt_bits = stack_limit_ & kInterruptsMask; |
+ stack_limit_ = saved_stack_limit_; |
+ return interrupt_bits; |
+} |
+ |
+ |
static int MostCalledFunctionFirst(const Function* const* a, |
const Function* const* b) { |
if ((*a)->invocation_counter() > (*b)->invocation_counter()) { |
@@ -230,6 +261,7 @@ |
Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; |
+Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL; |
void Isolate::SetCreateCallback(Dart_IsolateCreateCallback cb) { |
@@ -242,6 +274,16 @@ |
} |
+void Isolate::SetInterruptCallback(Dart_IsolateInterruptCallback cb) { |
+ interrupt_callback_ = cb; |
+} |
+ |
+ |
+Dart_IsolateInterruptCallback Isolate::InterruptCallback() { |
+ return interrupt_callback_; |
+} |
+ |
+ |
void Isolate::StandardRunLoop() { |
ASSERT(long_jump_base() != NULL); |
ASSERT(post_message_callback() == &StandardPostMessageCallback); |