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
This commit is contained in:
mikhail.naganov@gmail.com 2010-07-08 08:00:38 +00:00
parent 149dea4ab0
commit 03b566be92
3 changed files with 13 additions and 8 deletions

View File

@ -74,8 +74,10 @@ VMState::VMState(StateTag state)
if (state == EXTERNAL) state = OTHER;
#endif
state_ = state;
previous_ = current_state_; // Save the previous state.
current_state_ = this; // Install the new state.
// Save the previous state.
previous_ = reinterpret_cast<VMState*>(current_state_);
// Install the new state.
OS::ReleaseStore(&current_state_, reinterpret_cast<AtomicWord>(this));
#ifdef ENABLE_LOGGING_AND_PROFILING
if (FLAG_log_state_changes) {
@ -103,7 +105,8 @@ VMState::VMState(StateTag state)
VMState::~VMState() {
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
if (FLAG_log_state_changes) {

View File

@ -33,7 +33,7 @@ namespace v8 {
namespace internal {
#ifdef ENABLE_VMSTATE_TRACKING
VMState* VMState::current_state_ = NULL;
AtomicWord VMState::current_state_ = 0;
#endif
} } // namespace v8::internal

View File

@ -44,15 +44,17 @@ class VMState BASE_EMBEDDED {
// Used for debug asserts.
static bool is_outermost_external() {
return current_state_ == NULL;
return current_state_ == 0;
}
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() {
return current_state_ ? current_state_->external_callback_ : NULL;
VMState* state = reinterpret_cast<VMState*>(current_state_);
return state ? state->external_callback_ : NULL;
}
private:
@ -62,7 +64,7 @@ class VMState BASE_EMBEDDED {
Address external_callback_;
// A stack of VM states.
static VMState* current_state_;
static AtomicWord current_state_;
#else
public:
explicit VMState(StateTag state) {}