Commit c112fdc3 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Adds a new API where the host can supply a callback function. The callback...

Adds a new API where the host can supply a callback function. The callback function can resolve the location of a return address on stack to the location where a return-address rewriting profiler stashed the original return address.

Review URL: https://chromiumcodereview.appspot.com/9401019
Patch from Sigurður Ásgeirsson <siggi@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9b55ebaa
...@@ -2857,6 +2857,20 @@ class V8EXPORT StartupDataDecompressor { // NOLINT ...@@ -2857,6 +2857,20 @@ class V8EXPORT StartupDataDecompressor { // NOLINT
typedef bool (*EntropySource)(unsigned char* buffer, size_t length); typedef bool (*EntropySource)(unsigned char* buffer, size_t length);
/**
* ReturnAddressLocationResolver is used as a callback function when v8 is
* resolving the location of a return address on the stack. Profilers that
* change the return address on the stack can use this to resolve the stack
* location to whereever the profiler stashed the original return address.
* When invoked, return_addr_location will point to a location on stack where
* a machine return address resides, this function should return either the
* same pointer, or a pointer to the profiler's copy of the original return
* address.
*/
typedef uintptr_t (*ReturnAddressLocationResolver)(
uintptr_t return_addr_location);
/** /**
* Interface for iterating though all external resources in the heap. * Interface for iterating though all external resources in the heap.
*/ */
...@@ -3110,6 +3124,13 @@ class V8EXPORT V8 { ...@@ -3110,6 +3124,13 @@ class V8EXPORT V8 {
*/ */
static void SetEntropySource(EntropySource source); static void SetEntropySource(EntropySource source);
/**
* Allows the host application to provide a callback that allows v8 to
* cooperate with a profiler that rewrites return addresses on stack.
*/
static void SetReturnAddressLocationResolver(
ReturnAddressLocationResolver return_address_resolver);
/** /**
* Adjusts the amount of registered external memory. Used to give * Adjusts the amount of registered external memory. Used to give
* V8 an indication of the amount of externally allocated memory * V8 an indication of the amount of externally allocated memory
......
...@@ -4026,6 +4026,12 @@ void v8::V8::SetEntropySource(EntropySource source) { ...@@ -4026,6 +4026,12 @@ void v8::V8::SetEntropySource(EntropySource source) {
} }
void v8::V8::SetReturnAddressLocationResolver(
ReturnAddressLocationResolver return_address_resolver) {
i::V8::SetReturnAddressLocationResolver(return_address_resolver);
}
bool v8::V8::Dispose() { bool v8::V8::Dispose() {
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(), if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
......
...@@ -41,6 +41,22 @@ ...@@ -41,6 +41,22 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
static ReturnAddressLocationResolver return_address_location_resolver = NULL;
// Resolves pc_address through the resolution address function if one is set.
static inline Address* ResolveReturnAddressLocation(Address* pc_address) {
if (return_address_location_resolver == NULL) {
return pc_address;
} else {
return reinterpret_cast<Address*>(
return_address_location_resolver(
reinterpret_cast<uintptr_t>(pc_address)));
}
}
// Iterator that supports traversing the stack handlers of a // Iterator that supports traversing the stack handlers of a
// particular frame. Needs to know the top of the handler chain. // particular frame. Needs to know the top of the handler chain.
class StackHandlerIterator BASE_EMBEDDED { class StackHandlerIterator BASE_EMBEDDED {
...@@ -155,8 +171,8 @@ void StackFrameIterator::Reset() { ...@@ -155,8 +171,8 @@ void StackFrameIterator::Reset() {
ASSERT(fp_ != NULL); ASSERT(fp_ != NULL);
state.fp = fp_; state.fp = fp_;
state.sp = sp_; state.sp = sp_;
state.pc_address = state.pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
type = StackFrame::ComputeType(isolate(), &state); type = StackFrame::ComputeType(isolate(), &state);
} }
if (SingletonFor(type) == NULL) return; if (SingletonFor(type) == NULL) return;
...@@ -414,6 +430,13 @@ void StackFrame::IteratePc(ObjectVisitor* v, ...@@ -414,6 +430,13 @@ void StackFrame::IteratePc(ObjectVisitor* v,
} }
void StackFrame::SetReturnAddressLocationResolver(
ReturnAddressLocationResolver resolver) {
ASSERT(return_address_location_resolver == NULL);
return_address_location_resolver = resolver;
}
StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
ASSERT(state->fp != NULL); ASSERT(state->fp != NULL);
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
...@@ -488,8 +511,8 @@ void ExitFrame::ComputeCallerState(State* state) const { ...@@ -488,8 +511,8 @@ void ExitFrame::ComputeCallerState(State* state) const {
// Set up the caller state. // Set up the caller state.
state->sp = caller_sp(); state->sp = caller_sp();
state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
state->pc_address state->pc_address = ResolveReturnAddressLocation(
= reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
} }
...@@ -523,7 +546,8 @@ StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { ...@@ -523,7 +546,8 @@ StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
void ExitFrame::FillState(Address fp, Address sp, State* state) { void ExitFrame::FillState(Address fp, Address sp, State* state) {
state->sp = sp; state->sp = sp;
state->fp = fp; state->fp = fp;
state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(sp - 1 * kPointerSize));
} }
...@@ -558,7 +582,8 @@ int StandardFrame::ComputeExpressionsCount() const { ...@@ -558,7 +582,8 @@ int StandardFrame::ComputeExpressionsCount() const {
void StandardFrame::ComputeCallerState(State* state) const { void StandardFrame::ComputeCallerState(State* state) const {
state->sp = caller_sp(); state->sp = caller_sp();
state->fp = caller_fp(); state->fp = caller_fp();
state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp())); state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(ComputePCAddress(fp())));
} }
......
...@@ -241,6 +241,11 @@ class StackFrame BASE_EMBEDDED { ...@@ -241,6 +241,11 @@ class StackFrame BASE_EMBEDDED {
virtual void Iterate(ObjectVisitor* v) const = 0; virtual void Iterate(ObjectVisitor* v) const = 0;
static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
// Sets a callback function for return-address rewriting profilers
// to resolve the location of a return address to the location of the
// profiler's stashed return address.
static void SetReturnAddressLocationResolver(
ReturnAddressLocationResolver resolver);
// Printing support. // Printing support.
enum PrintMode { OVERVIEW, DETAILS }; enum PrintMode { OVERVIEW, DETAILS };
......
...@@ -146,6 +146,12 @@ void V8::SetEntropySource(EntropySource source) { ...@@ -146,6 +146,12 @@ void V8::SetEntropySource(EntropySource source) {
} }
void V8::SetReturnAddressLocationResolver(
ReturnAddressLocationResolver resolver) {
StackFrame::SetReturnAddressLocationResolver(resolver);
}
// Used by JavaScript APIs // Used by JavaScript APIs
uint32_t V8::Random(Context* context) { uint32_t V8::Random(Context* context) {
ASSERT(context->IsGlobalContext()); ASSERT(context->IsGlobalContext());
......
...@@ -95,6 +95,9 @@ class V8 : public AllStatic { ...@@ -95,6 +95,9 @@ class V8 : public AllStatic {
// Allows an entropy source to be provided for use in random number // Allows an entropy source to be provided for use in random number
// generation. // generation.
static void SetEntropySource(EntropySource source); static void SetEntropySource(EntropySource source);
// Support for return-address rewriting profilers.
static void SetReturnAddressLocationResolver(
ReturnAddressLocationResolver resolver);
// Random number generation support. Not cryptographically safe. // Random number generation support. Not cryptographically safe.
static uint32_t Random(Context* context); static uint32_t Random(Context* context);
// We use random numbers internally in memory allocation and in the // We use random numbers internally in memory allocation and in the
......
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