Author: [email protected]
Date: Fri Mar 6 05:07:57 2009
New Revision: 1440
Modified:
branches/bleeding_edge/src/log.cc
branches/bleeding_edge/src/log.h
branches/bleeding_edge/src/platform.h
branches/bleeding_edge/test/cctest/test-log-ia32.cc
Log:
Get rid or heap allocation in stack sampler to avoid deadlocks.
Review URL: http://codereview.chromium.org/40219
Modified: branches/bleeding_edge/src/log.cc
==============================================================================
--- branches/bleeding_edge/src/log.cc (original)
+++ branches/bleeding_edge/src/log.cc Fri Mar 6 05:07:57 2009
@@ -138,39 +138,31 @@
//
void StackTracer::Trace(TickSample* sample) {
if (sample->state == GC) {
- sample->InitStack(0);
+ sample->frames_count = 0;
return;
}
// If c_entry_fp is available, this means that we are inside a C++
- // function and sample->fp value isn't reliable due to FPO
+ // function and sample->fp value isn't reliable due to FPO.
if (Top::c_entry_fp(Top::GetCurrentThread()) != NULL) {
SafeStackTraceFrameIterator it(
reinterpret_cast<Address>(sample->sp),
reinterpret_cast<Address>(low_stack_bound_));
- // Pass 1: Calculate depth
- int depth = 0;
- while (!it.done() && depth <= kMaxStackFrames) {
- ++depth;
+ int i = 0;
+ while (!it.done() && i < TickSample::kMaxFramesCount) {
+ sample->stack[i++] = it.frame()->pc();
it.Advance();
}
- // Pass 2: Save stack
- sample->InitStack(depth);
- if (depth > 0) {
- it.Reset();
- for (int i = 0; i < depth && !it.done(); ++i, it.Advance()) {
- sample->stack[i] = it.frame()->pc();
- }
- }
+ sample->frames_count = i;
} else if (sample->sp < sample->fp && sample->fp < low_stack_bound_) {
- // The check assumes that stack grows from lower addresses
- sample->InitStack(1);
+ // The check assumes that stack grows from lower addresses.
sample->stack[0] = Memory::Address_at(
(Address)(sample->fp + StandardFrameConstants::kCallerPCOffset));
+ sample->frames_count = 1;
} else {
// FP seems to be in some intermediate state,
// better discard this sample
- sample->InitStack(0);
+ sample->frames_count = 0;
}
}
@@ -945,10 +937,8 @@
if (overflow) {
msg.Append(",overflow");
}
- if (*(sample->stack)) {
- for (size_t i = 0; sample->stack[i]; ++i) {
- msg.Append(",0x%x", reinterpret_cast<unsigned
int>(sample->stack[i]));
- }
+ for (int i = 0; i < sample->frames_count; ++i) {
+ msg.Append(",%p", sample->stack[i]);
}
msg.Append('\n');
msg.WriteToLogFile();
Modified: branches/bleeding_edge/src/log.h
==============================================================================
--- branches/bleeding_edge/src/log.h (original)
+++ branches/bleeding_edge/src/log.h Fri Mar 6 05:07:57 2009
@@ -277,8 +277,6 @@
: low_stack_bound_(low_stack_bound) { }
void Trace(TickSample* sample);
private:
- // Maximum number of stack frames to capture
- static const int kMaxStackFrames = 5;
unsigned int low_stack_bound_;
};
Modified: branches/bleeding_edge/src/platform.h
==============================================================================
--- branches/bleeding_edge/src/platform.h (original)
+++ branches/bleeding_edge/src/platform.h Fri Mar 6 05:07:57 2009
@@ -466,26 +466,9 @@
unsigned int sp; // Stack pointer.
unsigned int fp; // Frame pointer.
StateTag state; // The state of the VM.
- SmartPointer<Address> stack; // Call stack, null-terminated.
-
- inline TickSample& operator=(const TickSample& rhs) {
- if (this == &rhs) return *this;
- pc = rhs.pc;
- sp = rhs.sp;
- fp = rhs.fp;
- state = rhs.state;
- DeleteArray(stack.Detach());
- stack = rhs.stack;
- return *this;
- }
-
- inline void InitStack(int depth) {
- if (depth) {
- stack = SmartPointer<Address>(NewArray<Address>(depth + 1));
- // null-terminate
- stack[depth] = 0;
- }
- }
+ static const int kMaxFramesCount = 5;
+ EmbeddedVector<Address, kMaxFramesCount> stack; // Call stack.
+ int frames_count; // Number of captured frames.
};
class Sampler {
Modified: branches/bleeding_edge/test/cctest/test-log-ia32.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-log-ia32.cc (original)
+++ branches/bleeding_edge/test/cctest/test-log-ia32.cc Fri Mar 6 05:07:57
2009
@@ -94,9 +94,9 @@
#ifdef DEBUG
// C stack trace works only in debug mode, in release mode EBP is
// usually treated as a general-purpose register
+ CHECK_GT(sample.frames_count, 0);
CheckRetAddrIsInCFunction(reinterpret_cast<unsigned
int>(sample.stack[0]),
reinterpret_cast<unsigned int>(&CFunc));
- CHECK_EQ(0, sample.stack[1]);
#endif
}
@@ -217,7 +217,7 @@
" JSFuncDoTrace();"
"};\n"
"JSTrace();");
- CHECK_NE(0, *(sample.stack));
+ CHECK_GT(sample.frames_count, 1);
CheckRetAddrIsInFunction(
reinterpret_cast<unsigned int>(sample.stack[0]),
reinterpret_cast<unsigned int>(call_trace_code->instruction_start()),
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---