| Index: src/ic.cc
 | 
| diff --git a/src/ic.cc b/src/ic.cc
 | 
| index fd86f1e460b661562f48a38cd136bf7d46cc14b3..c79ea2c7cf09e9b194a27b7c18e36f9164588884 100644
 | 
| --- a/src/ic.cc
 | 
| +++ b/src/ic.cc
 | 
| @@ -424,8 +424,6 @@ void IC::Clear(Isolate* isolate, Address address) {
 | 
|      case Code::STORE_IC: return StoreIC::Clear(isolate, address, target);
 | 
|      case Code::KEYED_STORE_IC:
 | 
|        return KeyedStoreIC::Clear(isolate, address, target);
 | 
| -    case Code::CALL_IC: return CallIC::Clear(address, target);
 | 
| -    case Code::KEYED_CALL_IC:  return KeyedCallIC::Clear(address, target);
 | 
|      case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target);
 | 
|      case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target);
 | 
|      case Code::BINARY_OP_IC:
 | 
| @@ -438,14 +436,6 @@ void IC::Clear(Isolate* isolate, Address address) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void CallICBase::Clear(Address address, Code* target) {
 | 
| -  if (IsCleared(target)) return;
 | 
| -  Code* code = target->GetIsolate()->stub_cache()->FindCallInitialize(
 | 
| -      target->arguments_count(), target->kind());
 | 
| -  SetTargetAtAddress(address, code);
 | 
| -}
 | 
| -
 | 
| -
 | 
|  void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) {
 | 
|    if (IsCleared(target)) return;
 | 
|    // Make sure to also clear the map used in inline fast cases.  If we
 | 
| @@ -492,50 +482,6 @@ void CompareIC::Clear(Isolate* isolate, Address address, Code* target) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) {
 | 
| -  Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object);
 | 
| -
 | 
| -  if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) {
 | 
| -    // Patch the receiver and use the delegate as the function to
 | 
| -    // invoke. This is used for invoking objects as if they were functions.
 | 
| -    const int argc = target()->arguments_count();
 | 
| -    StackFrameLocator locator(isolate());
 | 
| -    JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
 | 
| -    int index = frame->ComputeExpressionsCount() - (argc + 1);
 | 
| -    frame->SetExpression(index, *object);
 | 
| -  }
 | 
| -
 | 
| -  return delegate;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee,
 | 
| -                                            Handle<Object> object) {
 | 
| -  while (callee->IsJSFunctionProxy()) {
 | 
| -    callee = Handle<Object>(JSFunctionProxy::cast(*callee)->call_trap(),
 | 
| -                            isolate());
 | 
| -  }
 | 
| -
 | 
| -  if (callee->IsJSFunction()) {
 | 
| -    Handle<JSFunction> function = Handle<JSFunction>::cast(callee);
 | 
| -    if (!function->shared()->is_classic_mode() || function->IsBuiltin()) {
 | 
| -      // Do not wrap receiver for strict mode functions or for builtins.
 | 
| -      return;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  // And only wrap string, number or boolean.
 | 
| -  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
 | 
| -    // Change the receiver to the result of calling ToObject on it.
 | 
| -    const int argc = this->target()->arguments_count();
 | 
| -    StackFrameLocator locator(isolate());
 | 
| -    JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
 | 
| -    int index = frame->ComputeExpressionsCount() - (argc + 1);
 | 
| -    frame->SetExpression(index, *isolate()->factory()->ToObject(object));
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
|  static bool MigrateDeprecated(Handle<Object> object) {
 | 
|    if (!object->IsJSObject()) return false;
 | 
|    Handle<JSObject> receiver = Handle<JSObject>::cast(object);
 | 
| @@ -545,248 +491,6 @@ static bool MigrateDeprecated(Handle<Object> object) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -MaybeObject* CallICBase::LoadFunction(Handle<Object> object,
 | 
| -                                      Handle<String> name) {
 | 
| -  bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
 | 
| -
 | 
| -  // If the object is undefined or null it's illegal to try to get any
 | 
| -  // of its properties; throw a TypeError in that case.
 | 
| -  if (object->IsUndefined() || object->IsNull()) {
 | 
| -    return TypeError("non_object_property_call", object, name);
 | 
| -  }
 | 
| -
 | 
| -  // Check if the name is trivially convertible to an index and get
 | 
| -  // the element if so.
 | 
| -  uint32_t index;
 | 
| -  if (name->AsArrayIndex(&index)) {
 | 
| -    Handle<Object> result = Object::GetElement(isolate(), object, index);
 | 
| -    RETURN_IF_EMPTY_HANDLE(isolate(), result);
 | 
| -    if (result->IsJSFunction()) return *result;
 | 
| -
 | 
| -    // Try to find a suitable function delegate for the object at hand.
 | 
| -    result = TryCallAsFunction(result);
 | 
| -    if (result->IsJSFunction()) return *result;
 | 
| -
 | 
| -    // Otherwise, it will fail in the lookup step.
 | 
| -  }
 | 
| -
 | 
| -  // Lookup the property in the object.
 | 
| -  LookupResult lookup(isolate());
 | 
| -  LookupForRead(object, name, &lookup);
 | 
| -
 | 
| -  if (!lookup.IsFound()) {
 | 
| -    // If the object does not have the requested property, check which
 | 
| -    // exception we need to throw.
 | 
| -    return object->IsGlobalObject()
 | 
| -        ? ReferenceError("not_defined", name)
 | 
| -        : TypeError("undefined_method", object, name);
 | 
| -  }
 | 
| -
 | 
| -  // Lookup is valid: Update inline cache and stub cache.
 | 
| -  if (use_ic) UpdateCaches(&lookup, object, name);
 | 
| -
 | 
| -  // Get the property.
 | 
| -  PropertyAttributes attr;
 | 
| -  Handle<Object> result =
 | 
| -      Object::GetProperty(object, object, &lookup, name, &attr);
 | 
| -  RETURN_IF_EMPTY_HANDLE(isolate(), result);
 | 
| -
 | 
| -  if (lookup.IsInterceptor() && attr == ABSENT) {
 | 
| -    // If the object does not have the requested property, check which
 | 
| -    // exception we need to throw.
 | 
| -    return object->IsGlobalObject()
 | 
| -        ? ReferenceError("not_defined", name)
 | 
| -        : TypeError("undefined_method", object, name);
 | 
| -  }
 | 
| -
 | 
| -  ASSERT(!result->IsTheHole());
 | 
| -
 | 
| -  // Make receiver an object if the callee requires it. Strict mode or builtin
 | 
| -  // functions do not wrap the receiver, non-strict functions and objects
 | 
| -  // called as functions do.
 | 
| -  ReceiverToObjectIfRequired(result, object);
 | 
| -
 | 
| -  if (result->IsJSFunction()) {
 | 
| -    Handle<JSFunction> function = Handle<JSFunction>::cast(result);
 | 
| -#ifdef ENABLE_DEBUGGER_SUPPORT
 | 
| -    // Handle stepping into a function if step into is active.
 | 
| -    Debug* debug = isolate()->debug();
 | 
| -    if (debug->StepInActive()) {
 | 
| -      // Protect the result in a handle as the debugger can allocate and might
 | 
| -      // cause GC.
 | 
| -      debug->HandleStepIn(function, object, fp(), false);
 | 
| -    }
 | 
| -#endif
 | 
| -    return *function;
 | 
| -  }
 | 
| -
 | 
| -  // Try to find a suitable function delegate for the object at hand.
 | 
| -  result = TryCallAsFunction(result);
 | 
| -  if (result->IsJSFunction()) return *result;
 | 
| -
 | 
| -  return TypeError("property_not_function", object, name);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
 | 
| -                                                Handle<Object> object,
 | 
| -                                                Handle<String> name) {
 | 
| -  int argc = target()->arguments_count();
 | 
| -  Handle<JSObject> holder(lookup->holder(), isolate());
 | 
| -  switch (lookup->type()) {
 | 
| -    case FIELD: {
 | 
| -      PropertyIndex index = lookup->GetFieldIndex();
 | 
| -      return isolate()->stub_cache()->ComputeCallField(
 | 
| -          argc, kind_, extra_ic_state(), name, object, holder, index);
 | 
| -    }
 | 
| -    case CONSTANT: {
 | 
| -      if (!lookup->IsConstantFunction()) return Handle<Code>::null();
 | 
| -      // 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.
 | 
| -      Handle<JSFunction> function(lookup->GetConstantFunction(), isolate());
 | 
| -      return isolate()->stub_cache()->ComputeCallConstant(
 | 
| -          argc, kind_, extra_ic_state(), name, object, holder, function);
 | 
| -    }
 | 
| -    case NORMAL: {
 | 
| -      // 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 (holder->IsGlobalObject()) {
 | 
| -        Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
 | 
| -        Handle<PropertyCell> cell(
 | 
| -            global->GetPropertyCell(lookup), isolate());
 | 
| -        if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
 | 
| -        Handle<JSFunction> function(JSFunction::cast(cell->value()));
 | 
| -        return isolate()->stub_cache()->ComputeCallGlobal(
 | 
| -            argc, kind_, extra_ic_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 (!holder.is_identical_to(receiver)) return Handle<Code>::null();
 | 
| -        return isolate()->stub_cache()->ComputeCallNormal(
 | 
| -            argc, kind_, extra_ic_state());
 | 
| -      }
 | 
| -      break;
 | 
| -    }
 | 
| -    case INTERCEPTOR:
 | 
| -      ASSERT(HasInterceptorGetter(*holder));
 | 
| -      return isolate()->stub_cache()->ComputeCallInterceptor(
 | 
| -          argc, kind_, extra_ic_state(), name, object, holder);
 | 
| -    default:
 | 
| -      return Handle<Code>::null();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> CallICBase::megamorphic_stub() {
 | 
| -  return isolate()->stub_cache()->ComputeCallMegamorphic(
 | 
| -      target()->arguments_count(), kind_, extra_ic_state());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> CallICBase::pre_monomorphic_stub() {
 | 
| -  return isolate()->stub_cache()->ComputeCallPreMonomorphic(
 | 
| -      target()->arguments_count(), kind_, extra_ic_state());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void CallICBase::UpdateCaches(LookupResult* lookup,
 | 
| -                              Handle<Object> object,
 | 
| -                              Handle<String> name) {
 | 
| -  // Bail out if we didn't find a result.
 | 
| -  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
 | 
| -
 | 
| -  if (state() == UNINITIALIZED) {
 | 
| -    set_target(*pre_monomorphic_stub());
 | 
| -    TRACE_IC("CallIC", name);
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  Handle<Code> code = ComputeMonomorphicStub(lookup, object, name);
 | 
| -  // If there's no appropriate stub we simply avoid updating the caches.
 | 
| -  // TODO(verwaest): Install a slow fallback in this case to avoid not learning,
 | 
| -  // and deopting Crankshaft code.
 | 
| -  if (code.is_null()) return;
 | 
| -
 | 
| -  Handle<JSObject> cache_object = object->IsJSObject()
 | 
| -      ? Handle<JSObject>::cast(object)
 | 
| -      : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
 | 
| -                         isolate());
 | 
| -
 | 
| -  PatchCache(CurrentTypeOf(cache_object, isolate()), name, code);
 | 
| -  TRACE_IC("CallIC", name);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object,
 | 
| -                                       Handle<Object> key) {
 | 
| -  if (key->IsInternalizedString()) {
 | 
| -    return CallICBase::LoadFunction(object, Handle<String>::cast(key));
 | 
| -  }
 | 
| -
 | 
| -  if (object->IsUndefined() || object->IsNull()) {
 | 
| -    return TypeError("non_object_property_call", object, key);
 | 
| -  }
 | 
| -
 | 
| -  bool use_ic = MigrateDeprecated(object)
 | 
| -      ? false : FLAG_use_ic && !object->IsAccessCheckNeeded();
 | 
| -
 | 
| -  if (use_ic && state() != MEGAMORPHIC) {
 | 
| -    ASSERT(!object->IsJSGlobalProxy());
 | 
| -    int argc = target()->arguments_count();
 | 
| -    Handle<Code> stub;
 | 
| -
 | 
| -    // Use the KeyedArrayCallStub if the call is of the form array[smi](...),
 | 
| -    // where array is an instance of one of the initial array maps (without
 | 
| -    // extra named properties).
 | 
| -    // TODO(verwaest): Also support keyed calls on instances of other maps.
 | 
| -    if (object->IsJSArray() && key->IsSmi()) {
 | 
| -      Handle<JSArray> array = Handle<JSArray>::cast(object);
 | 
| -      ElementsKind kind = array->map()->elements_kind();
 | 
| -      if (IsFastObjectElementsKind(kind) &&
 | 
| -          array->map() == isolate()->get_initial_js_array_map(kind)) {
 | 
| -        KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc);
 | 
| -        stub = stub_gen.GetCode(isolate());
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    if (stub.is_null()) {
 | 
| -      stub = isolate()->stub_cache()->ComputeCallMegamorphic(
 | 
| -          argc, Code::KEYED_CALL_IC, kNoExtraICState);
 | 
| -      if (object->IsJSObject()) {
 | 
| -        Handle<JSObject> receiver = Handle<JSObject>::cast(object);
 | 
| -        if (receiver->elements()->map() ==
 | 
| -            isolate()->heap()->non_strict_arguments_elements_map()) {
 | 
| -          stub = isolate()->stub_cache()->ComputeCallArguments(argc);
 | 
| -        }
 | 
| -      }
 | 
| -      ASSERT(!stub.is_null());
 | 
| -    }
 | 
| -    set_target(*stub);
 | 
| -    TRACE_IC("CallIC", key);
 | 
| -  }
 | 
| -
 | 
| -  Handle<Object> result = GetProperty(isolate(), object, key);
 | 
| -  RETURN_IF_EMPTY_HANDLE(isolate(), result);
 | 
| -
 | 
| -  // Make receiver an object if the callee requires it. Strict mode or builtin
 | 
| -  // functions do not wrap the receiver, non-strict functions and objects
 | 
| -  // called as functions do.
 | 
| -  ReceiverToObjectIfRequired(result, object);
 | 
| -  if (result->IsJSFunction()) return *result;
 | 
| -
 | 
| -  result = TryCallAsFunction(result);
 | 
| -  if (result->IsJSFunction()) return *result;
 | 
| -
 | 
| -  return TypeError("property_not_function", object, key);
 | 
| -}
 | 
| -
 | 
| -
 | 
|  MaybeObject* LoadIC::Load(Handle<Object> object,
 | 
|                            Handle<String> name) {
 | 
|    // If the object is undefined or null it's illegal to try to get any
 | 
| @@ -880,6 +584,7 @@ MaybeObject* LoadIC::Load(Handle<Object> object,
 | 
|        attr == ABSENT && IsUndeclaredGlobal(object)) {
 | 
|      return ReferenceError("not_defined", name);
 | 
|    }
 | 
| +
 | 
|    return *result;
 | 
|  }
 | 
|  
 | 
| @@ -1027,9 +732,7 @@ void IC::PatchCache(Handle<HeapType> type,
 | 
|      case MONOMORPHIC: {
 | 
|        // For now, call stubs are allowed to rewrite to the same stub. This
 | 
|        // happens e.g., when the field does not contain a function.
 | 
| -      ASSERT(target()->is_call_stub() ||
 | 
| -             target()->is_keyed_call_stub() ||
 | 
| -             !target().is_identical_to(code));
 | 
| +      ASSERT(!target().is_identical_to(code));
 | 
|        Code* old_handler = target()->FindFirstHandler();
 | 
|        if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
 | 
|          UpdateMonomorphicIC(type, code, name);
 | 
| @@ -1056,23 +759,20 @@ void IC::PatchCache(Handle<HeapType> type,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) {
 | 
| -  Handle<Code> ic = isolate->stub_cache()->ComputeLoad(
 | 
| -      UNINITIALIZED, ComputeExtraICState(mode));
 | 
| -  return ic;
 | 
| +Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
 | 
| +                                     ExtraICState extra_state) {
 | 
| +  return isolate->stub_cache()->ComputeLoad(UNINITIALIZED, extra_state);
 | 
|  }
 | 
|  
 | 
|  
 | 
|  Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
 | 
| -                                          ContextualMode mode) {
 | 
| -  return isolate->stub_cache()->ComputeLoad(
 | 
| -      PREMONOMORPHIC, ComputeExtraICState(mode));
 | 
| +                                          ExtraICState extra_state) {
 | 
| +  return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, extra_state);
 | 
|  }
 | 
|  
 | 
|  
 | 
|  Handle<Code> LoadIC::megamorphic_stub() {
 | 
| -  return isolate()->stub_cache()->ComputeLoad(
 | 
| -      MEGAMORPHIC, extra_ic_state());
 | 
| +  return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state());
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -2025,51 +1725,6 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
 | 
|  //
 | 
|  
 | 
|  // Used from ic-<arch>.cc.
 | 
| -RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
 | 
| -  HandleScope scope(isolate);
 | 
| -  ASSERT(args.length() == 2);
 | 
| -  CallIC ic(isolate);
 | 
| -  Handle<Object> receiver = args.at<Object>(0);
 | 
| -  Handle<String> key = args.at<String>(1);
 | 
| -  ic.UpdateState(receiver, key);
 | 
| -  MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
 | 
| -  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
 | 
| -  // 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;
 | 
| -
 | 
| -  Handle<JSFunction> function(raw_function);
 | 
| -  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
 | 
| -  return *function;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Used from ic-<arch>.cc.
 | 
| -RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
 | 
| -  HandleScope scope(isolate);
 | 
| -  ASSERT(args.length() == 2);
 | 
| -  KeyedCallIC ic(isolate);
 | 
| -  Handle<Object> receiver = args.at<Object>(0);
 | 
| -  Handle<Object> key = args.at<Object>(1);
 | 
| -  ic.UpdateState(receiver, key);
 | 
| -  MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
 | 
| -  // Result could be a function or a failure.
 | 
| -  JSFunction* raw_function = NULL;
 | 
| -  if (!maybe_result->To(&raw_function)) return maybe_result;
 | 
| -
 | 
| -  if (raw_function->is_compiled()) return raw_function;
 | 
| -
 | 
| -  Handle<JSFunction> function(raw_function, isolate);
 | 
| -  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
 | 
| -  return *function;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  // Used from ic-<arch>.cc.
 | 
|  RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
 | 
|    HandleScope scope(isolate);
 | 
| @@ -2128,28 +1783,6 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) {
 | 
| -  HandleScope scope(isolate);
 | 
| -  ASSERT(args.length() == 2);
 | 
| -  KeyedCallIC ic(isolate);
 | 
| -  Arguments* caller_args = reinterpret_cast<Arguments*>(args[0]);
 | 
| -  Handle<Object> key = args.at<Object>(1);
 | 
| -  Handle<Object> receiver((*caller_args)[0], isolate);
 | 
| -
 | 
| -  ic.UpdateState(receiver, key);
 | 
| -  MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
 | 
| -  // Result could be a function or a failure.
 | 
| -  JSFunction* raw_function = NULL;
 | 
| -  if (!maybe_result->To(&raw_function)) return maybe_result;
 | 
| -
 | 
| -  if (raw_function->is_compiled()) return raw_function;
 | 
| -
 | 
| -  Handle<JSFunction> function(raw_function, isolate);
 | 
| -  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
 | 
| -  return *function;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
 | 
|    SealHandleScope shs(isolate);
 | 
|  
 | 
| 
 |