Index: runtime/vm/isolate.cc |
=================================================================== |
--- runtime/vm/isolate.cc (revision 2528) |
+++ runtime/vm/isolate.cc (working copy) |
@@ -62,7 +62,9 @@ |
debugger_(NULL), |
long_jump_base_(NULL), |
timer_list_(), |
+ mutex_(new Mutex()), |
stack_limit_(0), |
+ saved_stack_limit_(0), |
ast_node_id_(AstNode::kNoId) { |
} |
@@ -76,6 +78,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. |
} |
@@ -152,10 +156,40 @@ |
void Isolate::SetStackLimit(uword limit) { |
siva
2011/12/17 00:05:38
ASSERT(limit != (~static_cast<uword>(0) & ~kInterr
|
- stack_limit_ = limit; |
+ MutexLocker ml(mutex_); |
+ if (stack_limit_ == saved_stack_limit_) { |
+ // No interrupt pending, set stack_limit_ too. |
+ 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_ = ~static_cast<uword>(0) & ~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()) { |
@@ -231,6 +265,7 @@ |
Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; |
+Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL; |
void Isolate::SetCreateCallback(Dart_IsolateCreateCallback cb) { |
@@ -243,6 +278,16 @@ |
} |
+void Isolate::SetInterruptCallback(Dart_IsolateInterruptCallback cb) { |
+ interrupt_callback_ = cb; |
+} |
+ |
+ |
+Dart_IsolateInterruptCallback Isolate::InterruptCallback() { |
+ return interrupt_callback_; |
+} |
+ |
+ |
static RawInstance* DeserializeMessage(void* data) { |
// Create a snapshot object using the buffer. |
const Snapshot* snapshot = Snapshot::SetupFromBuffer(data); |