Index: runtime/vm/dart_entry.cc |
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc |
index 63e2689a3555afa358fefb76ae8dc6289a2887f8..5a252e57a14d6a71c4c1b071aaecaea59f631549 100644 |
--- a/runtime/vm/dart_entry.cc |
+++ b/runtime/vm/dart_entry.cc |
@@ -33,26 +33,39 @@ RawObject* DartEntry::InvokeFunction(const Function& function, |
class ScopedIsolateStackLimits : public ValueObject { |
public: |
- explicit ScopedIsolateStackLimits(Isolate* isolate) |
- : isolate_(isolate), stack_base_(Isolate::GetCurrentStackPointer()) { |
- ASSERT(isolate_ != NULL); |
- ASSERT(isolate_ == Isolate::Current()); |
- if (stack_base_ >= isolate_->stack_base()) { |
- isolate_->SetStackLimitFromStackBase(stack_base_); |
+ explicit ScopedIsolateStackLimits(Thread* thread) |
+ : thread_(thread), saved_stack_limit_(0) { |
+ ASSERT(thread != NULL); |
+ // Set the thread's stack_base based on the current |
+ // stack pointer, we keep refining this value as we |
+ // see higher stack pointers (Note: we assume the stack |
+ // grows from high to low addresses). |
+ OSThread* os_thread = thread->os_thread(); |
+ ASSERT(os_thread != NULL); |
+ uword current_sp = Isolate::GetCurrentStackPointer(); |
+ if (current_sp > os_thread->stack_base()) { |
+ os_thread->set_stack_base(current_sp); |
} |
+ // Save the Isolate's current stack limit and adjust the stack |
+ // limit based on the thread's stack_base. |
+ Isolate* isolate = thread->isolate(); |
+ ASSERT(isolate == Isolate::Current()); |
+ saved_stack_limit_ = isolate->saved_stack_limit(); |
+ isolate->SetStackLimitFromStackBase(os_thread->stack_base()); |
} |
~ScopedIsolateStackLimits() { |
- ASSERT(isolate_ == Isolate::Current()); |
- if (isolate_->stack_base() == stack_base_) { |
- // Bottomed out. |
- isolate_->ClearStackLimit(); |
- } |
+ Isolate* isolate = thread_->isolate(); |
+ ASSERT(isolate == Isolate::Current()); |
+ // Since we started with a stack limit of 0 we should be getting back |
+ // to a stack limit of 0 when all nested invocations are done and |
+ // we have bottomed out. |
+ isolate->SetStackLimit(saved_stack_limit_); |
} |
private: |
- Isolate* isolate_; |
- uword stack_base_; |
+ Thread* thread_; |
+ uword saved_stack_limit_; |
}; |
@@ -84,7 +97,6 @@ RawObject* DartEntry::InvokeFunction(const Function& function, |
// compiled. |
Thread* thread = Thread::Current(); |
Zone* zone = thread->zone(); |
- Isolate* isolate = thread->isolate(); |
ASSERT(thread->IsMutatorThread()); |
if (!function.HasCode()) { |
const Error& error = Error::Handle( |
@@ -99,7 +111,7 @@ RawObject* DartEntry::InvokeFunction(const Function& function, |
const Code& code = Code::Handle(zone, function.CurrentCode()); |
ASSERT(!code.IsNull()); |
ASSERT(thread->no_callback_scope_depth() == 0); |
- ScopedIsolateStackLimits stack_limit(isolate); |
+ ScopedIsolateStackLimits stack_limit(thread); |
SuspendLongJumpScope suspend_long_jump_scope(thread); |
#if defined(USING_SIMULATOR) |
return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call( |