| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 82aa2189abb14192fb80d9fcdf3c3193e7f3b324..6ecb462cf70876001f21597c9af92a7a6ed64dc3 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -68,9 +68,11 @@ void IC::TraceIC(const char* type,
|
| }
|
| JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
|
| ExtraICState extra_state = new_target->extra_ic_state();
|
| - const char* modifier =
|
| - GetTransitionMarkModifier(
|
| - KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
|
| + const char* modifier = "";
|
| + if (new_target->kind() == Code::KEYED_STORE_IC) {
|
| + modifier = GetTransitionMarkModifier(
|
| + KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
|
| + }
|
| PrintF(" (%c->%c%s)",
|
| TransitionMarkFromState(state()),
|
| TransitionMarkFromState(new_state),
|
| @@ -390,6 +392,10 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
| target->is_inline_cache_stub()) {
|
| int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
|
| target->ic_state());
|
| + // Call ICs don't have interesting state changes from this point
|
| + // of view.
|
| + ASSERT(target->kind() != Code::CALL_IC || delta == 0);
|
| +
|
| // Not all Code objects have TypeFeedbackInfo.
|
| if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
|
| TypeFeedbackInfo* info =
|
| @@ -462,6 +468,8 @@ void IC::Clear(Isolate* isolate, Address address,
|
| return StoreIC::Clear(isolate, address, target, constant_pool);
|
| case Code::KEYED_STORE_IC:
|
| return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
|
| + case Code::CALL_IC:
|
| + return CallIC::Clear(isolate, address, target, constant_pool);
|
| case Code::COMPARE_IC:
|
| return CompareIC::Clear(isolate, address, target, constant_pool);
|
| case Code::COMPARE_NIL_IC:
|
| @@ -488,6 +496,15 @@ void KeyedLoadIC::Clear(Isolate* isolate,
|
| }
|
|
|
|
|
| +void CallIC::Clear(Isolate* isolate,
|
| + Address address,
|
| + Code* target,
|
| + ConstantPoolArray* constant_pool) {
|
| + // Currently, CallIC doesn't have state changes.
|
| + ASSERT(target->ic_state() == v8::internal::GENERIC);
|
| +}
|
| +
|
| +
|
| void LoadIC::Clear(Isolate* isolate,
|
| Address address,
|
| Code* target,
|
| @@ -1316,6 +1333,23 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object,
|
| }
|
|
|
|
|
| +void CallIC::State::Print(StringStream* stream) const {
|
| + stream->Add("(args(%d), ",
|
| + argc_);
|
| + stream->Add("%s, ",
|
| + call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION");
|
| +}
|
| +
|
| +
|
| +Handle<Code> CallIC::initialize_stub(Isolate* isolate,
|
| + int argc,
|
| + CallType call_type) {
|
| + CallICStub stub(isolate, State::DefaultCallState(argc, call_type));
|
| + Handle<Code> code = stub.GetCode();
|
| + return code;
|
| +}
|
| +
|
| +
|
| Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
|
| StrictMode strict_mode) {
|
| ExtraICState extra_state = ComputeExtraICState(strict_mode);
|
| @@ -1780,6 +1814,47 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| }
|
|
|
|
|
| +CallIC::State::State(ExtraICState extra_ic_state)
|
| + : argc_(ArgcBits::decode(extra_ic_state)),
|
| + call_type_(CallTypeBits::decode(extra_ic_state)) {
|
| +}
|
| +
|
| +
|
| +ExtraICState CallIC::State::GetExtraICState() const {
|
| + ExtraICState extra_ic_state =
|
| + ArgcBits::encode(argc_) |
|
| + CallTypeBits::encode(call_type_);
|
| + return extra_ic_state;
|
| +}
|
| +
|
| +
|
| +void CallIC::HandleMiss(Handle<Object> receiver,
|
| + Handle<Object> function,
|
| + Handle<FixedArray> vector,
|
| + Handle<Smi> slot) {
|
| + State state(target()->extra_ic_state());
|
| + Object* feedback = vector->get(slot->value());
|
| +
|
| + if (feedback->IsJSFunction() || !function->IsJSFunction()) {
|
| + // We are going generic.
|
| + ASSERT(!function->IsJSFunction() || *function != feedback);
|
| +
|
| + vector->set(slot->value(),
|
| + *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
|
| + SKIP_WRITE_BARRIER);
|
| + TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
|
| + } else {
|
| + // If we came here feedback must be the uninitialized sentinel,
|
| + // and we are going monomorphic.
|
| + ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()));
|
| + Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
|
| + Handle<Object> name(js_function->shared()->name(), isolate());
|
| + TRACE_IC("CallIC", name);
|
| + vector->set(slot->value(), *function);
|
| + }
|
| +}
|
| +
|
| +
|
| #undef TRACE_IC
|
|
|
|
|
| @@ -1788,6 +1863,19 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| //
|
|
|
| // Used from ic-<arch>.cc.
|
| +RUNTIME_FUNCTION(CallIC_Miss) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 4);
|
| + CallIC ic(isolate);
|
| + Handle<Object> receiver = args.at<Object>(0);
|
| + Handle<Object> function = args.at<Object>(1);
|
| + Handle<FixedArray> vector = args.at<FixedArray>(2);
|
| + Handle<Smi> slot = args.at<Smi>(3);
|
| + ic.HandleMiss(receiver, function, vector, slot);
|
| + return *function;
|
| +}
|
| +
|
| +
|
| // Used from ic-<arch>.cc.
|
| RUNTIME_FUNCTION(LoadIC_Miss) {
|
| HandleScope scope(isolate);
|
|
|