Store API callback entry address prior to entering a callback.

Callback entry address is stored in VMState and is later retrieved by
profiler stack sampler. This makes possible relating API entry to JS
stack, and this is simpler than trying to unwind native stack.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3344 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c2f12a72
......@@ -380,6 +380,9 @@ BUILTIN(HandleApiCall) {
{
// Leaving JavaScript.
VMState state(EXTERNAL);
#ifdef ENABLE_LOGGING_AND_PROFILING
state.set_external_callback(v8::ToCData<Address>(callback_obj));
#endif
value = callback(new_args);
}
if (value.IsEmpty()) {
......@@ -446,6 +449,9 @@ static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call,
{
// Leaving JavaScript.
VMState state(EXTERNAL);
#ifdef ENABLE_LOGGING_AND_PROFILING
state.set_external_callback(v8::ToCData<Address>(callback_obj));
#endif
value = callback(new_args);
}
if (value.IsEmpty()) {
......
......@@ -55,7 +55,7 @@ inline const char* StateToString(StateTag state) {
}
}
VMState::VMState(StateTag state) : disabled_(true) {
VMState::VMState(StateTag state) : disabled_(true), external_callback_(NULL) {
if (!Logger::is_logging()) {
return;
}
......
......@@ -155,12 +155,18 @@ void StackTracer::Trace(TickSample* sample) {
return;
}
int i = 0;
const Address callback = Logger::current_state_ != NULL ?
Logger::current_state_->external_callback() : NULL;
if (callback != NULL) {
sample->stack[i++] = callback;
}
SafeStackTraceFrameIterator it(
reinterpret_cast<Address>(sample->fp),
reinterpret_cast<Address>(sample->sp),
reinterpret_cast<Address>(sample->sp),
js_entry_sp);
int i = 0;
while (!it.done() && i < TickSample::kMaxFramesCount) {
sample->stack[i++] = it.frame()->pc();
it.Advance();
......@@ -683,7 +689,7 @@ void Logger::CallbackEvent(String* name, Address entry_point) {
msg.AppendAddress(entry_point);
SmartPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append(",0,\"%s\"", *str);
msg.Append(",1,\"%s\"", *str);
if (FLAG_compress_log) {
ASSERT(compression_helper_ != NULL);
if (!compression_helper_->HandleMessage(&msg)) return;
......
......@@ -91,15 +91,20 @@ class CompressionHelper;
class VMState BASE_EMBEDDED {
#ifdef ENABLE_LOGGING_AND_PROFILING
public:
inline explicit VMState(StateTag state);
inline VMState(StateTag state);
inline ~VMState();
StateTag state() { return state_; }
Address external_callback() { return external_callback_; }
void set_external_callback(Address external_callback) {
external_callback_ = external_callback;
}
private:
bool disabled_;
StateTag state_;
VMState* previous_;
Address external_callback_;
#else
public:
explicit VMState(StateTag state) {}
......@@ -333,6 +338,7 @@ class Logger {
friend class TimeLog;
friend class Profiler;
friend class SlidingStateWindow;
friend class StackTracer;
friend class VMState;
friend class LoggerTestHelper;
......
......@@ -524,7 +524,7 @@ TEST(LogCallbacks) {
pos += strlen(callback_rec);
EmbeddedVector<char, 100> ref_data;
i::OS::SNPrintF(ref_data,
"0x%" V8PRIxPTR ",0,\"method1\"", ObjMethod1);
"0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1);
*(pos + strlen(ref_data.start())) = '\0';
CHECK_EQ(ref_data.start(), pos);
......
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