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

Reply via email to