Currently, a new isolate is created in an uninitialized state, and
authorjochen@chromium.org <jochen@chromium.org>
Mon, 15 Sep 2014 11:17:00 +0000 (11:17 +0000)
committerjochen@chromium.org <jochen@chromium.org>
Mon, 15 Sep 2014 11:17:00 +0000 (11:17 +0000)
several API methods will automatically initialize it. During this
uninitialized state, code event handlers and function entry handlers can
be attached to the isolate.

This CL deprecates SetFunctionEntryHook and moves the configuration of
those handlers to the Isolate factory method.

This will allow for initializing the Isolate at creation time in the
future.

Users of V8::SetFunctionEntryHook should pass the entry hook to
Isolate::New instead. V8::SetJitCodeEventHandler should either be passed
to Isolate::New as well, or (if startup events are not required) invoked
via the Isolate.

BUG=none
LOG=y
R=svenpanne@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23940 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
src/d8.cc
src/third_party/vtune/DEPS [new file with mode: 0644]
src/third_party/vtune/v8-vtune.h
src/third_party/vtune/vtune-jit.cc
test/cctest/test-api.cc

index 7a2215e..39d01af 100644 (file)
@@ -4243,6 +4243,103 @@ class V8_EXPORT HeapStatistics {
 
 class RetainedObjectInfo;
 
+
+/**
+ * FunctionEntryHook is the type of the profile entry hook called at entry to
+ * any generated function when function-level profiling is enabled.
+ *
+ * \param function the address of the function that's being entered.
+ * \param return_addr_location points to a location on stack where the machine
+ *    return address resides. This can be used to identify the caller of
+ *    \p function, and/or modified to divert execution when \p function exits.
+ *
+ * \note the entry hook must not cause garbage collection.
+ */
+typedef void (*FunctionEntryHook)(uintptr_t function,
+                                  uintptr_t return_addr_location);
+
+/**
+ * A JIT code event is issued each time code is added, moved or removed.
+ *
+ * \note removal events are not currently issued.
+ */
+struct JitCodeEvent {
+  enum EventType {
+    CODE_ADDED,
+    CODE_MOVED,
+    CODE_REMOVED,
+    CODE_ADD_LINE_POS_INFO,
+    CODE_START_LINE_INFO_RECORDING,
+    CODE_END_LINE_INFO_RECORDING
+  };
+  // Definition of the code position type. The "POSITION" type means the place
+  // in the source code which are of interest when making stack traces to
+  // pin-point the source location of a stack frame as close as possible.
+  // The "STATEMENT_POSITION" means the place at the beginning of each
+  // statement, and is used to indicate possible break locations.
+  enum PositionType { POSITION, STATEMENT_POSITION };
+
+  // Type of event.
+  EventType type;
+  // Start of the instructions.
+  void* code_start;
+  // Size of the instructions.
+  size_t code_len;
+  // Script info for CODE_ADDED event.
+  Handle<UnboundScript> script;
+  // User-defined data for *_LINE_INFO_* event. It's used to hold the source
+  // code line information which is returned from the
+  // CODE_START_LINE_INFO_RECORDING event. And it's passed to subsequent
+  // CODE_ADD_LINE_POS_INFO and CODE_END_LINE_INFO_RECORDING events.
+  void* user_data;
+
+  struct name_t {
+    // Name of the object associated with the code, note that the string is not
+    // zero-terminated.
+    const char* str;
+    // Number of chars in str.
+    size_t len;
+  };
+
+  struct line_info_t {
+    // PC offset
+    size_t offset;
+    // Code postion
+    size_t pos;
+    // The position type.
+    PositionType position_type;
+  };
+
+  union {
+    // Only valid for CODE_ADDED.
+    struct name_t name;
+
+    // Only valid for CODE_ADD_LINE_POS_INFO
+    struct line_info_t line_info;
+
+    // New location of instructions. Only valid for CODE_MOVED.
+    void* new_code_start;
+  };
+};
+
+/**
+ * Option flags passed to the SetJitCodeEventHandler function.
+ */
+enum JitCodeEventOptions {
+  kJitCodeEventDefault = 0,
+  // Generate callbacks for already existent code.
+  kJitCodeEventEnumExisting = 1
+};
+
+
+/**
+ * Callback function passed to SetJitCodeEventHandler.
+ *
+ * \param event code add, move or removal event.
+ */
+typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);
+
+
 /**
  * Isolate represents an isolated instance of the V8 engine.  V8
  * isolates have completely separate states.  Objects from one isolate
@@ -4255,6 +4352,29 @@ class RetainedObjectInfo;
 class V8_EXPORT Isolate {
  public:
   /**
+   * Initial configuration parameters for a new Isolate.
+   */
+  struct CreateParams {
+    CreateParams() : entry_hook(NULL), code_event_handler(NULL) {}
+
+    /**
+     * The optional entry_hook allows the host application to provide the
+     * address of a function that's invoked on entry to every V8-generated
+     * function.  Note that entry_hook is invoked at the very start of each
+     * generated function. Furthermore, if an  entry_hook is given, V8 will
+     * always run without a context snapshot.
+     */
+    FunctionEntryHook entry_hook;
+
+    /**
+     * Allows the host application to provide the address of a function that is
+     * notified each time code is added, moved or removed.
+     */
+    JitCodeEventHandler code_event_handler;
+  };
+
+
+  /**
    * Stack-allocated class which sets the isolate for all operations
    * executed within a local scope.
    */
@@ -4362,7 +4482,7 @@ class V8_EXPORT Isolate {
    * When an isolate is no longer used its resources should be freed
    * by calling Dispose().  Using the delete operator is not allowed.
    */
-  static Isolate* New();
+  static Isolate* New(const CreateParams& params = CreateParams());
 
   /**
    * Returns the entered isolate for the current thread or NULL in
@@ -4672,6 +4792,31 @@ class V8_EXPORT Isolate {
    */
   int ContextDisposedNotification();
 
+  /**
+   * Allows the host application to provide the address of a function that is
+   * notified each time code is added, moved or removed.
+   *
+   * \param options options for the JIT code event handler.
+   * \param event_handler the JIT code event handler, which will be invoked
+   *     each time code is added, moved or removed.
+   * \note \p event_handler won't get notified of existent code.
+   * \note since code removal notifications are not currently issued, the
+   *     \p event_handler may get notifications of code that overlaps earlier
+   *     code notifications. This happens when code areas are reused, and the
+   *     earlier overlapping code areas should therefore be discarded.
+   * \note the events passed to \p event_handler and the strings they point to
+   *     are not guaranteed to live past each call. The \p event_handler must
+   *     copy strings and other parameters it needs to keep around.
+   * \note the set of events declared in JitCodeEvent::EventType is expected to
+   *     grow over time, and the JitCodeEvent structure is expected to accrue
+   *     new members. The \p event_handler function must ignore event codes
+   *     it does not recognize to maintain future compatibility.
+   * \note Use Isolate::CreateParams to get events for code executed during
+   *     Isolate setup.
+   */
+  void SetJitCodeEventHandler(JitCodeEventOptions options,
+                              JitCodeEventHandler event_handler);
+
  private:
   template<class K, class V, class Traits> friend class PersistentValueMap;
 
@@ -4751,106 +4896,6 @@ typedef uintptr_t (*ReturnAddressLocationResolver)(
 
 
 /**
- * FunctionEntryHook is the type of the profile entry hook called at entry to
- * any generated function when function-level profiling is enabled.
- *
- * \param function the address of the function that's being entered.
- * \param return_addr_location points to a location on stack where the machine
- *    return address resides. This can be used to identify the caller of
- *    \p function, and/or modified to divert execution when \p function exits.
- *
- * \note the entry hook must not cause garbage collection.
- */
-typedef void (*FunctionEntryHook)(uintptr_t function,
-                                  uintptr_t return_addr_location);
-
-
-/**
- * A JIT code event is issued each time code is added, moved or removed.
- *
- * \note removal events are not currently issued.
- */
-struct JitCodeEvent {
-  enum EventType {
-    CODE_ADDED,
-    CODE_MOVED,
-    CODE_REMOVED,
-    CODE_ADD_LINE_POS_INFO,
-    CODE_START_LINE_INFO_RECORDING,
-    CODE_END_LINE_INFO_RECORDING
-  };
-  // Definition of the code position type. The "POSITION" type means the place
-  // in the source code which are of interest when making stack traces to
-  // pin-point the source location of a stack frame as close as possible.
-  // The "STATEMENT_POSITION" means the place at the beginning of each
-  // statement, and is used to indicate possible break locations.
-  enum PositionType {
-    POSITION,
-    STATEMENT_POSITION
-  };
-
-  // Type of event.
-  EventType type;
-  // Start of the instructions.
-  void* code_start;
-  // Size of the instructions.
-  size_t code_len;
-  // Script info for CODE_ADDED event.
-  Handle<UnboundScript> script;
-  // User-defined data for *_LINE_INFO_* event. It's used to hold the source
-  // code line information which is returned from the
-  // CODE_START_LINE_INFO_RECORDING event. And it's passed to subsequent
-  // CODE_ADD_LINE_POS_INFO and CODE_END_LINE_INFO_RECORDING events.
-  void* user_data;
-
-  struct name_t {
-    // Name of the object associated with the code, note that the string is not
-    // zero-terminated.
-    const char* str;
-    // Number of chars in str.
-    size_t len;
-  };
-
-  struct line_info_t {
-    // PC offset
-    size_t offset;
-    // Code postion
-    size_t pos;
-    // The position type.
-    PositionType position_type;
-  };
-
-  union {
-    // Only valid for CODE_ADDED.
-    struct name_t name;
-
-    // Only valid for CODE_ADD_LINE_POS_INFO
-    struct line_info_t line_info;
-
-    // New location of instructions. Only valid for CODE_MOVED.
-    void* new_code_start;
-  };
-};
-
-/**
- * Option flags passed to the SetJitCodeEventHandler function.
- */
-enum JitCodeEventOptions {
-  kJitCodeEventDefault = 0,
-  // Generate callbacks for already existent code.
-  kJitCodeEventEnumExisting = 1
-};
-
-
-/**
- * Callback function passed to SetJitCodeEventHandler.
- *
- * \param event code add, move or removal event.
- */
-typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);
-
-
-/**
  * Interface for iterating through all external resources in the heap.
  */
 class V8_EXPORT ExternalResourceVisitor {  // NOLINT
@@ -5069,6 +5114,8 @@ class V8_EXPORT V8 {
    * \returns true on success on supported platforms, false on failure.
    * \note Setting an entry hook can only be done very early in an isolates
    *   lifetime, and once set, the entry hook cannot be revoked.
+   *
+   * Deprecated, will be removed. Use Isolate::New(entry_hook) instead.
    */
   static bool SetFunctionEntryHook(Isolate* isolate,
                                    FunctionEntryHook entry_hook);
@@ -5092,6 +5139,9 @@ class V8_EXPORT V8 {
    *     grow over time, and the JitCodeEvent structure is expected to accrue
    *     new members. The \p event_handler function must ignore event codes
    *     it does not recognize to maintain future compatibility.
+   *
+   * Deprecated, will be removed. Use Isolate::SetJitCodeEventHandler or
+   * Isolate::CreateParams instead.
    */
   static void SetJitCodeEventHandler(JitCodeEventOptions options,
                                      JitCodeEventHandler event_handler);
index e4a0065..94b00ef 100644 (file)
@@ -6662,8 +6662,16 @@ Isolate* Isolate::GetCurrent() {
 }
 
 
-Isolate* Isolate::New() {
+Isolate* Isolate::New(const Isolate::CreateParams& params) {
   i::Isolate* isolate = new i::Isolate();
+  if (params.entry_hook) {
+    isolate->set_function_entry_hook(params.entry_hook);
+  }
+  if (params.code_event_handler) {
+    isolate->InitializeLoggingAndCounters();
+    isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
+                                           params.code_event_handler);
+  }
   return reinterpret_cast<Isolate*>(isolate);
 }
 
@@ -6872,6 +6880,15 @@ int v8::Isolate::ContextDisposedNotification() {
 }
 
 
+void v8::Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
+                                         JitCodeEventHandler event_handler) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  // Ensure that logging is initialized for our isolate.
+  isolate->InitializeLoggingAndCounters();
+  isolate->logger()->SetCodeEventHandler(options, event_handler);
+}
+
+
 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
     : str_(NULL), length_(0) {
   i::Isolate* isolate = i::Isolate::Current();
index 819db82..f22be5b 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1612,7 +1612,16 @@ int Shell::Main(int argc, char* argv[]) {
     v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
   }
   int result = 0;
-  Isolate* isolate = Isolate::New();
+  Isolate::CreateParams create_params;
+#if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
+  if (i::FLAG_gdbjit) {
+    create_params.code_event_handler = i::GDBJITInterface::EventHandler;
+  }
+#endif
+#ifdef ENABLE_VTUNE_JIT_INTERFACE
+  vTune::InitializeVtuneForV8(create_params);
+#endif
+  Isolate* isolate = Isolate::New(create_params);
 #ifndef V8_SHARED
   v8::ResourceConstraints constraints;
   constraints.ConfigureDefaults(base::SysInfo::AmountOfPhysicalMemory(),
@@ -1624,15 +1633,6 @@ int Shell::Main(int argc, char* argv[]) {
   {
     Isolate::Scope scope(isolate);
     Initialize(isolate);
-#if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
-    if (i::FLAG_gdbjit) {
-      v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
-                                     i::GDBJITInterface::EventHandler);
-    }
-#endif
-#ifdef ENABLE_VTUNE_JIT_INTERFACE
-    vTune::InitializeVtuneForV8();
-#endif
     PerIsolateData data(isolate);
     InitializeDebugger(isolate);
 
diff --git a/src/third_party/vtune/DEPS b/src/third_party/vtune/DEPS
new file mode 100644 (file)
index 0000000..adbe86e
--- /dev/null
@@ -0,0 +1,3 @@
+include_rules = [
+  "+../../../include",
+]
index c60b303..a7e5116 100644 (file)
 #ifndef V8_VTUNE_H_
 #define V8_VTUNE_H_
 
+#include "../../../include/v8.h"
+
 namespace vTune {
 
-void InitializeVtuneForV8();
+void InitializeVtuneForV8(v8::Isolate::CreateParams& params);
 
 }  // namespace vTune
 
index d62dcfb..e489d6e 100644 (file)
@@ -271,13 +271,10 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
 
 }  // namespace internal
 
-void InitializeVtuneForV8() {
-  if (v8::V8::Initialize()) {
-    v8::V8::SetFlagsFromString("--nocompact_code_space",
-                              (int)strlen("--nocompact_code_space"));
-    v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
-        vTune::internal::VTUNEJITInterface::event_handler);
-  }
+void InitializeVtuneForV8(v8::Isolate::CreateParams& params) {
+  v8::V8::SetFlagsFromString("--nocompact_code_space",
+                             (int)strlen("--nocompact_code_space"));
+  params.code_event_handler = vTune::internal::VTUNEJITInterface::event_handler;
 }
 
 }  // namespace vTune
index 0c65e67..d7f1520 100644 (file)
@@ -14171,19 +14171,14 @@ void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) {
 
 void SetFunctionEntryHookTest::RunTest() {
   // Work in a new isolate throughout.
-  v8::Isolate* isolate = v8::Isolate::New();
-
-  // Test setting the entry hook on the new isolate.
-  CHECK(v8::V8::SetFunctionEntryHook(isolate, EntryHook));
-
-  // Replacing the hook, once set should fail.
-  CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook));
+  v8::Isolate::CreateParams create_params;
+  create_params.entry_hook = EntryHook;
+  create_params.code_event_handler = JitEvent;
+  v8::Isolate* isolate = v8::Isolate::New(create_params);
 
   {
     v8::Isolate::Scope scope(isolate);
 
-    v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, JitEvent);
-
     RunLoopInNewEnv(isolate);
 
     // Check the exepected invocation counts.
@@ -14211,9 +14206,6 @@ void SetFunctionEntryHookTest::RunTest() {
     // We should record no invocations in this isolate.
     CHECK_EQ(0, static_cast<int>(invocations_.size()));
   }
-  // Since the isolate has been used, we shouldn't be able to set an entry
-  // hook anymore.
-  CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook));
 
   isolate->Dispose();
 }
@@ -14407,7 +14399,7 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
     saw_bar = 0;
     move_events = 0;
 
-    V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, event_handler);
+    isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, event_handler);
 
     // Generate new code objects sparsely distributed across several
     // different fragmented code-space pages.
@@ -14431,7 +14423,7 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
     // Force code movement.
     heap->CollectAllAvailableGarbage("TestSetJitCodeEventHandler");
 
-    V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+    isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
 
     CHECK_LE(kIterations, saw_bar);
     CHECK_LT(0, move_events);
@@ -14461,8 +14453,9 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
     i::HashMap lineinfo(MatchPointers);
     jitcode_line_info = &lineinfo;
 
-    V8::SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting, event_handler);
-    V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+    isolate->SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting,
+                                    event_handler);
+    isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
 
     jitcode_line_info = NULL;
     // We expect that we got some events. Note that if we could get code removal