Commit 400b8b8c authored by verwaest@chromium.org's avatar verwaest@chromium.org

Slight cleanup of UpdateCache code.

Review URL: https://chromiumcodereview.appspot.com/11737033

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13328 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent eb9a22cc
...@@ -712,7 +712,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup, ...@@ -712,7 +712,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// Compute the number of arguments. // Compute the number of arguments.
int argc = target()->arguments_count(); int argc = target()->arguments_count();
bool had_proto_failure = false;
Handle<Code> code; Handle<Code> code;
if (state == UNINITIALIZED) { if (state == UNINITIALIZED) {
// This is the first time we execute this inline cache. // This is the first time we execute this inline cache.
...@@ -729,7 +728,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup, ...@@ -729,7 +728,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
TryRemoveInvalidPrototypeDependentStub(target(), TryRemoveInvalidPrototypeDependentStub(target(),
*object, *object,
*name)) { *name)) {
had_proto_failure = true; state = MONOMORPHIC_PROTOTYPE_FAILURE;
code = ComputeMonomorphicStub(lookup, state, extra_ic_state, code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
object, name); object, name);
} else { } else {
...@@ -745,12 +744,22 @@ void CallICBase::UpdateCaches(LookupResult* lookup, ...@@ -745,12 +744,22 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
if (code.is_null()) return; if (code.is_null()) return;
// Patch the call site depending on the state of the cache. // Patch the call site depending on the state of the cache.
if (state == UNINITIALIZED || switch (state) {
state == PREMONOMORPHIC || case UNINITIALIZED:
state == MONOMORPHIC || case MONOMORPHIC_PROTOTYPE_FAILURE:
state == 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); set_target(*code);
} else if (state == MEGAMORPHIC) { break;
case MEGAMORPHIC: {
// Cache code holding map should be consistent with // Cache code holding map should be consistent with
// GenerateMonomorphicCacheProbe. It is not the map which holds the stub. // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
Handle<JSObject> cache_object = object->IsJSObject() Handle<JSObject> cache_object = object->IsJSObject()
...@@ -758,9 +767,13 @@ void CallICBase::UpdateCaches(LookupResult* lookup, ...@@ -758,9 +767,13 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
: Handle<JSObject>(JSObject::cast(object->GetPrototype())); : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
// Update the stub cache. // Update the stub cache.
isolate()->stub_cache()->Set(*name, cache_object->map(), *code); isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
break;
}
case DEBUG_BREAK:
case DEBUG_PREPARE_STEP_IN:
break;
} }
if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
name, state, target()); name, state, target());
} }
...@@ -1024,11 +1037,14 @@ void LoadIC::UpdateCaches(LookupResult* lookup, ...@@ -1024,11 +1037,14 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
} }
// Patch the call site depending on the state of the cache. // Patch the call site depending on the state of the cache.
if (state == UNINITIALIZED || switch (state) {
state == PREMONOMORPHIC || case UNINITIALIZED:
state == MONOMORPHIC_PROTOTYPE_FAILURE) { case PREMONOMORPHIC:
case MONOMORPHIC_PROTOTYPE_FAILURE:
set_target(*code); set_target(*code);
} else if (state == MONOMORPHIC) { break;
case MONOMORPHIC:
if (target() != *code) {
// We are transitioning from monomorphic to megamorphic case. // We are transitioning from monomorphic to megamorphic case.
// Place the current monomorphic stub and stub compiled for // Place the current monomorphic stub and stub compiled for
// the receiver into stub cache. // the receiver into stub cache.
...@@ -1039,10 +1055,16 @@ void LoadIC::UpdateCaches(LookupResult* lookup, ...@@ -1039,10 +1055,16 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
isolate()->stub_cache()->Set(*name, receiver->map(), *code); isolate()->stub_cache()->Set(*name, receiver->map(), *code);
set_target(*megamorphic_stub()); set_target(*megamorphic_stub());
} else if (state == MEGAMORPHIC) { }
break;
case MEGAMORPHIC:
// Cache code holding map should be consistent with // Cache code holding map should be consistent with
// GenerateMonomorphicCacheProbe. // GenerateMonomorphicCacheProbe.
isolate()->stub_cache()->Set(*name, receiver->map(), *code); isolate()->stub_cache()->Set(*name, receiver->map(), *code);
break;
case DEBUG_BREAK:
case DEBUG_PREPARE_STEP_IN:
break;
} }
TRACE_IC("LoadIC", name, state, target()); TRACE_IC("LoadIC", name, state, target());
...@@ -1296,14 +1318,26 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup, ...@@ -1296,14 +1318,26 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
} }
} }
// Patch the call site depending on the state of the cache. Make // Patch the call site depending on the state of the cache.
// sure to always rewrite from monomorphic to megamorphic. switch (state) {
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); case UNINITIALIZED:
if (state == UNINITIALIZED || state == PREMONOMORPHIC) { case PREMONOMORPHIC:
set_target(*code); set_target(*code);
} else if (state == MONOMORPHIC) { break;
case MONOMORPHIC:
// Only move to megamorphic if the target changes.
if (target() != *code) {
set_target(*megamorphic_stub()); 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()); TRACE_IC("KeyedLoadIC", name, state, target());
} }
...@@ -1547,18 +1581,35 @@ void StoreIC::UpdateCaches(LookupResult* lookup, ...@@ -1547,18 +1581,35 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
} }
// Patch the call site depending on the state of the cache. // Patch the call site depending on the state of the cache.
if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { switch (state) {
case UNINITIALIZED:
case PREMONOMORPHIC:
case MONOMORPHIC_PROTOTYPE_FAILURE:
set_target(*code); set_target(*code);
} else if (state == MONOMORPHIC) { break;
case MONOMORPHIC:
// Only move to megamorphic if the target changes. // Only move to megamorphic if the target changes.
if (target() != *code) { 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) set_target((strict_mode == kStrictMode)
? megamorphic_stub_strict() ? megamorphic_stub_strict()
: megamorphic_stub()); : megamorphic_stub());
} }
} else if (state == MEGAMORPHIC) { break;
case MEGAMORPHIC:
// Update the stub cache. // Update the stub cache.
isolate()->stub_cache()->Set(*name, receiver->map(), *code); isolate()->stub_cache()->Set(*name, receiver->map(), *code);
break;
case DEBUG_BREAK:
case DEBUG_PREPARE_STEP_IN:
break;
} }
TRACE_IC("StoreIC", name, state, target()); TRACE_IC("StoreIC", name, state, target());
...@@ -1585,10 +1636,11 @@ void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, ...@@ -1585,10 +1636,11 @@ void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
return result->Add(isolate()->factory()->string_map()); return result->Add(isolate()->factory()->string_map());
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
if (stub->ic_state() == MONOMORPHIC) { switch (stub->ic_state()) {
case MONOMORPHIC:
result->Add(Handle<Map>(stub->FindFirstMap())); result->Add(Handle<Map>(stub->FindFirstMap()));
} else { break;
ASSERT(stub->ic_state() == MEGAMORPHIC); case MEGAMORPHIC: {
AssertNoAllocation no_allocation; AssertNoAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
for (RelocIterator it(*stub, mask); !it.done(); it.next()) { for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
...@@ -1597,6 +1649,15 @@ void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, ...@@ -1597,6 +1649,15 @@ void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
ASSERT(object->IsMap()); ASSERT(object->IsMap());
AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); 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,16 +2085,28 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, ...@@ -2024,16 +2085,28 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
ASSERT(!code.is_null()); ASSERT(!code.is_null());
// Patch the call site depending on the state of the cache. Make // Patch the call site depending on the state of the cache.
// sure to always rewrite from monomorphic to megamorphic. switch (state) {
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); case UNINITIALIZED:
if (state == UNINITIALIZED || state == PREMONOMORPHIC) { case PREMONOMORPHIC:
set_target(*code); set_target(*code);
} else if (state == MONOMORPHIC) { break;
case MONOMORPHIC:
// Only move to megamorphic if the target changes.
if (target() != *code) {
set_target((strict_mode == kStrictMode) set_target((strict_mode == kStrictMode)
? *megamorphic_stub_strict() ? *megamorphic_stub_strict()
: *megamorphic_stub()); : *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()); TRACE_IC("KeyedStoreIC", name, state, target());
} }
...@@ -2057,8 +2130,7 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { ...@@ -2057,8 +2130,7 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
extra_ic_state, extra_ic_state,
args.at<Object>(0), args.at<Object>(0),
args.at<String>(1)); args.at<String>(1));
// Result could be a function or a failure. JSFunction* raw_function;
JSFunction* raw_function = NULL;
if (!maybe_result->To(&raw_function)) return maybe_result; if (!maybe_result->To(&raw_function)) return maybe_result;
// The first time the inline cache is updated may be the first time the // The first time the inline cache is updated may be the first time the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment