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

Unified Diff: src/ic.cc

Issue 11737033: Slight cleanup/unification of UpdateCache code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments 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 | « no previous file | 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 8b3b4723fe215f6ad68566d6a7c3ed70067c3e14..8c7acc7e29069c36602fa101b31fb9c720a6122f 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -712,7 +712,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// Compute the number of arguments.
int argc = target()->arguments_count();
- bool had_proto_failure = false;
Handle<Code> code;
if (state == UNINITIALIZED) {
// This is the first time we execute this inline cache.
@@ -729,7 +728,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
TryRemoveInvalidPrototypeDependentStub(target(),
*object,
*name)) {
- had_proto_failure = true;
+ state = MONOMORPHIC_PROTOTYPE_FAILURE;
code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
object, name);
} else {
@@ -745,22 +744,36 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
if (code.is_null()) return;
// Patch the call site depending on the state of the cache.
- if (state == UNINITIALIZED ||
- state == PREMONOMORPHIC ||
- state == MONOMORPHIC ||
- state == MONOMORPHIC_PROTOTYPE_FAILURE) {
- set_target(*code);
- } else if (state == MEGAMORPHIC) {
- // Cache code holding map should be consistent with
- // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
- Handle<JSObject> cache_object = object->IsJSObject()
- ? Handle<JSObject>::cast(object)
- : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
- // Update the stub cache.
- isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
- }
-
- if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
+ switch (state) {
+ case UNINITIALIZED:
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
+ case PREMONOMORPHIC:
+ set_target(*code);
+ break;
+ case MONOMORPHIC:
+ if (code->ic_state() != MONOMORPHIC) {
+ Map* map = target()->FindFirstMap();
+ if (map != NULL) {
+ isolate()->stub_cache()->Set(*name, map, target());
+ }
+ }
+ set_target(*code);
+ break;
+ case MEGAMORPHIC: {
+ // Cache code holding map should be consistent with
+ // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
+ Handle<JSObject> cache_object = object->IsJSObject()
+ ? Handle<JSObject>::cast(object)
+ : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
+ // Update the stub cache.
+ isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
+ break;
+ }
+ case DEBUG_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ break;
+ }
+
TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
name, state, target());
}
@@ -1024,25 +1037,34 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
}
// Patch the call site depending on the state of the cache.
- if (state == UNINITIALIZED ||
- state == PREMONOMORPHIC ||
- state == MONOMORPHIC_PROTOTYPE_FAILURE) {
- set_target(*code);
- } else if (state == MONOMORPHIC) {
- // 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);
+ switch (state) {
+ case UNINITIALIZED:
+ case PREMONOMORPHIC:
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
+ set_target(*code);
+ break;
+ case MONOMORPHIC:
+ 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(*megamorphic_stub());
- } else if (state == MEGAMORPHIC) {
- // Cache code holding map should be consistent with
- // GenerateMonomorphicCacheProbe.
- isolate()->stub_cache()->Set(*name, receiver->map(), *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);
+ break;
+ case DEBUG_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ break;
}
TRACE_IC("LoadIC", name, state, target());
@@ -1296,13 +1318,25 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
}
}
- // Patch the call site depending on the state of the cache. Make
- // sure to always rewrite from monomorphic to megamorphic.
- ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
- if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
- set_target(*code);
- } else if (state == MONOMORPHIC) {
- set_target(*megamorphic_stub());
+ // Patch the call site depending on the state of the cache.
+ switch (state) {
+ case UNINITIALIZED:
+ case PREMONOMORPHIC:
+ 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 DEBUG_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ break;
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
+ UNREACHABLE();
+ break;
}
TRACE_IC("KeyedLoadIC", name, state, target());
@@ -1547,18 +1581,35 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
}
// Patch the call site depending on the state of the cache.
- if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
- set_target(*code);
- } else if (state == MONOMORPHIC) {
- // Only move to megamorphic if the target changes.
- if (target() != *code) {
- set_target((strict_mode == kStrictMode)
- ? megamorphic_stub_strict()
- : megamorphic_stub());
- }
- } else if (state == MEGAMORPHIC) {
- // Update the stub cache.
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+ 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_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ break;
}
TRACE_IC("StoreIC", name, state, target());
@@ -1585,18 +1636,28 @@ void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
return result->Add(isolate()->factory()->string_map());
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
- if (stub->ic_state() == MONOMORPHIC) {
- result->Add(Handle<Map>(stub->FindFirstMap()));
- } else {
- ASSERT(stub->ic_state() == MEGAMORPHIC);
- AssertNoAllocation no_allocation;
- int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
- for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- Handle<Object> object(info->target_object());
- ASSERT(object->IsMap());
- AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
+ switch (stub->ic_state()) {
+ case MONOMORPHIC:
+ result->Add(Handle<Map>(stub->FindFirstMap()));
+ break;
+ case MEGAMORPHIC: {
+ AssertNoAllocation no_allocation;
+ int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+ for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
+ RelocInfo* info = it.rinfo();
+ Handle<Object> object(info->target_object());
+ ASSERT(object->IsMap());
+ AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
+ }
+ break;
}
+ case UNINITIALIZED:
+ case PREMONOMORPHIC:
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
+ case DEBUG_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ UNREACHABLE();
+ break;
}
}
}
@@ -2024,15 +2085,27 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
ASSERT(!code.is_null());
- // Patch the call site depending on the state of the cache. Make
- // sure to always rewrite from monomorphic to megamorphic.
- ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
- if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
- set_target(*code);
- } else if (state == MONOMORPHIC) {
- set_target((strict_mode == kStrictMode)
- ? *megamorphic_stub_strict()
- : *megamorphic_stub());
+ // Patch the call site depending on the state of the cache.
+ switch (state) {
+ case UNINITIALIZED:
+ case PREMONOMORPHIC:
+ 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 DEBUG_BREAK:
+ case DEBUG_PREPARE_STEP_IN:
+ break;
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
+ UNREACHABLE();
+ break;
}
TRACE_IC("KeyedStoreIC", name, state, target());
@@ -2057,13 +2130,12 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
extra_ic_state,
args.at<Object>(0),
args.at<String>(1));
- // Result could be a function or a failure.
- JSFunction* raw_function = NULL;
+ JSFunction* raw_function;
if (!maybe_result->To(&raw_function)) return maybe_result;
// The first time the inline cache is updated may be the first time the
- // function it references gets called. If the function is lazily compiled
- // then the first call will trigger a compilation. We check for this case
+ // function it references gets called. If the function is lazily compiled
+ // then the first call will trigger a compilation. We check for this case
// and we do the compilation immediately, instead of waiting for the stub
// currently attached to the JSFunction object to trigger compilation.
if (raw_function->is_compiled()) return raw_function;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698