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

Unified Diff: src/ic.cc

Issue 12051057: Merge UpdateLoadCaches into a single function dispatching on ComputeLoadMonorphic and UpdateMegamor… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 11 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/ic.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index 49b33776cea839863b381ae3b4dbc5c485138c29..65d3f659320948a2ea57a16bdc8630bcc2eafaa0 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -941,7 +941,7 @@ MaybeObject* LoadIC::Load(State state,
// Update inline cache and stub cache.
if (FLAG_use_ic) {
- UpdateLoadCaches(&lookup, state, object, name);
+ UpdateCaches(&lookup, state, object, name);
}
PropertyAttributes attr;
@@ -963,89 +963,29 @@ MaybeObject* LoadIC::Load(State state,
}
-void LoadIC::UpdateLoadCaches(LookupResult* lookup,
- State state,
- Handle<Object> object,
- Handle<String> name) {
+void LoadIC::UpdateCaches(LookupResult* lookup,
+ State state,
+ Handle<Object> object,
+ Handle<String> name) {
// Bail out if the result is not cacheable.
if (!lookup->IsCacheable()) return;
// Loading properties from values is not common, so don't try to
// deal with non-JS objects here.
if (!object->IsJSObject()) return;
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
- // Compute the code stub for this load.
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
Handle<Code> code;
if (state == UNINITIALIZED) {
// This is the first time we execute this inline cache.
// Set the target to the pre monomorphic stub to delay
// setting the monomorphic state.
code = pre_monomorphic_stub();
- } else if (!lookup->IsProperty()) {
- // Nonexistent property. The result is undefined.
- code = isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
} else {
- // Compute monomorphic stub.
- Handle<JSObject> holder(lookup->holder());
- switch (lookup->type()) {
- case FIELD:
- code = isolate()->stub_cache()->ComputeLoadField(
- name, receiver, holder, lookup->GetFieldIndex());
- break;
- case CONSTANT_FUNCTION: {
- Handle<JSFunction> constant(lookup->GetConstantFunction());
- code = isolate()->stub_cache()->ComputeLoadConstant(
- name, receiver, holder, constant);
- break;
- }
- case NORMAL:
- if (holder->IsGlobalObject()) {
- Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
- Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
- code = isolate()->stub_cache()->ComputeLoadGlobal(
- name, receiver, global, cell, lookup->IsDontDelete());
- } else {
- // There is only one shared stub for loading normalized
- // properties. It does not traverse the prototype chain, so the
- // property must be found in the receiver for the stub to be
- // applicable.
- if (!holder.is_identical_to(receiver)) return;
- code = isolate()->stub_cache()->ComputeLoadNormal();
- }
- break;
- case CALLBACKS: {
- Handle<Object> callback(lookup->GetCallbackObject());
- if (callback->IsAccessorInfo()) {
- Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
- if (v8::ToCData<Address>(info->getter()) == 0) return;
- if (!info->IsCompatibleReceiver(*receiver)) return;
- code = isolate()->stub_cache()->ComputeLoadCallback(
- name, receiver, holder, info);
- } else if (callback->IsAccessorPair()) {
- Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
- if (!getter->IsJSFunction()) return;
- if (holder->IsGlobalObject()) return;
- if (!holder->HasFastProperties()) return;
- code = isolate()->stub_cache()->ComputeLoadViaGetter(
- name, receiver, holder, Handle<JSFunction>::cast(getter));
- } else {
- ASSERT(callback->IsForeign());
- // No IC support for old-style native accessors.
- return;
- }
- break;
- }
- case INTERCEPTOR:
- ASSERT(HasInterceptorGetter(*holder));
- code = isolate()->stub_cache()->ComputeLoadInterceptor(
- name, receiver, holder);
- break;
- default:
- return;
- }
+ code = ComputeLoadMonomorphic(lookup, receiver, name);
+ if (code.is_null()) return;
}
// Patch the call site depending on the state of the cache.
@@ -1062,17 +1002,14 @@ void LoadIC::UpdateLoadCaches(LookupResult* lookup,
// the receiver into stub cache.
Map* map = target()->FindFirstMap();
if (map != NULL) {
- isolate()->stub_cache()->Set(*name, map, target());
+ UpdateMegamorphicCache(map, *name, target());
}
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
-
+ UpdateMegamorphicCache(receiver->map(), *name, *code);
set_target(*megamorphic_stub());
}
break;
case MEGAMORPHIC:
- // Cache code holding map should be consistent with
- // GenerateMonomorphicCacheProbe.
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+ UpdateMegamorphicCache(receiver->map(), *name, *code);
break;
case DEBUG_STUB:
break;
@@ -1086,6 +1023,76 @@ void LoadIC::UpdateLoadCaches(LookupResult* lookup,
}
+void LoadIC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
+ // Cache code holding map should be consistent with
+ // GenerateMonomorphicCacheProbe.
+ isolate()->stub_cache()->Set(name, map, code);
+}
+
+
+Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name) {
+ if (!lookup->IsProperty()) {
+ // Nonexistent property. The result is undefined.
+ return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
+ }
+
+ // Compute monomorphic stub.
+ Handle<JSObject> holder(lookup->holder());
+ switch (lookup->type()) {
+ case FIELD:
+ return isolate()->stub_cache()->ComputeLoadField(
+ name, receiver, holder, lookup->GetFieldIndex());
+ case CONSTANT_FUNCTION: {
+ Handle<JSFunction> constant(lookup->GetConstantFunction());
+ return isolate()->stub_cache()->ComputeLoadConstant(
+ name, receiver, holder, constant);
+ }
+ case NORMAL:
+ if (holder->IsGlobalObject()) {
+ Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
+ Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+ return isolate()->stub_cache()->ComputeLoadGlobal(
+ name, receiver, global, cell, lookup->IsDontDelete());
+ }
+ // There is only one shared stub for loading normalized
+ // properties. It does not traverse the prototype chain, so the
+ // property must be found in the receiver for the stub to be
+ // applicable.
+ if (!holder.is_identical_to(receiver)) break;
+ return isolate()->stub_cache()->ComputeLoadNormal();
+ case CALLBACKS: {
+ Handle<Object> callback(lookup->GetCallbackObject());
+ if (callback->IsAccessorInfo()) {
+ Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
+ if (v8::ToCData<Address>(info->getter()) == 0) break;
+ if (!info->IsCompatibleReceiver(*receiver)) break;
+ return isolate()->stub_cache()->ComputeLoadCallback(
+ name, receiver, holder, info);
+ } else if (callback->IsAccessorPair()) {
+ Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
+ if (!getter->IsJSFunction()) break;
+ if (holder->IsGlobalObject()) break;
+ if (!holder->HasFastProperties()) break;
+ return isolate()->stub_cache()->ComputeLoadViaGetter(
+ name, receiver, holder, Handle<JSFunction>::cast(getter));
+ }
+ ASSERT(callback->IsForeign());
+ // No IC support for old-style native accessors.
+ break;
+ }
+ case INTERCEPTOR:
+ ASSERT(HasInterceptorGetter(*holder));
+ return isolate()->stub_cache()->ComputeLoadInterceptor(
+ name, receiver, holder);
+ default:
+ break;
+ }
+ return Handle<Code>::null();
+}
+
+
static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
// This helper implements a few common fast cases for converting
// non-smi keys of keyed loads/stores to a smi or a string.
@@ -1262,87 +1269,43 @@ MaybeObject* KeyedLoadIC::Load(State state,
}
-void KeyedLoadIC::UpdateLoadCaches(LookupResult* lookup,
- State state,
- Handle<Object> object,
- Handle<String> name) {
+Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name) {
// Bail out if we didn't find a result.
- if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
-
- if (!object->IsJSObject()) return;
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
-
- if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
+ if (!lookup->IsProperty()) return Handle<Code>::null();
- // Compute the code stub for this load.
- Handle<Code> code;
-
- if (state == UNINITIALIZED) {
- // This is the first time we execute this inline cache.
- // Set the target to the pre monomorphic stub to delay
- // setting the monomorphic state.
- code = pre_monomorphic_stub();
- } else {
- // Compute a monomorphic stub.
- Handle<JSObject> holder(lookup->holder());
- switch (lookup->type()) {
- case FIELD:
- code = isolate()->stub_cache()->ComputeKeyedLoadField(
- name, receiver, holder, lookup->GetFieldIndex());
- break;
- case CONSTANT_FUNCTION: {
- Handle<JSFunction> constant(lookup->GetConstantFunction());
- code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
- name, receiver, holder, constant);
- break;
- }
- case CALLBACKS: {
- Handle<Object> callback_object(lookup->GetCallbackObject());
- if (!callback_object->IsAccessorInfo()) return;
- Handle<AccessorInfo> callback =
- Handle<AccessorInfo>::cast(callback_object);
- if (v8::ToCData<Address>(callback->getter()) == 0) return;
- if (!callback->IsCompatibleReceiver(*receiver)) return;
- code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
- name, receiver, holder, callback);
- break;
- }
- case INTERCEPTOR:
- ASSERT(HasInterceptorGetter(lookup->holder()));
- code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
- name, receiver, holder);
- break;
- default:
- // Always rewrite to the generic case so that we do not
- // repeatedly try to rewrite.
- code = generic_stub();
- break;
+ // Compute a monomorphic stub.
+ Handle<JSObject> holder(lookup->holder());
+ switch (lookup->type()) {
+ case FIELD:
+ return isolate()->stub_cache()->ComputeKeyedLoadField(
+ name, receiver, holder, lookup->GetFieldIndex());
+ case CONSTANT_FUNCTION: {
+ Handle<JSFunction> constant(lookup->GetConstantFunction());
+ return isolate()->stub_cache()->ComputeKeyedLoadConstant(
+ name, receiver, holder, constant);
}
+ case CALLBACKS: {
+ Handle<Object> callback_object(lookup->GetCallbackObject());
+ if (!callback_object->IsAccessorInfo()) break;
+ Handle<AccessorInfo> callback =
+ Handle<AccessorInfo>::cast(callback_object);
+ if (v8::ToCData<Address>(callback->getter()) == 0) break;
+ if (!callback->IsCompatibleReceiver(*receiver)) break;
+ return isolate()->stub_cache()->ComputeKeyedLoadCallback(
+ name, receiver, holder, callback);
+ }
+ case INTERCEPTOR:
+ ASSERT(HasInterceptorGetter(lookup->holder()));
+ return isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
+ name, receiver, holder);
+ default:
+ // Always rewrite to the generic case so that we do not
+ // repeatedly try to rewrite.
+ return generic_stub();
}
-
- // Patch the call site depending on the state of the cache.
- switch (state) {
- case UNINITIALIZED:
- case PREMONOMORPHIC:
- case POLYMORPHIC:
- set_target(*code);
- break;
- case MONOMORPHIC:
- // Only move to megamorphic if the target changes.
- if (target() != *code) {
- set_target(*megamorphic_stub());
- }
- break;
- case MEGAMORPHIC:
- case GENERIC:
- case DEBUG_STUB:
- break;
- case MONOMORPHIC_PROTOTYPE_FAILURE:
- UNREACHABLE();
- break;
- }
-
- TRACE_IC("KeyedLoadIC", name, state, target());
+ return Handle<Code>::null();
}
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698