Revision: 13328
Author: [email protected]
Date: Mon Jan 7 07:35:00 2013
Log: Slight cleanup of UpdateCache code.
Review URL: https://chromiumcodereview.appspot.com/11737033
http://code.google.com/p/v8/source/detail?r=13328
Modified:
/branches/bleeding_edge/src/ic.cc
=======================================
--- /branches/bleeding_edge/src/ic.cc Fri Jan 4 07:37:59 2013
+++ /branches/bleeding_edge/src/ic.cc Mon Jan 7 07:35:00 2013
@@ -712,7 +712,6 @@
// 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 @@
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 @@
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);
+ 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;
}
- if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
name, state, target());
}
@@ -1024,25 +1037,34 @@
}
// 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 @@
}
}
- // 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 @@
}
// 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 @@
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 @@
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 @@
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;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev