Revision: 5941
Author: [email protected]
Date: Tue Dec 7 16:19:20 2010
Log: [Isolates] Cleanup of codepaths slowing down Dromaeo in browser.
This is Dromaeo Core numbers, v8 bleeding_edge, isolates and isolates +
this patch: http://dromaeo.com/?id=122292,122309,123122
There is more to do in api.cc, especially around things like v8::Null()
that pull Isolate multiple times while they don't need to. However, that is
more involved change, for another patch.
Review URL: http://codereview.chromium.org/5107003
http://code.google.com/p/v8/source/detail?r=5941
Modified:
/branches/experimental/isolates/include/v8.h
/branches/experimental/isolates/src/api.cc
/branches/experimental/isolates/src/builtins.cc
/branches/experimental/isolates/src/isolate.h
/branches/experimental/isolates/src/objects.cc
/branches/experimental/isolates/src/stub-cache.cc
=======================================
--- /branches/experimental/isolates/include/v8.h Tue Nov 9 14:15:38 2010
+++ /branches/experimental/isolates/include/v8.h Tue Dec 7 16:19:20 2010
@@ -110,6 +110,7 @@
class Arguments;
class Object;
class Heap;
+class HeapObject;
class Isolate;
}
@@ -437,6 +438,8 @@
* Creates a new handle with the given value.
*/
static internal::Object** CreateHandle(internal::Object* value);
+ // Faster version, uses HeapObject to obtain the current Isolate.
+ static internal::Object** CreateHandle(internal::HeapObject* value);
private:
// Make it impossible to create heap-allocated or illegal handle
@@ -3483,6 +3486,15 @@
uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset -
kHeapObjectTag;
return *reinterpret_cast<T*>(addr);
}
+
+ static inline bool CanCastToHeapObject(void*) { return false; }
+ static inline bool CanCastToHeapObject(Context*) { return true; }
+ static inline bool CanCastToHeapObject(String*) { return true; }
+ static inline bool CanCastToHeapObject(Object*) { return true; }
+ static inline bool CanCastToHeapObject(Message*) { return true; }
+ static inline bool CanCastToHeapObject(StackTrace*) { return true; }
+ static inline bool CanCastToHeapObject(StackFrame*) { return true; }
+
};
} // namespace internal
@@ -3499,7 +3511,12 @@
template <class T>
Local<T> Local<T>::New(Handle<T> that) {
if (that.IsEmpty()) return Local<T>();
- internal::Object** p = reinterpret_cast<internal::Object**>(*that);
+ T* that_ptr = *that;
+ internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
+ if (internal::Internals::CanCastToHeapObject(that_ptr)) {
+ return Local<T>(reinterpret_cast<T*>(
+
HandleScope::CreateHandle(reinterpret_cast<internal::HeapObject*>(*p))));
+ }
return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p)));
}
=======================================
--- /branches/experimental/isolates/src/api.cc Tue Nov 16 09:37:01 2010
+++ /branches/experimental/isolates/src/api.cc Tue Dec 7 16:19:20 2010
@@ -268,8 +268,8 @@
}
-static inline bool EnsureInitialized(const char* location) {
- i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
+ const char* location) {
if (isolate != NULL) {
if (isolate->IsDefaultIsolate()) {
if (i::V8::IsRunning()) {
@@ -287,6 +287,10 @@
return ApiCheck(InitializeHelper(), location, "Error initializing V8");
}
+static inline bool EnsureInitialized(const char* location) {
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ return EnsureInitializedForIsolate(isolate, location);
+}
#ifdef DEBUG
void ImplementationUtilities::ZapHandleRange(i::Object** begin,
@@ -303,8 +307,11 @@
v8::Handle<v8::Primitive> ImplementationUtilities::Null() {
- if (!EnsureInitialized("v8::Null()")) return v8::Handle<v8::Primitive>();
- return v8::Handle<Primitive>(ToApi<Primitive>(FACTORY->null_value()));
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ if (!EnsureInitializedForIsolate(isolate, "v8::Null()"))
+ return v8::Handle<v8::Primitive>();
+ return v8::Handle<Primitive>(
+ ToApi<Primitive>(isolate->factory()->null_value()));
}
@@ -512,9 +519,16 @@
}
-i::Object** v8::HandleScope::CreateHandle(i::Object* value) {
+i::Object** HandleScope::CreateHandle(i::Object* value) {
return i::HandleScope::CreateHandle(value, i::Isolate::Current());
}
+
+
+i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
+ ASSERT(value->IsHeapObject());
+ return reinterpret_cast<i::Object**>(
+ i::HandleScope::CreateHandle(value, value->GetIsolate()));
+}
void Context::Enter() {
@@ -3857,12 +3871,14 @@
Local<Integer> v8::Integer::New(int32_t value) {
- EnsureInitialized("v8::Integer::New()");
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
if (i::Smi::IsValid(value)) {
- return
Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value)));
+ return
Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
+ isolate));
}
ENTER_V8;
- i::Handle<i::Object> result = FACTORY->NewNumber(value);
+ i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
=======================================
--- /branches/experimental/isolates/src/builtins.cc Tue Nov 16 09:37:01 2010
+++ /branches/experimental/isolates/src/builtins.cc Tue Dec 7 16:19:20 2010
@@ -1063,7 +1063,7 @@
result = *reinterpret_cast<Object**>(*value);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!is_construct || result->IsJSObject()) return result;
}
@@ -1126,7 +1126,7 @@
args_length - 1,
is_construct);
- HandleScope scope;
+ HandleScope scope(isolate);
Object* result;
v8::Handle<v8::Value> value;
{
@@ -1146,7 +1146,7 @@
result = *reinterpret_cast<Object**>(*value);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
@@ -1212,7 +1212,7 @@
}
}
// Check for exceptions and return result.
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
=======================================
--- /branches/experimental/isolates/src/isolate.h Tue Nov 16 09:37:01 2010
+++ /branches/experimental/isolates/src/isolate.h Tue Dec 7 16:19:20 2010
@@ -106,10 +106,9 @@
// of handles to the actual constants.
typedef ZoneList<Handle<Object> > ZoneObjectList;
-// TODO(isolates): pass isolate pointer here.
-#define RETURN_IF_SCHEDULED_EXCEPTION() \
- if (Isolate::Current()->has_scheduled_exception()) \
- return Isolate::Current()->PromoteScheduledException()
+#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
+ if (isolate->has_scheduled_exception()) \
+ return isolate->PromoteScheduledException()
#define ISOLATE_ADDRESS_LIST(C) \
C(handler_address) \
=======================================
--- /branches/experimental/isolates/src/objects.cc Tue Nov 16 09:37:01 2010
+++ /branches/experimental/isolates/src/objects.cc Tue Dec 7 16:19:20 2010
@@ -160,6 +160,7 @@
Object* structure,
String* name,
Object* holder) {
+ Isolate* isolate = name->GetIsolate();
// To accommodate both the old and the new api we switch on the
// data structure used to store the callbacks. Eventually proxy
// callbacks should be phased out.
@@ -167,11 +168,9 @@
AccessorDescriptor* callback =
reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
MaybeObject* value = (callback->getter)(receiver, callback->data);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return value;
}
-
- Isolate* isolate = name->GetIsolate();
// api style callbacks.
if (structure->IsAccessorInfo()) {
@@ -191,7 +190,7 @@
VMState state(isolate, EXTERNAL);
result = call_fun(v8::Utils::ToLocal(key), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) {
return isolate->heap()->undefined_value();
}
@@ -1607,14 +1606,14 @@
v8::Utils::ToLocal(value_unhole),
info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) return *value_handle;
}
MaybeObject* raw_result =
this_handle->SetPropertyPostInterceptor(*name_handle,
*value_handle,
attributes);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
}
@@ -1647,7 +1646,7 @@
AccessorDescriptor* callback =
reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
MaybeObject* obj = (callback->setter)(this, value, callback->data);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (obj->IsFailure()) return obj;
return *value_handle;
}
@@ -1669,7 +1668,7 @@
v8::Utils::ToLocal(value_handle),
info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *value_handle;
}
@@ -2510,7 +2509,7 @@
VMState state(isolate, EXTERNAL);
result = deleter(v8::Utils::ToLocal(name_handle), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
return *v8::Utils::OpenHandle(*result);
@@ -2518,7 +2517,7 @@
}
MaybeObject* raw_result =
this_handle->DeletePropertyPostInterceptor(*name_handle,
NORMAL_DELETION);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
}
@@ -2578,14 +2577,14 @@
VMState state(isolate, EXTERNAL);
result = deleter(index, info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
return *v8::Utils::OpenHandle(*result);
}
MaybeObject* raw_result =
this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
}
@@ -6528,12 +6527,12 @@
VMState state(isolate, EXTERNAL);
result = setter(index, v8::Utils::ToLocal(value_handle), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) return *value_handle;
}
MaybeObject* raw_result =
this_handle->SetElementWithoutInterceptor(index, *value_handle);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
}
@@ -6564,7 +6563,7 @@
VMState state(isolate, EXTERNAL);
result = call_fun(v8::Utils::ToLocal(key), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) return isolate->heap()->undefined_value();
return *v8::Utils::OpenHandle(*result);
}
@@ -6620,7 +6619,7 @@
v8::Utils::ToLocal(value_handle),
info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *value_handle;
}
@@ -6958,13 +6957,13 @@
VMState state(isolate, EXTERNAL);
result = getter(index, info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
}
MaybeObject* raw_result =
holder_handle->GetElementPostInterceptor(*this_handle, index);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
}
@@ -7279,7 +7278,7 @@
VMState state(isolate, EXTERNAL);
result = getter(v8::Utils::ToLocal(name_handle), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) {
*attributes = NONE;
return *v8::Utils::OpenHandle(*result);
@@ -7290,7 +7289,7 @@
*receiver_handle,
*name_handle,
attributes);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
=======================================
--- /branches/experimental/isolates/src/stub-cache.cc Tue Nov 16 09:37:01
2010
+++ /branches/experimental/isolates/src/stub-cache.cc Tue Dec 7 16:19:20
2010
@@ -961,7 +961,7 @@
#endif
result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) return HEAP->undefined_value();
return *v8::Utils::OpenHandle(*result);
}
@@ -988,7 +988,7 @@
#endif
fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *value;
}
@@ -1021,20 +1021,20 @@
// Use the interceptor getter.
v8::AccessorInfo info(args.arguments() -
kAccessorInfoOffsetInInterceptorArgs);
- HandleScope scope;
+ HandleScope scope(isolate);
v8::Handle<v8::Value> r;
{
// Leaving JavaScript.
VMState state(isolate, EXTERNAL);
r = getter(v8::Utils::ToLocal(name_handle), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
return *v8::Utils::OpenHandle(*r);
}
}
- return HEAP->no_interceptor_result_sentinel();
+ return isolate->heap()->no_interceptor_result_sentinel();
}
@@ -1083,7 +1083,7 @@
VMState state(isolate, EXTERNAL);
r = getter(v8::Utils::ToLocal(name_handle), info);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
*attrs = NONE;
return *v8::Utils::OpenHandle(*r);
@@ -1094,7 +1094,7 @@
*receiver_handle,
*name_handle,
attrs);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
@@ -1121,7 +1121,7 @@
RUNTIME_GET_ISOLATE;
PropertyAttributes attr;
MaybeObject* result = LoadWithInterceptor(&args, &attr);
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
// This is call IC. In this case, we simply return the undefined result
which
// will lead to an exception when trying to invoke the result as a
// function.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev