| Index: src/execution.cc
|
| diff --git a/src/execution.cc b/src/execution.cc
|
| index c0e9a64fbb000fe94d8a3a0be97c20277ab935e6..634c83ae189e5a2e5cdc8be4abbb0c91f85dcb07 100644
|
| --- a/src/execution.cc
|
| +++ b/src/execution.cc
|
| @@ -540,6 +540,48 @@ void StackGuard::Continue(InterruptFlag after_what) {
|
| }
|
|
|
|
|
| +void StackGuard::RequestInterrupt(InterruptCallback callback, void* data) {
|
| + ExecutionAccess access(isolate_);
|
| + thread_local_.interrupt_flags_ |= API_INTERRUPT;
|
| + thread_local_.interrupt_callback_ = callback;
|
| + thread_local_.interrupt_callback_data_ = data;
|
| + set_interrupt_limits(access);
|
| +}
|
| +
|
| +
|
| +void StackGuard::ClearInterrupt() {
|
| + thread_local_.interrupt_callback_ = 0;
|
| + thread_local_.interrupt_callback_data_ = 0;
|
| + Continue(API_INTERRUPT);
|
| +}
|
| +
|
| +
|
| +bool StackGuard::IsAPIInterrupt() {
|
| + ExecutionAccess access(isolate_);
|
| + return thread_local_.interrupt_flags_ & API_INTERRUPT;
|
| +}
|
| +
|
| +
|
| +void StackGuard::InvokeInterruptCallback() {
|
| + InterruptCallback callback = 0;
|
| + void* data = 0;
|
| +
|
| + {
|
| + ExecutionAccess access(isolate_);
|
| + callback = thread_local_.interrupt_callback_;
|
| + data = thread_local_.interrupt_callback_data_;
|
| + thread_local_.interrupt_callback_ = NULL;
|
| + thread_local_.interrupt_callback_data_ = NULL;
|
| + }
|
| +
|
| + if (callback != NULL) {
|
| + VMState<EXTERNAL> state(isolate_);
|
| + HandleScope handle_scope(isolate_);
|
| + callback(reinterpret_cast<v8::Isolate*>(isolate_), data);
|
| + }
|
| +}
|
| +
|
| +
|
| char* StackGuard::ArchiveStackGuard(char* to) {
|
| ExecutionAccess access(isolate_);
|
| OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
|
| @@ -581,6 +623,7 @@ void StackGuard::ThreadLocal::Clear() {
|
| nesting_ = 0;
|
| postpone_interrupts_nesting_ = 0;
|
| interrupt_flags_ = 0;
|
| + interrupt_callback_ = 0;
|
| }
|
|
|
|
|
| @@ -601,6 +644,7 @@ bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
|
| nesting_ = 0;
|
| postpone_interrupts_nesting_ = 0;
|
| interrupt_flags_ = 0;
|
| + interrupt_callback_ = 0;
|
| return should_set_stack_limits;
|
| }
|
|
|
| @@ -936,6 +980,11 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
|
| return isolate->heap()->undefined_value();
|
| }
|
|
|
| + if (stack_guard->IsAPIInterrupt()) {
|
| + stack_guard->InvokeInterruptCallback();
|
| + stack_guard->Continue(API_INTERRUPT);
|
| + }
|
| +
|
| if (stack_guard->IsGCRequest()) {
|
| isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
|
| "StackGuard GC request");
|
|
|