Fix concurrent access to VMState::current_state_.

The main fix is for current_state() and external_callback() accessors.
I also applied memory access ordering on current_state_ modification,
mainly to reflect the fact that it is being shared among VM and profiler
sampler threads.

BUG=361

Review URL: http://codereview.chromium.org/2852047

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5035 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 149dea4a
...@@ -74,8 +74,10 @@ VMState::VMState(StateTag state) ...@@ -74,8 +74,10 @@ VMState::VMState(StateTag state)
if (state == EXTERNAL) state = OTHER; if (state == EXTERNAL) state = OTHER;
#endif #endif
state_ = state; state_ = state;
previous_ = current_state_; // Save the previous state. // Save the previous state.
current_state_ = this; // Install the new state. previous_ = reinterpret_cast<VMState*>(current_state_);
// Install the new state.
OS::ReleaseStore(&current_state_, reinterpret_cast<AtomicWord>(this));
#ifdef ENABLE_LOGGING_AND_PROFILING #ifdef ENABLE_LOGGING_AND_PROFILING
if (FLAG_log_state_changes) { if (FLAG_log_state_changes) {
...@@ -103,7 +105,8 @@ VMState::VMState(StateTag state) ...@@ -103,7 +105,8 @@ VMState::VMState(StateTag state)
VMState::~VMState() { VMState::~VMState() {
if (disabled_) return; if (disabled_) return;
current_state_ = previous_; // Return to the previous state. // Return to the previous state.
OS::ReleaseStore(&current_state_, reinterpret_cast<AtomicWord>(previous_));
#ifdef ENABLE_LOGGING_AND_PROFILING #ifdef ENABLE_LOGGING_AND_PROFILING
if (FLAG_log_state_changes) { if (FLAG_log_state_changes) {
......
...@@ -33,7 +33,7 @@ namespace v8 { ...@@ -33,7 +33,7 @@ namespace v8 {
namespace internal { namespace internal {
#ifdef ENABLE_VMSTATE_TRACKING #ifdef ENABLE_VMSTATE_TRACKING
VMState* VMState::current_state_ = NULL; AtomicWord VMState::current_state_ = 0;
#endif #endif
} } // namespace v8::internal } } // namespace v8::internal
...@@ -44,15 +44,17 @@ class VMState BASE_EMBEDDED { ...@@ -44,15 +44,17 @@ class VMState BASE_EMBEDDED {
// Used for debug asserts. // Used for debug asserts.
static bool is_outermost_external() { static bool is_outermost_external() {
return current_state_ == NULL; return current_state_ == 0;
} }
static StateTag current_state() { static StateTag current_state() {
return current_state_ ? current_state_->state() : EXTERNAL; VMState* state = reinterpret_cast<VMState*>(current_state_);
return state ? state->state() : EXTERNAL;
} }
static Address external_callback() { static Address external_callback() {
return current_state_ ? current_state_->external_callback_ : NULL; VMState* state = reinterpret_cast<VMState*>(current_state_);
return state ? state->external_callback_ : NULL;
} }
private: private:
...@@ -62,7 +64,7 @@ class VMState BASE_EMBEDDED { ...@@ -62,7 +64,7 @@ class VMState BASE_EMBEDDED {
Address external_callback_; Address external_callback_;
// A stack of VM states. // A stack of VM states.
static VMState* current_state_; static AtomicWord current_state_;
#else #else
public: public:
explicit VMState(StateTag state) {} explicit VMState(StateTag state) {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment