Commit 9f8c2116 authored by mbrandy's avatar mbrandy Committed by Commit bot

Additional fixes for external callback logging in profiler.

For platforms that use function descriptors (currently AIX and
PPC64BE), log an external callback's entrypoint address rather than
its function descriptor address.

R=jkummerow@chromium.org, michael_dawson@ca.ibm.com
TEST=cctest/test-cpu-profiler/JsNativeJsSample
BUG=

Review URL: https://codereview.chromium.org/1752173003

Cr-Commit-Position: refs/heads/master@{#34505}
parent 9a1387f6
......@@ -1415,11 +1415,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) {
msg.Append(",%ld", static_cast<int>(timer_.Elapsed().InMicroseconds()));
if (sample->has_external_callback) {
msg.Append(",1,");
#if USES_FUNCTION_DESCRIPTORS
msg.AppendAddress(*FUNCTION_ENTRYPOINT_ADDRESS(sample->external_callback));
#else
msg.AppendAddress(sample->external_callback);
#endif
msg.AppendAddress(sample->external_callback_entry);
} else {
msg.Append(",0,");
msg.AppendAddress(sample->tos);
......@@ -1640,6 +1636,9 @@ void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
Object* callback_obj = call_data->callback();
Address entry_point = v8::ToCData<Address>(callback_obj);
#if USES_FUNCTION_DESCRIPTORS
entry_point = *FUNCTION_ENTRYPOINT_ADDRESS(entry_point);
#endif
PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
}
} else {
......@@ -1683,10 +1682,16 @@ void Logger::LogAccessorCallbacks() {
Address getter_entry = v8::ToCData<Address>(ai->getter());
Name* name = Name::cast(ai->name());
if (getter_entry != 0) {
#if USES_FUNCTION_DESCRIPTORS
getter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(getter_entry);
#endif
PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
}
Address setter_entry = v8::ToCData<Address>(ai->setter());
if (setter_entry != 0) {
#if USES_FUNCTION_DESCRIPTORS
setter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(setter_entry);
#endif
PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
}
}
......
......@@ -608,7 +608,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
// Don't use PC when in external callback code, as it can point
// inside callback's code, and we will erroneously report
// that a callback calls itself.
entries.push_back(code_map_.FindEntry(sample.external_callback));
entries.push_back(code_map_.FindEntry(sample.external_callback_entry));
} else {
CodeEntry* pc_entry = code_map_.FindEntry(sample.pc);
// If there is no pc_entry we're likely in native code.
......
......@@ -683,7 +683,7 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
// we have already entrered JavaScript again and the external callback
// is not the top function.
if (scope && scope->scope_address() < handler) {
external_callback = scope->callback();
external_callback_entry = *scope->callback_entrypoint_address();
has_external_callback = true;
} else {
// sp register may point at an arbitrary place in memory, make
......
......@@ -34,7 +34,7 @@ struct TickSample {
TickSample()
: state(OTHER),
pc(NULL),
external_callback(NULL),
external_callback_entry(NULL),
frames_count(0),
has_external_callback(false),
update_stats(true),
......@@ -49,7 +49,7 @@ struct TickSample {
Address pc; // Instruction pointer.
union {
Address tos; // Top stack value (*sp).
Address external_callback;
Address external_callback_entry;
};
static const unsigned kMaxFramesCountLog2 = 8;
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
......
......@@ -180,7 +180,8 @@ TEST(CFromJSStackTrace) {
// TickSample::Trace
CHECK(sample.has_external_callback);
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace), sample.external_callback);
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace),
sample.external_callback_entry);
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
unsigned base = 0;
......@@ -234,7 +235,8 @@ TEST(PureJSStackTrace) {
//
CHECK(sample.has_external_callback);
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace), sample.external_callback);
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace),
sample.external_callback_entry);
// Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
unsigned base = 0;
......
......@@ -370,10 +370,14 @@ TEST(LogCallbacks) {
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
CHECK(exists);
Address ObjMethod1_entry = reinterpret_cast<Address>(ObjMethod1);
#if USES_FUNCTION_DESCRIPTORS
ObjMethod1_entry = *FUNCTION_ENTRYPOINT_ADDRESS(ObjMethod1_entry);
#endif
i::EmbeddedVector<char, 100> ref_data;
i::SNPrintF(ref_data,
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"",
reinterpret_cast<intptr_t>(ObjMethod1));
reinterpret_cast<intptr_t>(ObjMethod1_entry));
CHECK(StrNStr(log.start(), ref_data.start(), log.length()));
log.Dispose();
......@@ -419,22 +423,34 @@ TEST(LogAccessorCallbacks) {
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
CHECK(exists);
Address Prop1Getter_entry = reinterpret_cast<Address>(Prop1Getter);
#if USES_FUNCTION_DESCRIPTORS
Prop1Getter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(Prop1Getter_entry);
#endif
EmbeddedVector<char, 100> prop1_getter_record;
i::SNPrintF(prop1_getter_record,
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"",
reinterpret_cast<intptr_t>(Prop1Getter));
reinterpret_cast<intptr_t>(Prop1Getter_entry));
CHECK(StrNStr(log.start(), prop1_getter_record.start(), log.length()));
Address Prop1Setter_entry = reinterpret_cast<Address>(Prop1Setter);
#if USES_FUNCTION_DESCRIPTORS
Prop1Setter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(Prop1Setter_entry);
#endif
EmbeddedVector<char, 100> prop1_setter_record;
i::SNPrintF(prop1_setter_record,
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"",
reinterpret_cast<intptr_t>(Prop1Setter));
reinterpret_cast<intptr_t>(Prop1Setter_entry));
CHECK(StrNStr(log.start(), prop1_setter_record.start(), log.length()));
Address Prop2Getter_entry = reinterpret_cast<Address>(Prop2Getter);
#if USES_FUNCTION_DESCRIPTORS
Prop2Getter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(Prop2Getter_entry);
#endif
EmbeddedVector<char, 100> prop2_getter_record;
i::SNPrintF(prop2_getter_record,
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"",
reinterpret_cast<intptr_t>(Prop2Getter));
reinterpret_cast<intptr_t>(Prop2Getter_entry));
CHECK(StrNStr(log.start(), prop2_getter_record.start(), log.length()));
log.Dispose();
}
......
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