Commit 5e9db683 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

no longer need a guard in StackTraceStack

Summary:
The guard targets its former use in `__thread` variables, which must be trivial. But it is now used in `thread_local` variables, which can have default constructors.

The relevant switch from `__thread` to `thread_local` was in {D27559375 (https://github.com/facebook/folly/commit/eeec4600b857dd70ca6b30837d14bb79cf9a2ef7)}.

Reviewed By: luciang

Differential Revision: D28683625

fbshipit-source-id: af74801a13e479a262ea50e6d3f89053e67d7ac9
parent a73640d7
...@@ -47,7 +47,6 @@ void StackTraceStack::Node::deallocate() { ...@@ -47,7 +47,6 @@ void StackTraceStack::Node::deallocate() {
} }
bool StackTraceStack::pushCurrent() { bool StackTraceStack::pushCurrent() {
checkGuard();
auto node = Node::allocate(); auto node = Node::allocate();
if (!node) { if (!node) {
// cannot allocate memory // cannot allocate memory
...@@ -61,61 +60,54 @@ bool StackTraceStack::pushCurrent() { ...@@ -61,61 +60,54 @@ bool StackTraceStack::pushCurrent() {
} }
node->frameCount = n; node->frameCount = n;
node->next = state_[kTopIdx]; node->next = state_;
state_[kTopIdx] = node; state_ = node;
return true; return true;
} }
bool StackTraceStack::pop() { bool StackTraceStack::pop() {
checkGuard(); if (!state_) {
if (!state_[kTopIdx]) {
return false; return false;
} }
auto node = state_[kTopIdx]; auto node = state_;
state_[kTopIdx] = node->next; state_ = node->next;
node->deallocate(); node->deallocate();
return true; return true;
} }
bool StackTraceStack::moveTopFrom(StackTraceStack& other) { bool StackTraceStack::moveTopFrom(StackTraceStack& other) {
checkGuard(); if (!other.state_) {
if (!other.state_[kTopIdx]) {
return false; return false;
} }
auto node = other.state_[kTopIdx]; auto node = other.state_;
other.state_[kTopIdx] = node->next; other.state_ = node->next;
node->next = state_[kTopIdx]; node->next = state_;
state_[kTopIdx] = node; state_ = node;
return true; return true;
} }
void StackTraceStack::clear() { void StackTraceStack::clear() {
checkGuard(); while (state_) {
while (state_[kTopIdx]) {
pop(); pop();
} }
} }
StackTrace* StackTraceStack::top() { StackTrace* StackTraceStack::top() {
checkGuard(); return state_;
return state_[kTopIdx];
} }
const StackTrace* StackTraceStack::top() const { const StackTrace* StackTraceStack::top() const {
checkGuard(); return state_;
return state_[kTopIdx];
} }
StackTrace* StackTraceStack::next(StackTrace* p) { StackTrace* StackTraceStack::next(StackTrace* p) {
checkGuard();
assert(p); assert(p);
return static_cast<Node*>(p)->next; return static_cast<Node*>(p)->next;
} }
const StackTrace* StackTraceStack::next(const StackTrace* p) const { const StackTrace* StackTraceStack::next(const StackTrace* p) const {
checkGuard();
assert(p); assert(p);
return static_cast<const Node*>(p)->next; return static_cast<const Node*>(p)->next;
} }
......
...@@ -34,12 +34,15 @@ struct StackTrace { ...@@ -34,12 +34,15 @@ struct StackTrace {
uintptr_t addresses[kMaxFrames]; uintptr_t addresses[kMaxFrames];
}; };
// note: no constructor so this can be __thread.
// A StackTraceStack MUST be placed in zero-initialized memory.
class StackTraceStack { class StackTraceStack {
class Node; class Node;
public: public:
StackTraceStack() = default;
StackTraceStack(const StackTraceStack&) = delete;
void operator=(const StackTraceStack&) = delete;
/** /**
* Push the current stack trace onto the stack. * Push the current stack trace onto the stack.
* Returns false on failure (not enough memory, getting stack trace failed), * Returns false on failure (not enough memory, getting stack trace failed),
...@@ -68,7 +71,7 @@ class StackTraceStack { ...@@ -68,7 +71,7 @@ class StackTraceStack {
/** /**
* Is the stack empty? * Is the stack empty?
*/ */
bool empty() const { return !state_[kTopIdx]; } bool empty() const { return !state_; }
/** /**
* Return the top stack trace, or nullptr if the stack is empty. * Return the top stack trace, or nullptr if the stack is empty.
...@@ -84,13 +87,7 @@ class StackTraceStack { ...@@ -84,13 +87,7 @@ class StackTraceStack {
const StackTrace* next(const StackTrace* p) const; const StackTrace* next(const StackTrace* p) const;
private: private:
static constexpr size_t kTopIdx = kIsDebug ? 1 : 0; Node* state_ = nullptr;
// In debug mode, we assert that we're in zero-initialized memory by
// checking that the two guards around the Node* from top() are zero.
void checkGuard() const { assert(state_[0] == 0 && state_[2] == 0); }
Node* state_[kIsDebug ? 3 : 1];
}; };
} // namespace exception_tracer } // namespace exception_tracer
} // namespace folly } // namespace folly
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