Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1294)

Unified Diff: src/stub-cache.cc

Issue 140069: Store a lookup result when compiling interceptor ICs.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/stub-cache.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/stub-cache.cc
===================================================================
--- src/stub-cache.cc (revision 2562)
+++ src/stub-cache.cc (working copy)
@@ -787,23 +787,25 @@
return *value;
}
-
-Object* LoadInterceptorProperty(Arguments args) {
+/**
+ * Attempts to load a property with an interceptor (which must be present),
+ * but doesn't search the prototype chain.
+ *
+ * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
+ * provide any value for the given name.
+ */
+Object* LoadPropertyWithInterceptorOnly(Arguments args) {
Handle<JSObject> receiver_handle = args.at<JSObject>(0);
Handle<JSObject> holder_handle = args.at<JSObject>(1);
Handle<String> name_handle = args.at<String>(2);
- Smi* lookup_hint = Smi::cast(args[3]);
- Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(4);
- Handle<Object> data_handle = args.at<Object>(5);
+ Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(3);
+ Handle<Object> data_handle = args.at<Object>(4);
Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
v8::NamedPropertyGetter getter =
FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
ASSERT(getter != NULL);
- PropertyAttributes attributes = ABSENT;
- Object* result = Heap::undefined_value();
-
{
// Use the interceptor getter.
v8::AccessorInfo info(v8::Utils::ToLocal(receiver_handle),
@@ -822,68 +824,95 @@
}
}
- int property_index = lookup_hint->value();
- if (property_index >= 0) {
- result = holder_handle->FastPropertyAt(property_index);
- } else {
- switch (property_index) {
- case JSObject::kLookupInPrototype: {
- Object* pt = holder_handle->GetPrototype();
- if (pt == Heap::null_value()) return Heap::undefined_value();
- result = pt->GetPropertyWithReceiver(
- *receiver_handle,
- *name_handle,
- &attributes);
- RETURN_IF_SCHEDULED_EXCEPTION();
- }
- break;
+ return Heap::no_interceptor_result_sentinel();
+}
- case JSObject::kLookupInHolder:
- result = holder_handle->GetPropertyPostInterceptor(
- *receiver_handle,
- *name_handle,
- &attributes);
- RETURN_IF_SCHEDULED_EXCEPTION();
- break;
- default:
- UNREACHABLE();
- }
- }
-
- if (result->IsFailure()) return result;
- if (attributes != ABSENT) return result;
-
- // If the top frame is an internal frame, this is really a 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.
- StackFrameIterator it;
- it.Advance(); // skip exit frame
- if (it.frame()->is_internal()) return result;
-
+static Object* ThrowReferenceError(String* name) {
// If the load is non-contextual, just return the undefined result.
// Note that both keyed and non-keyed loads may end up here, so we
// can't use either LoadIC or KeyedLoadIC constructors.
IC ic(IC::NO_EXTRA_FRAME);
ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
- if (!ic.is_contextual()) return result;
+ if (!ic.is_contextual()) return Heap::undefined_value();
// Throw a reference error.
+ HandleScope scope;
+ Handle<String> name_handle(name);
+ Handle<Object> error =
+ Factory::NewReferenceError("not_defined",
+ HandleVector(&name_handle, 1));
+ return Top::Throw(*error);
+}
+
+
+static Object* LoadWithInterceptor(Arguments* args,
+ PropertyAttributes* attrs) {
+ Handle<JSObject> receiver_handle = args->at<JSObject>(0);
+ Handle<JSObject> holder_handle = args->at<JSObject>(1);
+ Handle<String> name_handle = args->at<String>(2);
+ Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(3);
+ Handle<Object> data_handle = args->at<Object>(4);
+
+ Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
+ v8::NamedPropertyGetter getter =
+ FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
+ ASSERT(getter != NULL);
+
{
+ // Use the interceptor getter.
+ v8::AccessorInfo info(v8::Utils::ToLocal(receiver_handle),
+ v8::Utils::ToLocal(data_handle),
+ v8::Utils::ToLocal(holder_handle));
HandleScope scope;
- // We cannot use the raw name pointer here since getting the
- // property might cause a GC. However, we can get the name from
- // the stack using the arguments object.
- Handle<String> name_handle = args.at<String>(2);
- Handle<Object> error =
- Factory::NewReferenceError("not_defined",
- HandleVector(&name_handle, 1));
- return Top::Throw(*error);
+ v8::Handle<v8::Value> r;
+ {
+ // Leaving JavaScript.
+ VMState state(EXTERNAL);
+ r = getter(v8::Utils::ToLocal(name_handle), info);
+ }
+ RETURN_IF_SCHEDULED_EXCEPTION();
+ if (!r.IsEmpty()) {
+ *attrs = NONE;
+ return *v8::Utils::OpenHandle(*r);
+ }
}
+
+ Object* result = holder_handle->GetPropertyPostInterceptor(
+ *receiver_handle,
+ *name_handle,
+ attrs);
+ RETURN_IF_SCHEDULED_EXCEPTION();
+ return result;
}
+/**
+ * Loads a property with an interceptor performing post interceptor
+ * lookup if interceptor failed.
+ */
+Object* LoadPropertyWithInterceptorForLoad(Arguments args) {
+ PropertyAttributes attr = NONE;
+ Object* result = LoadWithInterceptor(&args, &attr);
+ if (result->IsFailure()) return result;
+
+ // If the property is present, return it.
+ if (attr != ABSENT) return result;
+ return ThrowReferenceError(String::cast(args[2]));
+}
+
+
+Object* LoadPropertyWithInterceptorForCall(Arguments args) {
+ PropertyAttributes attr;
+ Object* result = LoadWithInterceptor(&args, &attr);
+ RETURN_IF_SCHEDULED_EXCEPTION();
+ // 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.
+ return result;
+}
+
+
Object* StoreInterceptorProperty(Arguments args) {
JSObject* recv = JSObject::cast(args[0]);
String* name = String::cast(args[1]);
« no previous file with comments | « src/stub-cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698