Revision: 10845
Author: [email protected]
Date: Mon Feb 27 07:15:53 2012
Log: 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 <[email protected]>.
http://code.google.com/p/v8/source/detail?r=10845
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/frames.cc
/branches/bleeding_edge/src/frames.h
/branches/bleeding_edge/src/v8.cc
/branches/bleeding_edge/src/v8.h
=======================================
--- /branches/bleeding_edge/include/v8.h Fri Feb 24 06:34:01 2012
+++ /branches/bleeding_edge/include/v8.h Mon Feb 27 07:15:53 2012
@@ -2857,6 +2857,20 @@
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.
*/
@@ -3110,6 +3124,13 @@
*/
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
* V8 an indication of the amount of externally allocated memory
=======================================
--- /branches/bleeding_edge/src/api.cc Thu Feb 23 03:43:07 2012
+++ /branches/bleeding_edge/src/api.cc Mon Feb 27 07:15:53 2012
@@ -4024,6 +4024,12 @@
void v8::V8::SetEntropySource(EntropySource source) {
i::V8::SetEntropySource(source);
}
+
+
+void v8::V8::SetReturnAddressLocationResolver(
+ ReturnAddressLocationResolver return_address_resolver) {
+ i::V8::SetReturnAddressLocationResolver(return_address_resolver);
+}
bool v8::V8::Dispose() {
=======================================
--- /branches/bleeding_edge/src/frames.cc Thu Feb 9 01:43:37 2012
+++ /branches/bleeding_edge/src/frames.cc Mon Feb 27 07:15:53 2012
@@ -41,6 +41,22 @@
namespace v8 {
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
// particular frame. Needs to know the top of the handler chain.
class StackHandlerIterator BASE_EMBEDDED {
@@ -155,8 +171,8 @@
ASSERT(fp_ != NULL);
state.fp = fp_;
state.sp = sp_;
- state.pc_address =
- reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_));
+ state.pc_address = ResolveReturnAddressLocation(
+ reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
type = StackFrame::ComputeType(isolate(), &state);
}
if (SingletonFor(type) == NULL) return;
@@ -412,6 +428,13 @@
*pc_address = pc;
}
}
+
+
+void StackFrame::SetReturnAddressLocationResolver(
+ ReturnAddressLocationResolver resolver) {
+ ASSERT(return_address_location_resolver == NULL);
+ return_address_location_resolver = resolver;
+}
StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
@@ -488,8 +511,8 @@
// Set up the caller state.
state->sp = caller_sp();
state->fp = Memory::Address_at(fp() +
ExitFrameConstants::kCallerFPOffset);
- state->pc_address
- = reinterpret_cast<Address*>(fp() +
ExitFrameConstants::kCallerPCOffset);
+ state->pc_address = ResolveReturnAddressLocation(
+ reinterpret_cast<Address*>(fp() +
ExitFrameConstants::kCallerPCOffset));
}
@@ -523,7 +546,8 @@
void ExitFrame::FillState(Address fp, Address sp, State* state) {
state->sp = sp;
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 @@
void StandardFrame::ComputeCallerState(State* state) const {
state->sp = caller_sp();
state->fp = caller_fp();
- state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp()));
+ state->pc_address = ResolveReturnAddressLocation(
+ reinterpret_cast<Address*>(ComputePCAddress(fp())));
}
=======================================
--- /branches/bleeding_edge/src/frames.h Thu Feb 9 01:43:37 2012
+++ /branches/bleeding_edge/src/frames.h Mon Feb 27 07:15:53 2012
@@ -241,6 +241,11 @@
virtual void Iterate(ObjectVisitor* v) const = 0;
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.
enum PrintMode { OVERVIEW, DETAILS };
=======================================
--- /branches/bleeding_edge/src/v8.cc Wed Feb 8 01:55:25 2012
+++ /branches/bleeding_edge/src/v8.cc Mon Feb 27 07:15:53 2012
@@ -144,6 +144,12 @@
void V8::SetEntropySource(EntropySource source) {
entropy_source = source;
}
+
+
+void V8::SetReturnAddressLocationResolver(
+ ReturnAddressLocationResolver resolver) {
+ StackFrame::SetReturnAddressLocationResolver(resolver);
+}
// Used by JavaScript APIs
=======================================
--- /branches/bleeding_edge/src/v8.h Fri Jan 13 05:09:52 2012
+++ /branches/bleeding_edge/src/v8.h Mon Feb 27 07:15:53 2012
@@ -95,6 +95,9 @@
// Allows an entropy source to be provided for use in random number
// generation.
static void SetEntropySource(EntropySource source);
+ // Support for return-address rewriting profilers.
+ static void SetReturnAddressLocationResolver(
+ ReturnAddressLocationResolver resolver);
// Random number generation support. Not cryptographically safe.
static uint32_t Random(Context* context);
// We use random numbers internally in memory allocation and in the
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev