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

Unified Diff: src/ic.cc

Issue 12057003: Merge UpdateStoreCaches into a single function dispatching on ComputeStoreMonorphic and UpdateMegam… (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 65d3f659320948a2ea57a16bdc8630bcc2eafaa0..30117c9f7aa0c0ae090eca63566c957f81b16f67 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -963,39 +963,20 @@ MaybeObject* LoadIC::Load(State state,
}
-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;
-
- if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
-
- 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 {
- code = ComputeLoadMonomorphic(lookup, receiver, name);
- if (code.is_null()) return;
- }
-
- // Patch the call site depending on the state of the cache.
+void IC::PatchCache(State state,
+ StrictModeFlag strict_mode,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Code> code) {
switch (state) {
case UNINITIALIZED:
case PREMONOMORPHIC:
case MONOMORPHIC_PROTOTYPE_FAILURE:
+ case POLYMORPHIC:
set_target(*code);
break;
case MONOMORPHIC:
+ // Only move to megamorphic if the target changes.
if (target() != *code) {
// We are transitioning from monomorphic to megamorphic case.
// Place the current monomorphic stub and stub compiled for
@@ -1005,25 +986,53 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
UpdateMegamorphicCache(map, *name, target());
}
UpdateMegamorphicCache(receiver->map(), *name, *code);
- set_target(*megamorphic_stub());
+ set_target((strict_mode == kStrictMode)
+ ? *megamorphic_stub_strict()
+ : *megamorphic_stub());
}
break;
case MEGAMORPHIC:
+ // Update the stub cache.
UpdateMegamorphicCache(receiver->map(), *name, *code);
break;
- case DEBUG_STUB:
- break;
- case POLYMORPHIC:
case GENERIC:
- UNREACHABLE();
+ case DEBUG_STUB:
break;
}
+}
+
+
+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;
+
+ if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
+
+ 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 {
+ code = ComputeLoadMonomorphic(lookup, receiver, name);
+ if (code.is_null()) return;
+ }
+ PatchCache(state, kNonStrictMode, receiver, name, code);
TRACE_IC("LoadIC", name, state, target());
}
-void LoadIC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
+void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
// Cache code holding map should be consistent with
// GenerateMonomorphicCacheProbe.
isolate()->stub_cache()->Set(name, map, code);
@@ -1424,7 +1433,7 @@ MaybeObject* StoreIC::Store(State state,
LookupResult lookup(isolate());
if (LookupForWrite(receiver, name, &lookup)) {
if (FLAG_use_ic) {
- UpdateStoreCaches(&lookup, state, strict_mode, receiver, name, value);
+ UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
}
} else if (strict_mode == kStrictMode &&
!(lookup.IsProperty() && lookup.IsReadOnly()) &&
@@ -1438,12 +1447,12 @@ MaybeObject* StoreIC::Store(State state,
}
-void StoreIC::UpdateStoreCaches(LookupResult* lookup,
- State state,
- StrictModeFlag strict_mode,
- Handle<JSObject> receiver,
- Handle<String> name,
- Handle<Object> value) {
+void StoreIC::UpdateCaches(LookupResult* lookup,
+ State state,
+ StrictModeFlag strict_mode,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
ASSERT(StoreICableLookup(lookup));
ASSERT(lookup->IsFound());
@@ -1451,22 +1460,25 @@ void StoreIC::UpdateStoreCaches(LookupResult* lookup,
// These are not cacheable, so we never see such LookupResults here.
ASSERT(!lookup->IsHandler());
- // If the property has a non-field type allowing map transitions
- // where there is extra room in the object, we leave the IC in its
- // current state.
- PropertyType type = lookup->type();
+ Handle<Code> code =
+ ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
+ if (code.is_null()) return;
- // Compute the code stub for this store; used for rewriting to
- // monomorphic state and making sure that the code stub is in the
- // stub cache.
+ PatchCache(state, strict_mode, receiver, name, code);
+ TRACE_IC("StoreIC", name, state, target());
+}
+
+
+Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
+ StrictModeFlag strict_mode,
+ Handle<JSObject> receiver,
+ Handle<String> name) {
Handle<JSObject> holder(lookup->holder());
- Handle<Code> code;
- switch (type) {
+ switch (lookup->type()) {
case FIELD:
- code = isolate()->stub_cache()->ComputeStoreField(
+ return isolate()->stub_cache()->ComputeStoreField(
name, receiver, lookup->GetFieldIndex().field_index(),
Handle<Map>::null(), strict_mode);
- break;
case NORMAL:
if (receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
@@ -1474,44 +1486,39 @@ void StoreIC::UpdateStoreCaches(LookupResult* lookup,
// global object.
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
- code = isolate()->stub_cache()->ComputeStoreGlobal(
+ return isolate()->stub_cache()->ComputeStoreGlobal(
name, global, cell, strict_mode);
- } else {
- if (!holder.is_identical_to(receiver)) return;
- code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
}
- break;
+ if (!holder.is_identical_to(receiver)) break;
+ return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject());
if (callback->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
- if (v8::ToCData<Address>(info->setter()) == 0) return;
- if (!holder->HasFastProperties()) return;
- if (!info->IsCompatibleReceiver(*receiver)) return;
- code = isolate()->stub_cache()->ComputeStoreCallback(
+ if (v8::ToCData<Address>(info->setter()) == 0) break;
+ if (!holder->HasFastProperties()) break;
+ if (!info->IsCompatibleReceiver(*receiver)) break;
+ return isolate()->stub_cache()->ComputeStoreCallback(
name, receiver, holder, info, strict_mode);
} else if (callback->IsAccessorPair()) {
Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
- if (!setter->IsJSFunction()) return;
- if (holder->IsGlobalObject()) return;
- if (!holder->HasFastProperties()) return;
- code = isolate()->stub_cache()->ComputeStoreViaSetter(
+ if (!setter->IsJSFunction()) break;
+ if (holder->IsGlobalObject()) break;
+ if (!holder->HasFastProperties()) break;
+ return isolate()->stub_cache()->ComputeStoreViaSetter(
name, receiver, holder, Handle<JSFunction>::cast(setter),
strict_mode);
- } else {
- ASSERT(callback->IsForeign());
- // No IC support for old-style native accessors.
- return;
}
+ ASSERT(callback->IsForeign());
+ // No IC support for old-style native accessors.
break;
}
case INTERCEPTOR:
ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
- code = isolate()->stub_cache()->ComputeStoreInterceptor(
+ return isolate()->stub_cache()->ComputeStoreInterceptor(
name, receiver, strict_mode);
- break;
case CONSTANT_FUNCTION:
- return;
+ break;
case TRANSITION: {
Handle<Map> transition(lookup->GetTransitionTarget());
int descriptor = transition->LastAdded();
@@ -1519,56 +1526,18 @@ void StoreIC::UpdateStoreCaches(LookupResult* lookup,
DescriptorArray* target_descriptors = transition->instance_descriptors();
PropertyDetails details = target_descriptors->GetDetails(descriptor);
- if (details.type() != FIELD || details.attributes() != NONE) return;
+ if (details.type() != FIELD || details.attributes() != NONE) break;
int field_index = target_descriptors->GetFieldIndex(descriptor);
- code = isolate()->stub_cache()->ComputeStoreField(
+ return isolate()->stub_cache()->ComputeStoreField(
name, receiver, field_index, transition, strict_mode);
-
- break;
}
case NONEXISTENT:
case HANDLER:
UNREACHABLE();
- return;
- }
-
- // Patch the call site depending on the state of the cache.
- switch (state) {
- case UNINITIALIZED:
- case PREMONOMORPHIC:
- case MONOMORPHIC_PROTOTYPE_FAILURE:
- set_target(*code);
- break;
- case MONOMORPHIC:
- // Only move to megamorphic if the target changes.
- if (target() != *code) {
- // We are transitioning from monomorphic to megamorphic case.
- // Place the current monomorphic stub and stub compiled for
- // the receiver into stub cache.
- Map* map = target()->FindFirstMap();
- if (map != NULL) {
- isolate()->stub_cache()->Set(*name, map, target());
- }
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
- set_target((strict_mode == kStrictMode)
- ? *megamorphic_stub_strict()
- : *megamorphic_stub());
- }
- break;
- case MEGAMORPHIC:
- // Update the stub cache.
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
- break;
- case DEBUG_STUB:
- break;
- case POLYMORPHIC:
- case GENERIC:
- UNREACHABLE();
break;
}
-
- TRACE_IC("StoreIC", name, state, target());
+ return Handle<Code>::null();
}
@@ -1804,35 +1773,18 @@ MaybeObject* KeyedStoreIC::Store(State state,
}
-void KeyedStoreIC::UpdateStoreCaches(LookupResult* lookup,
- State state,
- StrictModeFlag strict_mode,
- Handle<JSObject> receiver,
- Handle<String> name,
- Handle<Object> value) {
- ASSERT(!receiver->IsJSGlobalProxy());
- ASSERT(StoreICableLookup(lookup));
- ASSERT(lookup->IsFound());
-
- // These are not cacheable, so we never see such LookupResults here.
- ASSERT(!lookup->IsHandler());
-
+Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
+ StrictModeFlag strict_mode,
+ Handle<JSObject> receiver,
+ Handle<String> name) {
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
// current state.
- PropertyType type = lookup->type();
-
- // Compute the code stub for this store; used for rewriting to
- // monomorphic state and making sure that the code stub is in the
- // stub cache.
- Handle<Code> code;
-
- switch (type) {
+ switch (lookup->type()) {
case FIELD:
- code = isolate()->stub_cache()->ComputeKeyedStoreField(
+ return isolate()->stub_cache()->ComputeKeyedStoreField(
name, receiver, lookup->GetFieldIndex().field_index(),
Handle<Map>::null(), strict_mode);
- break;
case TRANSITION: {
Handle<Map> transition(lookup->GetTransitionTarget());
int descriptor = transition->LastAdded();
@@ -1842,9 +1794,8 @@ void KeyedStoreIC::UpdateStoreCaches(LookupResult* lookup,
if (details.type() == FIELD && details.attributes() == NONE) {
int field_index = target_descriptors->GetFieldIndex(descriptor);
- code = isolate()->stub_cache()->ComputeKeyedStoreField(
+ return isolate()->stub_cache()->ComputeKeyedStoreField(
name, receiver, field_index, transition, strict_mode);
- break;
}
// fall through.
}
@@ -1854,43 +1805,15 @@ void KeyedStoreIC::UpdateStoreCaches(LookupResult* lookup,
case INTERCEPTOR:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
- code = (strict_mode == kStrictMode)
+ return (strict_mode == kStrictMode)
? generic_stub_strict()
: generic_stub();
- break;
case HANDLER:
case NONEXISTENT:
UNREACHABLE();
- return;
- }
-
- ASSERT(!code.is_null());
-
- // 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((strict_mode == kStrictMode)
- ? *megamorphic_stub_strict()
- : *megamorphic_stub());
- }
- break;
- case MEGAMORPHIC:
- case GENERIC:
- case DEBUG_STUB:
- break;
- case MONOMORPHIC_PROTOTYPE_FAILURE:
- UNREACHABLE();
break;
}
-
- TRACE_IC("KeyedStoreIC", 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