Chromium Code Reviews| Index: src/ic.cc |
| diff --git a/src/ic.cc b/src/ic.cc |
| index 659e7fb0ad90b02c40d56c1b1438ada2c32a5e3a..7f4fbf10cb7a4d92705ead95fc37f8c5e3a00543 100644 |
| --- a/src/ic.cc |
| +++ b/src/ic.cc |
| @@ -100,7 +100,11 @@ void IC::TraceIC(const char* type, |
| PrintF("]\n"); |
| } |
| } |
| -#endif |
| +#endif // DEBUG |
| + |
| + |
| +#define TRACE_IC(type, name, old_state, new_target) \ |
| + ASSERT((TraceIC(type, name, old_state, new_target), true)) |
| IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { |
| @@ -617,89 +621,57 @@ bool CallICBase::TryUpdateExtraICState(LookupResult* lookup, |
| } |
| -MaybeObject* CallICBase::ComputeMonomorphicStub( |
| - LookupResult* lookup, |
| - State state, |
| - Code::ExtraICState extra_ic_state, |
| - Handle<Object> object, |
| - Handle<String> name) { |
| +Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
| + State state, |
| + Code::ExtraICState extra_state, |
| + Handle<Object> object, |
| + Handle<String> name) { |
| int argc = target()->arguments_count(); |
| - MaybeObject* maybe_code = NULL; |
| + Handle<JSObject> holder(lookup->holder()); |
| switch (lookup->type()) { |
| case FIELD: { |
| int index = lookup->GetFieldIndex(); |
| - maybe_code = isolate()->stub_cache()->ComputeCallField(argc, |
| - kind_, |
| - extra_ic_state, |
| - *name, |
| - *object, |
| - lookup->holder(), |
| - index); |
| - break; |
| + return isolate()->stub_cache()->ComputeCallField( |
| + argc, kind_, extra_state, name, object, holder, index); |
| } |
| case CONSTANT_FUNCTION: { |
| // Get the constant function and compute the code stub for this |
| // call; used for rewriting to monomorphic state and making sure |
| // that the code stub is in the stub cache. |
| - JSFunction* function = lookup->GetConstantFunction(); |
| - maybe_code = |
| - isolate()->stub_cache()->ComputeCallConstant(argc, |
| - kind_, |
| - extra_ic_state, |
| - *name, |
| - *object, |
| - lookup->holder(), |
| - function); |
| - break; |
| + Handle<JSFunction> function(lookup->GetConstantFunction()); |
| + return isolate()->stub_cache()->ComputeCallConstant( |
| + argc, kind_, extra_state, name, object, holder, function); |
| } |
| case NORMAL: { |
| - if (!object->IsJSObject()) return NULL; |
| + // If we return a null handle, the IC will not be patched. |
| + if (!object->IsJSObject()) return Handle<Code>::null(); |
| Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| - if (lookup->holder()->IsGlobalObject()) { |
| - GlobalObject* global = GlobalObject::cast(lookup->holder()); |
| - JSGlobalPropertyCell* cell = |
| - JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
| - if (!cell->value()->IsJSFunction()) return NULL; |
| - JSFunction* function = JSFunction::cast(cell->value()); |
| - maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, |
| - kind_, |
| - extra_ic_state, |
| - *name, |
| - *receiver, |
| - global, |
| - cell, |
| - function); |
| + if (holder->IsGlobalObject()) { |
| + Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
| + Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); |
| + if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); |
| + Handle<JSFunction> function(JSFunction::cast(cell->value())); |
| + return isolate()->stub_cache()->ComputeCallGlobal( |
| + argc, kind_, extra_state, name, receiver, global, cell, function); |
| } else { |
| // There is only one shared stub for calling normalized |
| // properties. It does not traverse the prototype chain, so the |
| // property must be found in the receiver for the stub to be |
| // applicable. |
| - if (lookup->holder() != *receiver) return NULL; |
| - maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, |
| - kind_, |
| - extra_ic_state, |
| - *name, |
| - *receiver); |
| + if (!holder.is_identical_to(receiver)) return Handle<Code>::null(); |
| + return isolate()->stub_cache()->ComputeCallNormal( |
| + argc, kind_, extra_state); |
| } |
| break; |
| } |
| - case INTERCEPTOR: { |
| - ASSERT(HasInterceptorGetter(lookup->holder())); |
| - maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( |
| - argc, |
| - kind_, |
| - extra_ic_state, |
| - *name, |
| - *object, |
| - lookup->holder()); |
| - break; |
| - } |
| + case INTERCEPTOR: |
| + ASSERT(HasInterceptorGetter(*holder)); |
| + return isolate()->stub_cache()->ComputeCallInterceptor( |
| + argc, kind_, extra_state, name, object, holder); |
| default: |
| - maybe_code = NULL; |
| - break; |
| + return Handle<Code>::null(); |
| } |
| - return maybe_code; |
| } |
| @@ -721,75 +693,57 @@ void CallICBase::UpdateCaches(LookupResult* lookup, |
| // Compute the number of arguments. |
| int argc = target()->arguments_count(); |
| - MaybeObject* maybe_code = NULL; |
| bool had_proto_failure = false; |
| + 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. |
| - maybe_code = |
| - isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, |
| - kind_, |
| - extra_ic_state); |
| + code = isolate()->stub_cache()->ComputeCallPreMonomorphic( |
| + argc, kind_, extra_ic_state); |
| } else if (state == MONOMORPHIC) { |
| if (kind_ == Code::CALL_IC && |
| TryUpdateExtraICState(lookup, object, &extra_ic_state)) { |
| - maybe_code = ComputeMonomorphicStub(lookup, |
| - state, |
| - extra_ic_state, |
| - object, |
| - name); |
| + code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
| + object, name); |
| } else if (kind_ == Code::CALL_IC && |
| TryRemoveInvalidPrototypeDependentStub(target(), |
| *object, |
| *name)) { |
| had_proto_failure = true; |
| - maybe_code = ComputeMonomorphicStub(lookup, |
| - state, |
| - extra_ic_state, |
| - object, |
| - name); |
| + code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
| + object, name); |
| } else { |
| - maybe_code = |
| - isolate()->stub_cache()->ComputeCallMegamorphic(argc, |
| - kind_, |
| - extra_ic_state); |
| + code = isolate()->stub_cache()->ComputeCallMegamorphic( |
| + argc, kind_, extra_ic_state); |
| } |
| } else { |
| - maybe_code = ComputeMonomorphicStub(lookup, |
| - state, |
| - extra_ic_state, |
| - object, |
| - name); |
| + code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
| + object, name); |
| } |
| - // If we're unable to compute the stub (not enough memory left), we |
| - // simply avoid updating the caches. |
| - Object* code; |
| - if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; |
| + // If there's no appropriate stub we simply avoid updating the caches. |
| + 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::cast(code)); |
| + 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. |
| - Map* map = JSObject::cast(object->IsJSObject() ? *object : |
| - object->GetPrototype())->map(); |
| - |
| + 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, map, Code::cast(code)); |
| + isolate()->stub_cache()->Set(*name, cache_object->map(), *code); |
| } |
| - USE(had_proto_failure); |
| -#ifdef DEBUG |
| if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; |
| - TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", |
| - name, state, target()); |
| -#endif |
| + TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", |
| + name, state, target()); |
| } |
| @@ -813,25 +767,15 @@ MaybeObject* KeyedCallIC::LoadFunction(State state, |
| isolate()->factory()->non_strict_arguments_elements_map(); |
| if (object->IsJSObject() && |
| Handle<JSObject>::cast(object)->elements()->map() == *map) { |
| - MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( |
| + Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments( |
| argc, Code::KEYED_CALL_IC); |
| - Code* code = NULL; |
| - if (maybe_code->To(&code)) { |
| - set_target(code); |
| -#ifdef DEBUG |
| - TraceIC("KeyedCallIC", key, state, target()); |
| -#endif |
| - } |
| + set_target(*code); |
| + TRACE_IC("KeyedCallIC", key, state, target()); |
| } else if (!object->IsAccessCheckNeeded()) { |
| - MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( |
| + Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic( |
| argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
| - Code* code; |
| - if (maybe_code->To(&code)) { |
| - set_target(code); |
| -#ifdef DEBUG |
| - TraceIC("KeyedCallIC", key, state, target()); |
| -#endif |
| - } |
| + set_target(*code); |
| + TRACE_IC("KeyedCallIC", key, state, target()); |
| } |
| } |
| @@ -1062,9 +1006,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup, |
| isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
| } |
| -#ifdef DEBUG |
| - TraceIC("LoadIC", name, state, target()); |
| -#endif |
| + TRACE_IC("LoadIC", name, state, target()); |
| } |
| @@ -1138,9 +1080,7 @@ MaybeObject* KeyedLoadIC::Load(State state, |
| if (!maybe_code->ToObject(&code)) return maybe_code; |
| } |
| set_target(Code::cast(code)); |
| -#ifdef DEBUG |
| - TraceIC("KeyedLoadIC", name, state, target()); |
| -#endif // DEBUG |
| + TRACE_IC("KeyedLoadIC", name, state, target()); |
| return Smi::FromInt(string->length()); |
| } |
| @@ -1155,9 +1095,7 @@ MaybeObject* KeyedLoadIC::Load(State state, |
| if (!maybe_code->ToObject(&code)) return maybe_code; |
| } |
| set_target(Code::cast(code)); |
| -#ifdef DEBUG |
| - TraceIC("KeyedLoadIC", name, state, target()); |
| -#endif // DEBUG |
| + TRACE_IC("KeyedLoadIC", name, state, target()); |
| return JSArray::cast(*object)->length(); |
| } |
| @@ -1173,9 +1111,7 @@ MaybeObject* KeyedLoadIC::Load(State state, |
| if (!maybe_code->ToObject(&code)) return maybe_code; |
| } |
| set_target(Code::cast(code)); |
| -#ifdef DEBUG |
| - TraceIC("KeyedLoadIC", name, state, target()); |
| -#endif // DEBUG |
| + TRACE_IC("KeyedLoadIC", name, state, target()); |
| return Accessors::FunctionGetPrototype(*object, 0); |
| } |
| } |
| @@ -1254,9 +1190,7 @@ MaybeObject* KeyedLoadIC::Load(State state, |
| if (stub != NULL) set_target(stub); |
| } |
| -#ifdef DEBUG |
| - TraceIC("KeyedLoadIC", key, state, target()); |
| -#endif // DEBUG |
| + TRACE_IC("KeyedLoadIC", key, state, target()); |
| // Get the property. |
| return Runtime::GetObjectProperty(isolate(), object, key); |
| @@ -1333,9 +1267,7 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, |
| set_target(megamorphic_stub()); |
| } |
| -#ifdef DEBUG |
| - TraceIC("KeyedLoadIC", name, state, target()); |
| -#endif |
| + TRACE_IC("KeyedLoadIC", name, state, target()); |
| } |
| @@ -1450,9 +1382,7 @@ MaybeObject* StoreIC::Store(State state, |
| : global_proxy_stub(); |
| if (target() != *stub) { |
| set_target(*stub); |
| -#ifdef DEBUG |
| - TraceIC("StoreIC", name, state, target()); |
| -#endif |
| + TRACE_IC("StoreIC", name, state, target()); |
| } |
| } |
| @@ -1546,9 +1476,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup, |
| isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
| } |
| -#ifdef DEBUG |
| - TraceIC("StoreIC", name, state, target()); |
| -#endif |
| + TRACE_IC("StoreIC", name, state, target()); |
| } |
| @@ -1886,9 +1814,7 @@ MaybeObject* KeyedStoreIC::Store(State state, |
| if (stub != NULL) set_target(stub); |
| } |
| -#ifdef DEBUG |
| - TraceIC("KeyedStoreIC", key, state, target()); |
| -#endif |
| + TRACE_IC("KeyedStoreIC", key, state, target()); |
| // Set the property. |
| return Runtime::SetObjectProperty( |
| @@ -1966,11 +1892,11 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, |
| : megamorphic_stub()); |
| } |
| -#ifdef DEBUG |
| - TraceIC("KeyedStoreIC", name, state, target()); |
| -#endif |
| + TRACE_IC("KeyedStoreIC", name, state, target()); |
| } |
|
Vyacheslav Egorov (Chromium)
2011/10/20 10:12:23
add empty line
Kevin Millikin (Chromium)
2011/10/20 10:57:08
Done.
|
| +#undef TRACE_IC |
| + |
| // ---------------------------------------------------------------------------- |
| // Static IC stub generators. |