Pass Isolate to Local<T>::New()
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 5 Dec 2012 09:13:53 +0000 (09:13 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 5 Dec 2012 09:13:53 +0000 (09:13 +0000)
Our profiling revealed that Local<T>::New() is one of bottlenecks of DOM bindings.

BUG=
TEST=cctest/test-api/LocalHandle

Review URL: https://codereview.chromium.org/11316331
Patch from Kentaro Hara <haraken@chromium.org>.

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

include/v8.h
src/api.cc
test/cctest/test-api.cc

index e93555e..c569078 100644 (file)
@@ -308,11 +308,13 @@ template <class T> class Local : public Handle<T> {
     return Local<S>::Cast(*this);
   }
 
-  /** Create a local handle for the content of another handle.
-   *  The referee is kept alive by the local handle even when
-   *  the original handle is destroyed/disposed.
+  /**
+   * Create a local handle for the content of another handle.
+   * The referee is kept alive by the local handle even when
+   * the original handle is destroyed/disposed.
    */
   V8_INLINE(static Local<T> New(Handle<T> that));
+  V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that));
 };
 
 
@@ -494,6 +496,8 @@ class V8EXPORT HandleScope {
    * Creates a new handle with the given value.
    */
   static internal::Object** CreateHandle(internal::Object* value);
+  static internal::Object** CreateHandle(internal::Isolate* isolate,
+                                         internal::Object* value);
   // Faster version, uses HeapObject to obtain the current Isolate.
   static internal::Object** CreateHandle(internal::HeapObject* value);
 
@@ -4285,6 +4289,16 @@ Local<T> Local<T>::New(Handle<T> that) {
 
 
 template <class T>
+  Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
+  if (that.IsEmpty()) return Local<T>();
+  T* that_ptr = *that;
+  internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
+  return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
+      reinterpret_cast<internal::Isolate*>(isolate), *p)));
+}
+
+
+template <class T>
 Persistent<T> Persistent<T>::New(Handle<T> that) {
   if (that.IsEmpty()) return Persistent<T>();
   internal::Object** p = reinterpret_cast<internal::Object**>(*that);
index 688b5ce..e19f372 100644 (file)
@@ -769,6 +769,12 @@ i::Object** HandleScope::CreateHandle(i::Object* value) {
 }
 
 
+i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
+  ASSERT(isolate == i::Isolate::Current());
+  return i::HandleScope::CreateHandle(value, isolate);
+}
+
+
 i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
   ASSERT(value->IsHeapObject());
   return reinterpret_cast<i::Object**>(
index 1610dcd..b7180d5 100644 (file)
@@ -2360,6 +2360,16 @@ THREADED_TEST(GlobalHandle) {
 }
 
 
+THREADED_TEST(LocalHandle) {
+  v8::HandleScope scope;
+  v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
+  CHECK_EQ(local->Length(), 3);
+
+  local = v8::Local<String>::New(v8::Isolate::GetCurrent(), v8_str("str"));
+  CHECK_EQ(local->Length(), 3);
+}
+
+
 class WeakCallCounter {
  public:
   explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { }