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

Unified Diff: src/ic.cc

Issue 115744: This patch much improves our tracking of whether function is... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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
Index: src/ic.cc
===================================================================
--- src/ic.cc (revision 2034)
+++ src/ic.cc (working copy)
@@ -38,10 +38,9 @@
namespace v8 { namespace internal {
#ifdef DEBUG
-static char TransitionMarkFromState(IC::State state) {
+static const char TransitionMarkFromState(IC::State state) {
switch (state) {
case UNINITIALIZED: return '0';
- case UNINITIALIZED_IN_LOOP: return 'L';
case PREMONOMORPHIC: return 'P';
case MONOMORPHIC: return '1';
case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
@@ -60,12 +59,14 @@
void IC::TraceIC(const char* type,
Handle<String> name,
State old_state,
- Code* new_target) {
+ Code* new_target,
+ const char* extra_info) {
if (FLAG_trace_ic) {
State new_state = StateFrom(new_target, Heap::undefined_value());
- PrintF("[%s (%c->%c) ", type,
+ PrintF("[%s (%c->%c)%s", type,
TransitionMarkFromState(old_state),
- TransitionMarkFromState(new_state));
+ TransitionMarkFromState(new_state),
+ extra_info);
name->Print();
PrintF("]\n");
}
@@ -226,8 +227,10 @@
void CallIC::Clear(Address address, Code* target) {
State state = target->ic_state();
- if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP) return;
- Code* code = StubCache::FindCallInitialize(target->arguments_count());
+ InlineCacheInLoop in_loop = target->ic_in_loop();
+ if (state == UNINITIALIZED) return;
+ Code* code =
+ StubCache::FindCallInitialize(target->arguments_count(), in_loop);
SetTargetAtAddress(address, code);
}
@@ -390,21 +393,22 @@
// Compute the number of arguments.
int argc = target()->arguments_count();
+ InlineCacheInLoop in_loop = target()->ic_in_loop();
Object* code = NULL;
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 = StubCache::ComputeCallPreMonomorphic(argc);
+ code = StubCache::ComputeCallPreMonomorphic(argc, in_loop);
} else if (state == MONOMORPHIC) {
- code = StubCache::ComputeCallMegamorphic(argc);
+ code = StubCache::ComputeCallMegamorphic(argc, in_loop);
} else {
// Compute monomorphic stub.
switch (lookup->type()) {
case FIELD: {
int index = lookup->GetFieldIndex();
- code = StubCache::ComputeCallField(argc, *name, *object,
+ code = StubCache::ComputeCallField(argc, in_loop, *name, *object,
lookup->holder(), index);
break;
}
@@ -413,7 +417,7 @@
// call; used for rewriting to monomorphic state and making sure
// that the code stub is in the stub cache.
JSFunction* function = lookup->GetConstantFunction();
- code = StubCache::ComputeCallConstant(argc, *name, *object,
+ code = StubCache::ComputeCallConstant(argc, in_loop, *name, *object,
lookup->holder(), function);
break;
}
@@ -425,7 +429,7 @@
if (!object->IsJSObject()) return;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
if (lookup->holder() != *receiver) return;
- code = StubCache::ComputeCallNormal(argc, *name, *receiver);
+ code = StubCache::ComputeCallNormal(argc, in_loop, *name, *receiver);
break;
}
case INTERCEPTOR: {
@@ -443,14 +447,14 @@
if (code->IsFailure()) return;
// Patch the call site depending on the state of the cache.
- if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP ||
+ if (state == UNINITIALIZED ||
state == PREMONOMORPHIC || state == MONOMORPHIC ||
Kevin Millikin (Chromium) 2009/05/25 11:00:42 One disjunct per line?
state == MONOMORPHIC_PROTOTYPE_FAILURE) {
set_target(Code::cast(code));
}
#ifdef DEBUG
- TraceIC("CallIC", name, state, target());
+ TraceIC("CallIC", name, state, target(), in_loop ? " (in-loop)" : "");
#endif
}
@@ -1088,14 +1092,27 @@
IC::State state = IC::StateFrom(ic.target(), args[0]);
Object* result =
ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
- if (state != UNINITIALIZED_IN_LOOP || !result->IsJSFunction())
+
+ // The first time the inline cache is updated may be the first time the
+ // function it references gets called. If the function was 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. We
+ // do this in the case where we know that the inline cache is inside a loop,
+ // because then we know that we want to optimize the function.
+ if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
return result;
+ }
- // Compile the function with the knowledge that it's called from
- // within a loop. This enables further optimization of the function.
+ // Compile now with optimization.
HandleScope scope;
Handle<JSFunction> function = Handle<JSFunction>(JSFunction::cast(result));
- if (!function->is_compiled()) CompileLazyInLoop(function, CLEAR_EXCEPTION);
+ InlineCacheInLoop in_loop = ic.target()->ic_in_loop();
+ if (in_loop) {
Kevin Millikin (Chromium) 2009/05/25 11:00:42 if (in_loop == IN_LOOP) ....
+ CompileLazyInLoop(function, CLEAR_EXCEPTION);
+ } else {
+ CompileLazy(function, CLEAR_EXCEPTION);
+ }
return *function;
}

Powered by Google App Engine
This is Rietveld 408576698