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

Side by Side Diff: src/ic.cc

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/isolate.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 // Don't clear debug break inline cache as it will remove the break point. 417 // Don't clear debug break inline cache as it will remove the break point.
418 if (target->is_debug_stub()) return; 418 if (target->is_debug_stub()) return;
419 419
420 switch (target->kind()) { 420 switch (target->kind()) {
421 case Code::LOAD_IC: return LoadIC::Clear(isolate, address, target); 421 case Code::LOAD_IC: return LoadIC::Clear(isolate, address, target);
422 case Code::KEYED_LOAD_IC: 422 case Code::KEYED_LOAD_IC:
423 return KeyedLoadIC::Clear(isolate, address, target); 423 return KeyedLoadIC::Clear(isolate, address, target);
424 case Code::STORE_IC: return StoreIC::Clear(isolate, address, target); 424 case Code::STORE_IC: return StoreIC::Clear(isolate, address, target);
425 case Code::KEYED_STORE_IC: 425 case Code::KEYED_STORE_IC:
426 return KeyedStoreIC::Clear(isolate, address, target); 426 return KeyedStoreIC::Clear(isolate, address, target);
427 case Code::CALL_IC: return CallIC::Clear(address, target);
428 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
429 case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target); 427 case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target);
430 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); 428 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target);
431 case Code::BINARY_OP_IC: 429 case Code::BINARY_OP_IC:
432 case Code::TO_BOOLEAN_IC: 430 case Code::TO_BOOLEAN_IC:
433 // Clearing these is tricky and does not 431 // Clearing these is tricky and does not
434 // make any performance difference. 432 // make any performance difference.
435 return; 433 return;
436 default: UNREACHABLE(); 434 default: UNREACHABLE();
437 } 435 }
438 } 436 }
439 437
440 438
441 void CallICBase::Clear(Address address, Code* target) {
442 if (IsCleared(target)) return;
443 Code* code = target->GetIsolate()->stub_cache()->FindCallInitialize(
444 target->arguments_count(), target->kind());
445 SetTargetAtAddress(address, code);
446 }
447
448
449 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { 439 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) {
450 if (IsCleared(target)) return; 440 if (IsCleared(target)) return;
451 // Make sure to also clear the map used in inline fast cases. If we 441 // Make sure to also clear the map used in inline fast cases. If we
452 // do not clear these maps, cached code can keep objects alive 442 // do not clear these maps, cached code can keep objects alive
453 // through the embedded maps. 443 // through the embedded maps.
454 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 444 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate));
455 } 445 }
456 446
457 447
458 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { 448 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) {
(...skipping 26 matching lines...) Expand all
485 Token::Value op; 475 Token::Value op;
486 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, 476 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
487 &handler_state, &op); 477 &handler_state, &op);
488 // Only clear CompareICs that can retain objects. 478 // Only clear CompareICs that can retain objects.
489 if (handler_state != KNOWN_OBJECT) return; 479 if (handler_state != KNOWN_OBJECT) return;
490 SetTargetAtAddress(address, GetRawUninitialized(isolate, op)); 480 SetTargetAtAddress(address, GetRawUninitialized(isolate, op));
491 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 481 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
492 } 482 }
493 483
494 484
495 Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) {
496 Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object);
497
498 if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) {
499 // Patch the receiver and use the delegate as the function to
500 // invoke. This is used for invoking objects as if they were functions.
501 const int argc = target()->arguments_count();
502 StackFrameLocator locator(isolate());
503 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
504 int index = frame->ComputeExpressionsCount() - (argc + 1);
505 frame->SetExpression(index, *object);
506 }
507
508 return delegate;
509 }
510
511
512 void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee,
513 Handle<Object> object) {
514 while (callee->IsJSFunctionProxy()) {
515 callee = Handle<Object>(JSFunctionProxy::cast(*callee)->call_trap(),
516 isolate());
517 }
518
519 if (callee->IsJSFunction()) {
520 Handle<JSFunction> function = Handle<JSFunction>::cast(callee);
521 if (!function->shared()->is_classic_mode() || function->IsBuiltin()) {
522 // Do not wrap receiver for strict mode functions or for builtins.
523 return;
524 }
525 }
526
527 // And only wrap string, number or boolean.
528 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
529 // Change the receiver to the result of calling ToObject on it.
530 const int argc = this->target()->arguments_count();
531 StackFrameLocator locator(isolate());
532 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
533 int index = frame->ComputeExpressionsCount() - (argc + 1);
534 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
535 }
536 }
537
538
539 static bool MigrateDeprecated(Handle<Object> object) { 485 static bool MigrateDeprecated(Handle<Object> object) {
540 if (!object->IsJSObject()) return false; 486 if (!object->IsJSObject()) return false;
541 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 487 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
542 if (!receiver->map()->is_deprecated()) return false; 488 if (!receiver->map()->is_deprecated()) return false;
543 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 489 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
544 return true; 490 return true;
545 } 491 }
546 492
547 493
548 MaybeObject* CallICBase::LoadFunction(Handle<Object> object,
549 Handle<String> name) {
550 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
551
552 // If the object is undefined or null it's illegal to try to get any
553 // of its properties; throw a TypeError in that case.
554 if (object->IsUndefined() || object->IsNull()) {
555 return TypeError("non_object_property_call", object, name);
556 }
557
558 // Check if the name is trivially convertible to an index and get
559 // the element if so.
560 uint32_t index;
561 if (name->AsArrayIndex(&index)) {
562 Handle<Object> result = Object::GetElement(isolate(), object, index);
563 RETURN_IF_EMPTY_HANDLE(isolate(), result);
564 if (result->IsJSFunction()) return *result;
565
566 // Try to find a suitable function delegate for the object at hand.
567 result = TryCallAsFunction(result);
568 if (result->IsJSFunction()) return *result;
569
570 // Otherwise, it will fail in the lookup step.
571 }
572
573 // Lookup the property in the object.
574 LookupResult lookup(isolate());
575 LookupForRead(object, name, &lookup);
576
577 if (!lookup.IsFound()) {
578 // If the object does not have the requested property, check which
579 // exception we need to throw.
580 return object->IsGlobalObject()
581 ? ReferenceError("not_defined", name)
582 : TypeError("undefined_method", object, name);
583 }
584
585 // Lookup is valid: Update inline cache and stub cache.
586 if (use_ic) UpdateCaches(&lookup, object, name);
587
588 // Get the property.
589 PropertyAttributes attr;
590 Handle<Object> result =
591 Object::GetProperty(object, object, &lookup, name, &attr);
592 RETURN_IF_EMPTY_HANDLE(isolate(), result);
593
594 if (lookup.IsInterceptor() && attr == ABSENT) {
595 // If the object does not have the requested property, check which
596 // exception we need to throw.
597 return object->IsGlobalObject()
598 ? ReferenceError("not_defined", name)
599 : TypeError("undefined_method", object, name);
600 }
601
602 ASSERT(!result->IsTheHole());
603
604 // Make receiver an object if the callee requires it. Strict mode or builtin
605 // functions do not wrap the receiver, non-strict functions and objects
606 // called as functions do.
607 ReceiverToObjectIfRequired(result, object);
608
609 if (result->IsJSFunction()) {
610 Handle<JSFunction> function = Handle<JSFunction>::cast(result);
611 #ifdef ENABLE_DEBUGGER_SUPPORT
612 // Handle stepping into a function if step into is active.
613 Debug* debug = isolate()->debug();
614 if (debug->StepInActive()) {
615 // Protect the result in a handle as the debugger can allocate and might
616 // cause GC.
617 debug->HandleStepIn(function, object, fp(), false);
618 }
619 #endif
620 return *function;
621 }
622
623 // Try to find a suitable function delegate for the object at hand.
624 result = TryCallAsFunction(result);
625 if (result->IsJSFunction()) return *result;
626
627 return TypeError("property_not_function", object, name);
628 }
629
630
631 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
632 Handle<Object> object,
633 Handle<String> name) {
634 int argc = target()->arguments_count();
635 Handle<JSObject> holder(lookup->holder(), isolate());
636 switch (lookup->type()) {
637 case FIELD: {
638 PropertyIndex index = lookup->GetFieldIndex();
639 return isolate()->stub_cache()->ComputeCallField(
640 argc, kind_, extra_ic_state(), name, object, holder, index);
641 }
642 case CONSTANT: {
643 if (!lookup->IsConstantFunction()) return Handle<Code>::null();
644 // Get the constant function and compute the code stub for this
645 // call; used for rewriting to monomorphic state and making sure
646 // that the code stub is in the stub cache.
647 Handle<JSFunction> function(lookup->GetConstantFunction(), isolate());
648 return isolate()->stub_cache()->ComputeCallConstant(
649 argc, kind_, extra_ic_state(), name, object, holder, function);
650 }
651 case NORMAL: {
652 // If we return a null handle, the IC will not be patched.
653 if (!object->IsJSObject()) return Handle<Code>::null();
654 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
655
656 if (holder->IsGlobalObject()) {
657 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
658 Handle<PropertyCell> cell(
659 global->GetPropertyCell(lookup), isolate());
660 if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
661 Handle<JSFunction> function(JSFunction::cast(cell->value()));
662 return isolate()->stub_cache()->ComputeCallGlobal(
663 argc, kind_, extra_ic_state(), name,
664 receiver, global, cell, function);
665 } else {
666 // There is only one shared stub for calling normalized
667 // properties. It does not traverse the prototype chain, so the
668 // property must be found in the receiver for the stub to be
669 // applicable.
670 if (!holder.is_identical_to(receiver)) return Handle<Code>::null();
671 return isolate()->stub_cache()->ComputeCallNormal(
672 argc, kind_, extra_ic_state());
673 }
674 break;
675 }
676 case INTERCEPTOR:
677 ASSERT(HasInterceptorGetter(*holder));
678 return isolate()->stub_cache()->ComputeCallInterceptor(
679 argc, kind_, extra_ic_state(), name, object, holder);
680 default:
681 return Handle<Code>::null();
682 }
683 }
684
685
686 Handle<Code> CallICBase::megamorphic_stub() {
687 return isolate()->stub_cache()->ComputeCallMegamorphic(
688 target()->arguments_count(), kind_, extra_ic_state());
689 }
690
691
692 Handle<Code> CallICBase::pre_monomorphic_stub() {
693 return isolate()->stub_cache()->ComputeCallPreMonomorphic(
694 target()->arguments_count(), kind_, extra_ic_state());
695 }
696
697
698 void CallICBase::UpdateCaches(LookupResult* lookup,
699 Handle<Object> object,
700 Handle<String> name) {
701 // Bail out if we didn't find a result.
702 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
703
704 if (state() == UNINITIALIZED) {
705 set_target(*pre_monomorphic_stub());
706 TRACE_IC("CallIC", name);
707 return;
708 }
709
710 Handle<Code> code = ComputeMonomorphicStub(lookup, object, name);
711 // If there's no appropriate stub we simply avoid updating the caches.
712 // TODO(verwaest): Install a slow fallback in this case to avoid not learning,
713 // and deopting Crankshaft code.
714 if (code.is_null()) return;
715
716 Handle<JSObject> cache_object = object->IsJSObject()
717 ? Handle<JSObject>::cast(object)
718 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
719 isolate());
720
721 PatchCache(CurrentTypeOf(cache_object, isolate()), name, code);
722 TRACE_IC("CallIC", name);
723 }
724
725
726 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object,
727 Handle<Object> key) {
728 if (key->IsInternalizedString()) {
729 return CallICBase::LoadFunction(object, Handle<String>::cast(key));
730 }
731
732 if (object->IsUndefined() || object->IsNull()) {
733 return TypeError("non_object_property_call", object, key);
734 }
735
736 bool use_ic = MigrateDeprecated(object)
737 ? false : FLAG_use_ic && !object->IsAccessCheckNeeded();
738
739 if (use_ic && state() != MEGAMORPHIC) {
740 ASSERT(!object->IsJSGlobalProxy());
741 int argc = target()->arguments_count();
742 Handle<Code> stub;
743
744 // Use the KeyedArrayCallStub if the call is of the form array[smi](...),
745 // where array is an instance of one of the initial array maps (without
746 // extra named properties).
747 // TODO(verwaest): Also support keyed calls on instances of other maps.
748 if (object->IsJSArray() && key->IsSmi()) {
749 Handle<JSArray> array = Handle<JSArray>::cast(object);
750 ElementsKind kind = array->map()->elements_kind();
751 if (IsFastObjectElementsKind(kind) &&
752 array->map() == isolate()->get_initial_js_array_map(kind)) {
753 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc);
754 stub = stub_gen.GetCode(isolate());
755 }
756 }
757
758 if (stub.is_null()) {
759 stub = isolate()->stub_cache()->ComputeCallMegamorphic(
760 argc, Code::KEYED_CALL_IC, kNoExtraICState);
761 if (object->IsJSObject()) {
762 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
763 if (receiver->elements()->map() ==
764 isolate()->heap()->non_strict_arguments_elements_map()) {
765 stub = isolate()->stub_cache()->ComputeCallArguments(argc);
766 }
767 }
768 ASSERT(!stub.is_null());
769 }
770 set_target(*stub);
771 TRACE_IC("CallIC", key);
772 }
773
774 Handle<Object> result = GetProperty(isolate(), object, key);
775 RETURN_IF_EMPTY_HANDLE(isolate(), result);
776
777 // Make receiver an object if the callee requires it. Strict mode or builtin
778 // functions do not wrap the receiver, non-strict functions and objects
779 // called as functions do.
780 ReceiverToObjectIfRequired(result, object);
781 if (result->IsJSFunction()) return *result;
782
783 result = TryCallAsFunction(result);
784 if (result->IsJSFunction()) return *result;
785
786 return TypeError("property_not_function", object, key);
787 }
788
789
790 MaybeObject* LoadIC::Load(Handle<Object> object, 494 MaybeObject* LoadIC::Load(Handle<Object> object,
791 Handle<String> name) { 495 Handle<String> name) {
792 // If the object is undefined or null it's illegal to try to get any 496 // If the object is undefined or null it's illegal to try to get any
793 // of its properties; throw a TypeError in that case. 497 // of its properties; throw a TypeError in that case.
794 if (object->IsUndefined() || object->IsNull()) { 498 if (object->IsUndefined() || object->IsNull()) {
795 return TypeError("non_object_property_load", object, name); 499 return TypeError("non_object_property_load", object, name);
796 } 500 }
797 501
798 if (FLAG_use_ic) { 502 if (FLAG_use_ic) {
799 // Use specialized code for getting the length of strings and 503 // Use specialized code for getting the length of strings and
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 // Get the property. 577 // Get the property.
874 Handle<Object> result = 578 Handle<Object> result =
875 Object::GetProperty(object, object, &lookup, name, &attr); 579 Object::GetProperty(object, object, &lookup, name, &attr);
876 RETURN_IF_EMPTY_HANDLE(isolate(), result); 580 RETURN_IF_EMPTY_HANDLE(isolate(), result);
877 // If the property is not present, check if we need to throw an 581 // If the property is not present, check if we need to throw an
878 // exception. 582 // exception.
879 if ((lookup.IsInterceptor() || lookup.IsHandler()) && 583 if ((lookup.IsInterceptor() || lookup.IsHandler()) &&
880 attr == ABSENT && IsUndeclaredGlobal(object)) { 584 attr == ABSENT && IsUndeclaredGlobal(object)) {
881 return ReferenceError("not_defined", name); 585 return ReferenceError("not_defined", name);
882 } 586 }
587
883 return *result; 588 return *result;
884 } 589 }
885 590
886 591
887 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 592 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
888 Handle<Map> new_receiver_map) { 593 Handle<Map> new_receiver_map) {
889 ASSERT(!new_receiver_map.is_null()); 594 ASSERT(!new_receiver_map.is_null());
890 for (int current = 0; current < receiver_maps->length(); ++current) { 595 for (int current = 0; current < receiver_maps->length(); ++current) {
891 if (!receiver_maps->at(current).is_null() && 596 if (!receiver_maps->at(current).is_null() &&
892 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 597 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 Handle<Code> code) { 725 Handle<Code> code) {
1021 switch (state()) { 726 switch (state()) {
1022 case UNINITIALIZED: 727 case UNINITIALIZED:
1023 case PREMONOMORPHIC: 728 case PREMONOMORPHIC:
1024 case MONOMORPHIC_PROTOTYPE_FAILURE: 729 case MONOMORPHIC_PROTOTYPE_FAILURE:
1025 UpdateMonomorphicIC(type, code, name); 730 UpdateMonomorphicIC(type, code, name);
1026 break; 731 break;
1027 case MONOMORPHIC: { 732 case MONOMORPHIC: {
1028 // For now, call stubs are allowed to rewrite to the same stub. This 733 // For now, call stubs are allowed to rewrite to the same stub. This
1029 // happens e.g., when the field does not contain a function. 734 // happens e.g., when the field does not contain a function.
1030 ASSERT(target()->is_call_stub() || 735 ASSERT(!target().is_identical_to(code));
1031 target()->is_keyed_call_stub() ||
1032 !target().is_identical_to(code));
1033 Code* old_handler = target()->FindFirstHandler(); 736 Code* old_handler = target()->FindFirstHandler();
1034 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { 737 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
1035 UpdateMonomorphicIC(type, code, name); 738 UpdateMonomorphicIC(type, code, name);
1036 break; 739 break;
1037 } 740 }
1038 // Fall through. 741 // Fall through.
1039 } 742 }
1040 case POLYMORPHIC: 743 case POLYMORPHIC:
1041 if (!target()->is_keyed_stub()) { 744 if (!target()->is_keyed_stub()) {
1042 if (UpdatePolymorphicIC(type, name, code)) break; 745 if (UpdatePolymorphicIC(type, name, code)) break;
1043 CopyICToMegamorphicCache(name); 746 CopyICToMegamorphicCache(name);
1044 } 747 }
1045 set_target(*megamorphic_stub()); 748 set_target(*megamorphic_stub());
1046 // Fall through. 749 // Fall through.
1047 case MEGAMORPHIC: 750 case MEGAMORPHIC:
1048 UpdateMegamorphicCache(*type, *name, *code); 751 UpdateMegamorphicCache(*type, *name, *code);
1049 break; 752 break;
1050 case DEBUG_STUB: 753 case DEBUG_STUB:
1051 break; 754 break;
1052 case GENERIC: 755 case GENERIC:
1053 UNREACHABLE(); 756 UNREACHABLE();
1054 break; 757 break;
1055 } 758 }
1056 } 759 }
1057 760
1058 761
1059 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { 762 Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
1060 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( 763 ExtraICState extra_state) {
1061 UNINITIALIZED, ComputeExtraICState(mode)); 764 return isolate->stub_cache()->ComputeLoad(UNINITIALIZED, extra_state);
1062 return ic;
1063 } 765 }
1064 766
1065 767
1066 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 768 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1067 ContextualMode mode) { 769 ExtraICState extra_state) {
1068 return isolate->stub_cache()->ComputeLoad( 770 return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, extra_state);
1069 PREMONOMORPHIC, ComputeExtraICState(mode));
1070 } 771 }
1071 772
1072 773
1073 Handle<Code> LoadIC::megamorphic_stub() { 774 Handle<Code> LoadIC::megamorphic_stub() {
1074 return isolate()->stub_cache()->ComputeLoad( 775 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state());
1075 MEGAMORPHIC, extra_ic_state());
1076 } 776 }
1077 777
1078 778
1079 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 779 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
1080 bool inobject, 780 bool inobject,
1081 Representation representation) { 781 Representation representation) {
1082 if (kind() == Code::LOAD_IC) { 782 if (kind() == Code::LOAD_IC) {
1083 LoadFieldStub stub(inobject, offset, representation); 783 LoadFieldStub stub(inobject, offset, representation);
1084 return stub.GetCode(isolate()); 784 return stub.GetCode(isolate());
1085 } else { 785 } else {
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 1718
2019 1719
2020 #undef TRACE_IC 1720 #undef TRACE_IC
2021 1721
2022 1722
2023 // ---------------------------------------------------------------------------- 1723 // ----------------------------------------------------------------------------
2024 // Static IC stub generators. 1724 // Static IC stub generators.
2025 // 1725 //
2026 1726
2027 // Used from ic-<arch>.cc. 1727 // Used from ic-<arch>.cc.
2028 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
2029 HandleScope scope(isolate);
2030 ASSERT(args.length() == 2);
2031 CallIC ic(isolate);
2032 Handle<Object> receiver = args.at<Object>(0);
2033 Handle<String> key = args.at<String>(1);
2034 ic.UpdateState(receiver, key);
2035 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2036 JSFunction* raw_function;
2037 if (!maybe_result->To(&raw_function)) return maybe_result;
2038
2039 // The first time the inline cache is updated may be the first time the
2040 // function it references gets called. If the function is lazily compiled
2041 // then the first call will trigger a compilation. We check for this case
2042 // and we do the compilation immediately, instead of waiting for the stub
2043 // currently attached to the JSFunction object to trigger compilation.
2044 if (raw_function->is_compiled()) return raw_function;
2045
2046 Handle<JSFunction> function(raw_function);
2047 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2048 return *function;
2049 }
2050
2051
2052 // Used from ic-<arch>.cc.
2053 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
2054 HandleScope scope(isolate);
2055 ASSERT(args.length() == 2);
2056 KeyedCallIC ic(isolate);
2057 Handle<Object> receiver = args.at<Object>(0);
2058 Handle<Object> key = args.at<Object>(1);
2059 ic.UpdateState(receiver, key);
2060 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2061 // Result could be a function or a failure.
2062 JSFunction* raw_function = NULL;
2063 if (!maybe_result->To(&raw_function)) return maybe_result;
2064
2065 if (raw_function->is_compiled()) return raw_function;
2066
2067 Handle<JSFunction> function(raw_function, isolate);
2068 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2069 return *function;
2070 }
2071
2072
2073 // Used from ic-<arch>.cc. 1728 // Used from ic-<arch>.cc.
2074 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { 1729 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
2075 HandleScope scope(isolate); 1730 HandleScope scope(isolate);
2076 ASSERT(args.length() == 2); 1731 ASSERT(args.length() == 2);
2077 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 1732 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2078 Handle<Object> receiver = args.at<Object>(0); 1733 Handle<Object> receiver = args.at<Object>(0);
2079 Handle<String> key = args.at<String>(1); 1734 Handle<String> key = args.at<String>(1);
2080 ic.UpdateState(receiver, key); 1735 ic.UpdateState(receiver, key);
2081 return ic.Load(receiver, key); 1736 return ic.Load(receiver, key);
2082 } 1737 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 HandleScope scope(isolate); 1776 HandleScope scope(isolate);
2122 ASSERT(args.length() == 3); 1777 ASSERT(args.length() == 3);
2123 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 1778 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2124 Handle<Object> receiver = args.at<Object>(0); 1779 Handle<Object> receiver = args.at<Object>(0);
2125 Handle<String> key = args.at<String>(1); 1780 Handle<String> key = args.at<String>(1);
2126 ic.UpdateState(receiver, key); 1781 ic.UpdateState(receiver, key);
2127 return ic.Store(receiver, key, args.at<Object>(2)); 1782 return ic.Store(receiver, key, args.at<Object>(2));
2128 } 1783 }
2129 1784
2130 1785
2131 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) {
2132 HandleScope scope(isolate);
2133 ASSERT(args.length() == 2);
2134 KeyedCallIC ic(isolate);
2135 Arguments* caller_args = reinterpret_cast<Arguments*>(args[0]);
2136 Handle<Object> key = args.at<Object>(1);
2137 Handle<Object> receiver((*caller_args)[0], isolate);
2138
2139 ic.UpdateState(receiver, key);
2140 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2141 // Result could be a function or a failure.
2142 JSFunction* raw_function = NULL;
2143 if (!maybe_result->To(&raw_function)) return maybe_result;
2144
2145 if (raw_function->is_compiled()) return raw_function;
2146
2147 Handle<JSFunction> function(raw_function, isolate);
2148 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2149 return *function;
2150 }
2151
2152
2153 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 1786 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
2154 SealHandleScope shs(isolate); 1787 SealHandleScope shs(isolate);
2155 1788
2156 ASSERT(args.length() == 2); 1789 ASSERT(args.length() == 2);
2157 JSArray* receiver = JSArray::cast(args[0]); 1790 JSArray* receiver = JSArray::cast(args[0]);
2158 Object* len = args[1]; 1791 Object* len = args[1];
2159 1792
2160 // The generated code should filter out non-Smis before we get here. 1793 // The generated code should filter out non-Smis before we get here.
2161 ASSERT(len->IsSmi()); 1794 ASSERT(len->IsSmi());
2162 1795
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
3172 #undef ADDR 2805 #undef ADDR
3173 }; 2806 };
3174 2807
3175 2808
3176 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2809 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3177 return IC_utilities[id]; 2810 return IC_utilities[id];
3178 } 2811 }
3179 2812
3180 2813
3181 } } // namespace v8::internal 2814 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698