Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Unified Diff: runtime/vm/thread.cc

Issue 1812753002: - Move (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/thread.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/thread.cc
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index c5c6e70a7bb8524c897de04779dcfa75b19f837f..31bcaad6f22fbb863c6ab398bfad8b22c90b22ed 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -9,6 +9,7 @@
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/log.h"
+#include "vm/message_handler.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/os_thread.h"
@@ -21,6 +22,12 @@
namespace dart {
+
+DECLARE_FLAG(bool, trace_isolates);
+DECLARE_FLAG(bool, trace_service);
+DECLARE_FLAG(bool, trace_service_verbose);
+
+
Thread::~Thread() {
// We should cleanly exit any isolate before destruction.
ASSERT(isolate_ == NULL);
@@ -49,17 +56,20 @@ Thread::~Thread() {
Thread::Thread(Isolate* isolate)
: BaseThread(false),
- os_thread_(NULL),
- thread_lock_(new Monitor()),
+ stack_limit_(0),
+ stack_overflow_flags_(0),
isolate_(NULL),
heap_(NULL),
+ top_exit_frame_info_(0),
+ store_buffer_block_(NULL),
+ vm_tag_(0),
+ os_thread_(NULL),
+ thread_lock_(new Monitor()),
zone_(NULL),
api_reusable_scope_(NULL),
api_top_scope_(NULL),
- top_exit_frame_info_(0),
top_resource_(NULL),
long_jump_base_(NULL),
- store_buffer_block_(NULL),
no_callback_scope_depth_(0),
#if defined(DEBUG)
top_handle_scope_(NULL),
@@ -67,9 +77,12 @@ Thread::Thread(Isolate* isolate)
no_safepoint_scope_depth_(0),
#endif
reusable_handles_(),
+ saved_stack_limit_(0),
+ deferred_interrupts_mask_(0),
+ deferred_interrupts_(0),
+ stack_overflow_count_(0),
cha_(NULL),
deopt_id_(0),
- vm_tag_(0),
pending_functions_(GrowableObjectArray::null()),
sticky_error_(Error::null()),
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
@@ -282,6 +295,176 @@ void Thread::PrepareForGC() {
}
+void Thread::SetStackLimitFromStackBase(uword stack_base) {
+ // Set stack limit.
+#if defined(USING_SIMULATOR)
+ // Ignore passed-in native stack top and use Simulator stack top.
+ Simulator* sim = Simulator::Current(); // May allocate a simulator.
+ ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one.
+ stack_base = sim->StackTop();
+ // The overflow area is accounted for by the simulator.
+#endif
+ SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize());
+}
+
+
+void Thread::SetStackLimit(uword limit) {
+ // The thread setting the stack limit is not necessarily the thread which
+ // the stack limit is being set on.
+ MonitorLocker ml(thread_lock_);
+ if (stack_limit_ == saved_stack_limit_) {
+ // No interrupt pending, set stack_limit_ too.
+ stack_limit_ = limit;
+ }
+ saved_stack_limit_ = limit;
+}
+
+
+void Thread::ClearStackLimit() {
+ SetStackLimit(~static_cast<uword>(0));
+}
+
+
+/* static */
+uword Thread::GetCurrentStackPointer() {
+ // Since AddressSanitizer's detect_stack_use_after_return instruments the
+ // C++ code to give out fake stack addresses, we call a stub in that case.
+ uword (*func)() = reinterpret_cast<uword (*)()>(
+ StubCode::GetStackPointer_entry()->EntryPoint());
+ // But for performance (and to support simulators), we normally use a local.
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+ uword current_sp = func();
+ return current_sp;
+#else
+ uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
+ return stack_allocated_local_address;
+#endif
+#else
+ uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
+ return stack_allocated_local_address;
+#endif
+}
+
+
+void Thread::ScheduleInterrupts(uword interrupt_bits) {
+ MonitorLocker ml(thread_lock_);
+ ScheduleInterruptsLocked(interrupt_bits);
+}
+
+
+void Thread::ScheduleInterruptsLocked(uword interrupt_bits) {
+ ASSERT(thread_lock_->IsOwnedByCurrentThread());
+ ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask.
+
+ // Check to see if any of the requested interrupts should be deferred.
+ uword defer_bits = interrupt_bits & deferred_interrupts_mask_;
+ if (defer_bits != 0) {
+ deferred_interrupts_ |= defer_bits;
+ interrupt_bits &= ~deferred_interrupts_mask_;
+ if (interrupt_bits == 0) {
+ return;
+ }
+ }
+
+ if (stack_limit_ == saved_stack_limit_) {
+ stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask;
+ }
+ stack_limit_ |= interrupt_bits;
+}
+
+
+uword Thread::GetAndClearInterrupts() {
+ MonitorLocker ml(thread_lock_);
+ 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;
+}
+
+
+void Thread::DeferOOBMessageInterrupts() {
+ MonitorLocker ml(thread_lock_);
+ ASSERT(deferred_interrupts_mask_ == 0);
+ deferred_interrupts_mask_ = kMessageInterrupt;
+
+ if (stack_limit_ != saved_stack_limit_) {
+ // Defer any interrupts which are currently pending.
+ deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_;
+
+ // Clear deferrable interrupts, if present.
+ stack_limit_ &= ~deferred_interrupts_mask_;
+
+ if ((stack_limit_ & kInterruptsMask) == 0) {
+ // No other pending interrupts. Restore normal stack limit.
+ stack_limit_ = saved_stack_limit_;
+ }
+ }
+ if (FLAG_trace_service && FLAG_trace_service_verbose) {
+ OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n",
+ Dart::timestamp(), isolate()->name());
+ }
+}
+
+
+void Thread::RestoreOOBMessageInterrupts() {
+ MonitorLocker ml(thread_lock_);
+ ASSERT(deferred_interrupts_mask_ == kMessageInterrupt);
+ deferred_interrupts_mask_ = 0;
+ if (deferred_interrupts_ != 0) {
+ if (stack_limit_ == saved_stack_limit_) {
+ stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask;
+ }
+ stack_limit_ |= deferred_interrupts_;
+ deferred_interrupts_ = 0;
+ }
+ if (FLAG_trace_service && FLAG_trace_service_verbose) {
+ OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n",
+ Dart::timestamp(), isolate()->name());
+ }
+}
+
+
+RawError* Thread::HandleInterrupts() {
+ uword interrupt_bits = GetAndClearInterrupts();
+ if ((interrupt_bits & kVMInterrupt) != 0) {
+ if (isolate()->store_buffer()->Overflowed()) {
+ if (FLAG_verbose_gc) {
+ OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
+ }
+ heap()->CollectGarbage(Heap::kNew);
+ }
+ }
+ if ((interrupt_bits & kMessageInterrupt) != 0) {
+ MessageHandler::MessageStatus status =
+ isolate()->message_handler()->HandleOOBMessages();
+ if (status != MessageHandler::kOK) {
+ // False result from HandleOOBMessages signals that the isolate should
+ // be terminating.
+ if (FLAG_trace_isolates) {
+ OS::Print("[!] Terminating isolate due to OOB message:\n"
+ "\tisolate: %s\n", isolate()->name());
+ }
+ Thread* thread = Thread::Current();
+ const Error& error = Error::Handle(thread->sticky_error());
+ ASSERT(!error.IsNull() && error.IsUnwindError());
+ thread->clear_sticky_error();
+ return error.raw();
+ }
+ }
+ return Error::null();
+}
+
+
+uword Thread::GetAndClearStackOverflowFlags() {
+ uword stack_overflow_flags = stack_overflow_flags_;
+ stack_overflow_flags_ = 0;
+ return stack_overflow_flags;
+}
+
+
void Thread::StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy) {
StoreBufferRelease(policy);
StoreBufferAcquire();
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698