OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 case DEBUG_BREAK: break; | 54 case DEBUG_BREAK: break; |
55 case DEBUG_PREPARE_STEP_IN: break; | 55 case DEBUG_PREPARE_STEP_IN: break; |
56 } | 56 } |
57 UNREACHABLE(); | 57 UNREACHABLE(); |
58 return 0; | 58 return 0; |
59 } | 59 } |
60 | 60 |
61 void IC::TraceIC(const char* type, | 61 void IC::TraceIC(const char* type, |
62 Handle<Object> name, | 62 Handle<Object> name, |
63 State old_state, | 63 State old_state, |
64 Code* new_target, | 64 Code* new_target) { |
65 const char* extra_info) { | |
66 if (FLAG_trace_ic) { | 65 if (FLAG_trace_ic) { |
67 State new_state = StateFrom(new_target, | 66 State new_state = StateFrom(new_target, |
68 HEAP->undefined_value(), | 67 HEAP->undefined_value(), |
69 HEAP->undefined_value()); | 68 HEAP->undefined_value()); |
70 PrintF("[%s in ", type); | 69 PrintF("[%s in ", type); |
71 StackFrameIterator it; | 70 StackFrameIterator it; |
72 while (it.frame()->fp() != this->fp()) it.Advance(); | 71 while (it.frame()->fp() != this->fp()) it.Advance(); |
73 StackFrame* raw_frame = it.frame(); | 72 StackFrame* raw_frame = it.frame(); |
74 if (raw_frame->is_internal()) { | 73 if (raw_frame->is_internal()) { |
75 Isolate* isolate = new_target->GetIsolate(); | 74 Isolate* isolate = new_target->GetIsolate(); |
(...skipping 11 matching lines...) Expand all Loading... |
87 // Find the function on the stack and both the active code for the | 86 // Find the function on the stack and both the active code for the |
88 // function and the original code. | 87 // function and the original code. |
89 JSFunction* function = JSFunction::cast(frame->function()); | 88 JSFunction* function = JSFunction::cast(frame->function()); |
90 function->PrintName(); | 89 function->PrintName(); |
91 int code_offset = | 90 int code_offset = |
92 static_cast<int>(address() - js_code->instruction_start()); | 91 static_cast<int>(address() - js_code->instruction_start()); |
93 PrintF("+%d", code_offset); | 92 PrintF("+%d", code_offset); |
94 } else { | 93 } else { |
95 PrintF("<unknown>"); | 94 PrintF("<unknown>"); |
96 } | 95 } |
97 PrintF(" (%c->%c)%s", | 96 PrintF(" (%c->%c)", |
98 TransitionMarkFromState(old_state), | 97 TransitionMarkFromState(old_state), |
99 TransitionMarkFromState(new_state), | 98 TransitionMarkFromState(new_state)); |
100 extra_info); | |
101 name->Print(); | 99 name->Print(); |
102 PrintF("]\n"); | 100 PrintF("]\n"); |
103 } | 101 } |
104 } | 102 } |
105 #endif | 103 #endif |
106 | 104 |
107 | 105 |
108 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { | 106 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { |
109 ASSERT(isolate == Isolate::Current()); | 107 ASSERT(isolate == Isolate::Current()); |
110 // To improve the performance of the (much used) IC code, we unfold | 108 // To improve the performance of the (much used) IC code, we unfold |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 } | 317 } |
320 | 318 |
321 | 319 |
322 void CallICBase::Clear(Address address, Code* target) { | 320 void CallICBase::Clear(Address address, Code* target) { |
323 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); | 321 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); |
324 State state = target->ic_state(); | 322 State state = target->ic_state(); |
325 if (state == UNINITIALIZED) return; | 323 if (state == UNINITIALIZED) return; |
326 Code* code = | 324 Code* code = |
327 Isolate::Current()->stub_cache()->FindCallInitialize( | 325 Isolate::Current()->stub_cache()->FindCallInitialize( |
328 target->arguments_count(), | 326 target->arguments_count(), |
329 target->ic_in_loop(), | |
330 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, | 327 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, |
331 target->kind()); | 328 target->kind()); |
332 SetTargetAtAddress(address, code); | 329 SetTargetAtAddress(address, code); |
333 } | 330 } |
334 | 331 |
335 | 332 |
336 void KeyedLoadIC::Clear(Address address, Code* target) { | 333 void KeyedLoadIC::Clear(Address address, Code* target) { |
337 if (target->ic_state() == UNINITIALIZED) return; | 334 if (target->ic_state() == UNINITIALIZED) return; |
338 // Make sure to also clear the map used in inline fast cases. If we | 335 // Make sure to also clear the map used in inline fast cases. If we |
339 // do not clear these maps, cached code can keep objects alive | 336 // do not clear these maps, cached code can keep objects alive |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 } | 594 } |
598 | 595 |
599 | 596 |
600 MaybeObject* CallICBase::ComputeMonomorphicStub( | 597 MaybeObject* CallICBase::ComputeMonomorphicStub( |
601 LookupResult* lookup, | 598 LookupResult* lookup, |
602 State state, | 599 State state, |
603 Code::ExtraICState extra_ic_state, | 600 Code::ExtraICState extra_ic_state, |
604 Handle<Object> object, | 601 Handle<Object> object, |
605 Handle<String> name) { | 602 Handle<String> name) { |
606 int argc = target()->arguments_count(); | 603 int argc = target()->arguments_count(); |
607 InLoopFlag in_loop = target()->ic_in_loop(); | |
608 MaybeObject* maybe_code = NULL; | 604 MaybeObject* maybe_code = NULL; |
609 switch (lookup->type()) { | 605 switch (lookup->type()) { |
610 case FIELD: { | 606 case FIELD: { |
611 int index = lookup->GetFieldIndex(); | 607 int index = lookup->GetFieldIndex(); |
612 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, | 608 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, |
613 in_loop, | |
614 kind_, | 609 kind_, |
615 extra_ic_state, | 610 extra_ic_state, |
616 *name, | 611 *name, |
617 *object, | 612 *object, |
618 lookup->holder(), | 613 lookup->holder(), |
619 index); | 614 index); |
620 break; | 615 break; |
621 } | 616 } |
622 case CONSTANT_FUNCTION: { | 617 case CONSTANT_FUNCTION: { |
623 // Get the constant function and compute the code stub for this | 618 // Get the constant function and compute the code stub for this |
624 // call; used for rewriting to monomorphic state and making sure | 619 // call; used for rewriting to monomorphic state and making sure |
625 // that the code stub is in the stub cache. | 620 // that the code stub is in the stub cache. |
626 JSFunction* function = lookup->GetConstantFunction(); | 621 JSFunction* function = lookup->GetConstantFunction(); |
627 maybe_code = | 622 maybe_code = |
628 isolate()->stub_cache()->ComputeCallConstant(argc, | 623 isolate()->stub_cache()->ComputeCallConstant(argc, |
629 in_loop, | |
630 kind_, | 624 kind_, |
631 extra_ic_state, | 625 extra_ic_state, |
632 *name, | 626 *name, |
633 *object, | 627 *object, |
634 lookup->holder(), | 628 lookup->holder(), |
635 function); | 629 function); |
636 break; | 630 break; |
637 } | 631 } |
638 case NORMAL: { | 632 case NORMAL: { |
639 if (!object->IsJSObject()) return NULL; | 633 if (!object->IsJSObject()) return NULL; |
640 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 634 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
641 | 635 |
642 if (lookup->holder()->IsGlobalObject()) { | 636 if (lookup->holder()->IsGlobalObject()) { |
643 GlobalObject* global = GlobalObject::cast(lookup->holder()); | 637 GlobalObject* global = GlobalObject::cast(lookup->holder()); |
644 JSGlobalPropertyCell* cell = | 638 JSGlobalPropertyCell* cell = |
645 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); | 639 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
646 if (!cell->value()->IsJSFunction()) return NULL; | 640 if (!cell->value()->IsJSFunction()) return NULL; |
647 JSFunction* function = JSFunction::cast(cell->value()); | 641 JSFunction* function = JSFunction::cast(cell->value()); |
648 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, | 642 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, |
649 in_loop, | |
650 kind_, | 643 kind_, |
651 extra_ic_state, | 644 extra_ic_state, |
652 *name, | 645 *name, |
653 *receiver, | 646 *receiver, |
654 global, | 647 global, |
655 cell, | 648 cell, |
656 function); | 649 function); |
657 } else { | 650 } else { |
658 // There is only one shared stub for calling normalized | 651 // There is only one shared stub for calling normalized |
659 // properties. It does not traverse the prototype chain, so the | 652 // properties. It does not traverse the prototype chain, so the |
660 // property must be found in the receiver for the stub to be | 653 // property must be found in the receiver for the stub to be |
661 // applicable. | 654 // applicable. |
662 if (lookup->holder() != *receiver) return NULL; | 655 if (lookup->holder() != *receiver) return NULL; |
663 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, | 656 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, |
664 in_loop, | |
665 kind_, | 657 kind_, |
666 extra_ic_state, | 658 extra_ic_state, |
667 *name, | 659 *name, |
668 *receiver); | 660 *receiver); |
669 } | 661 } |
670 break; | 662 break; |
671 } | 663 } |
672 case INTERCEPTOR: { | 664 case INTERCEPTOR: { |
673 ASSERT(HasInterceptorGetter(lookup->holder())); | 665 ASSERT(HasInterceptorGetter(lookup->holder())); |
674 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( | 666 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( |
(...skipping 24 matching lines...) Expand all Loading... |
699 if (lookup->holder() != *object && | 691 if (lookup->holder() != *object && |
700 HasNormalObjectsInPrototypeChain( | 692 HasNormalObjectsInPrototypeChain( |
701 isolate(), lookup, object->GetPrototype())) { | 693 isolate(), lookup, object->GetPrototype())) { |
702 // Suppress optimization for prototype chains with slow properties objects | 694 // Suppress optimization for prototype chains with slow properties objects |
703 // in the middle. | 695 // in the middle. |
704 return; | 696 return; |
705 } | 697 } |
706 | 698 |
707 // Compute the number of arguments. | 699 // Compute the number of arguments. |
708 int argc = target()->arguments_count(); | 700 int argc = target()->arguments_count(); |
709 InLoopFlag in_loop = target()->ic_in_loop(); | |
710 MaybeObject* maybe_code = NULL; | 701 MaybeObject* maybe_code = NULL; |
711 bool had_proto_failure = false; | 702 bool had_proto_failure = false; |
712 if (state == UNINITIALIZED) { | 703 if (state == UNINITIALIZED) { |
713 // This is the first time we execute this inline cache. | 704 // This is the first time we execute this inline cache. |
714 // Set the target to the pre monomorphic stub to delay | 705 // Set the target to the pre monomorphic stub to delay |
715 // setting the monomorphic state. | 706 // setting the monomorphic state. |
716 maybe_code = | 707 maybe_code = |
717 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, | 708 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, |
718 in_loop, | |
719 kind_, | 709 kind_, |
720 extra_ic_state); | 710 extra_ic_state); |
721 } else if (state == MONOMORPHIC) { | 711 } else if (state == MONOMORPHIC) { |
722 if (kind_ == Code::CALL_IC && | 712 if (kind_ == Code::CALL_IC && |
723 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { | 713 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { |
724 maybe_code = ComputeMonomorphicStub(lookup, | 714 maybe_code = ComputeMonomorphicStub(lookup, |
725 state, | 715 state, |
726 extra_ic_state, | 716 extra_ic_state, |
727 object, | 717 object, |
728 name); | 718 name); |
729 } else if (kind_ == Code::CALL_IC && | 719 } else if (kind_ == Code::CALL_IC && |
730 TryRemoveInvalidPrototypeDependentStub(target(), | 720 TryRemoveInvalidPrototypeDependentStub(target(), |
731 *object, | 721 *object, |
732 *name)) { | 722 *name)) { |
733 had_proto_failure = true; | 723 had_proto_failure = true; |
734 maybe_code = ComputeMonomorphicStub(lookup, | 724 maybe_code = ComputeMonomorphicStub(lookup, |
735 state, | 725 state, |
736 extra_ic_state, | 726 extra_ic_state, |
737 object, | 727 object, |
738 name); | 728 name); |
739 } else { | 729 } else { |
740 maybe_code = | 730 maybe_code = |
741 isolate()->stub_cache()->ComputeCallMegamorphic(argc, | 731 isolate()->stub_cache()->ComputeCallMegamorphic(argc, |
742 in_loop, | |
743 kind_, | 732 kind_, |
744 extra_ic_state); | 733 extra_ic_state); |
745 } | 734 } |
746 } else { | 735 } else { |
747 maybe_code = ComputeMonomorphicStub(lookup, | 736 maybe_code = ComputeMonomorphicStub(lookup, |
748 state, | 737 state, |
749 extra_ic_state, | 738 extra_ic_state, |
750 object, | 739 object, |
751 name); | 740 name); |
752 } | 741 } |
(...skipping 16 matching lines...) Expand all Loading... |
769 object->GetPrototype())->map(); | 758 object->GetPrototype())->map(); |
770 | 759 |
771 // Update the stub cache. | 760 // Update the stub cache. |
772 isolate()->stub_cache()->Set(*name, map, Code::cast(code)); | 761 isolate()->stub_cache()->Set(*name, map, Code::cast(code)); |
773 } | 762 } |
774 | 763 |
775 USE(had_proto_failure); | 764 USE(had_proto_failure); |
776 #ifdef DEBUG | 765 #ifdef DEBUG |
777 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; | 766 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; |
778 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", | 767 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", |
779 name, state, target(), in_loop ? " (in-loop)" : ""); | 768 name, state, target()); |
780 #endif | 769 #endif |
781 } | 770 } |
782 | 771 |
783 | 772 |
784 MaybeObject* KeyedCallIC::LoadFunction(State state, | 773 MaybeObject* KeyedCallIC::LoadFunction(State state, |
785 Handle<Object> object, | 774 Handle<Object> object, |
786 Handle<Object> key) { | 775 Handle<Object> key) { |
787 if (key->IsSymbol()) { | 776 if (key->IsSymbol()) { |
788 return CallICBase::LoadFunction(state, | 777 return CallICBase::LoadFunction(state, |
789 Code::kNoExtraICState, | 778 Code::kNoExtraICState, |
790 object, | 779 object, |
791 Handle<String>::cast(key)); | 780 Handle<String>::cast(key)); |
792 } | 781 } |
793 | 782 |
794 if (object->IsUndefined() || object->IsNull()) { | 783 if (object->IsUndefined() || object->IsNull()) { |
795 return TypeError("non_object_property_call", object, key); | 784 return TypeError("non_object_property_call", object, key); |
796 } | 785 } |
797 | 786 |
798 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { | 787 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { |
799 int argc = target()->arguments_count(); | 788 int argc = target()->arguments_count(); |
800 InLoopFlag in_loop = target()->ic_in_loop(); | |
801 Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); | 789 Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); |
802 Map* map = heap->non_strict_arguments_elements_map(); | 790 Map* map = heap->non_strict_arguments_elements_map(); |
803 if (object->IsJSObject() && | 791 if (object->IsJSObject() && |
804 Handle<JSObject>::cast(object)->elements()->map() == map) { | 792 Handle<JSObject>::cast(object)->elements()->map() == map) { |
805 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( | 793 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( |
806 argc, in_loop, Code::KEYED_CALL_IC); | 794 argc, Code::KEYED_CALL_IC); |
807 Object* code; | 795 Object* code; |
808 if (maybe_code->ToObject(&code)) { | 796 if (maybe_code->ToObject(&code)) { |
809 set_target(Code::cast(code)); | 797 set_target(Code::cast(code)); |
810 #ifdef DEBUG | 798 #ifdef DEBUG |
811 TraceIC( | 799 TraceIC("KeyedCallIC", key, state, target()); |
812 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); | |
813 #endif | 800 #endif |
814 } | 801 } |
815 } else if (FLAG_use_ic && state != MEGAMORPHIC && | 802 } else if (FLAG_use_ic && state != MEGAMORPHIC && |
816 !object->IsAccessCheckNeeded()) { | 803 !object->IsAccessCheckNeeded()) { |
817 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( | 804 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( |
818 argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState); | 805 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
819 Object* code; | 806 Object* code; |
820 if (maybe_code->ToObject(&code)) { | 807 if (maybe_code->ToObject(&code)) { |
821 set_target(Code::cast(code)); | 808 set_target(Code::cast(code)); |
822 #ifdef DEBUG | 809 #ifdef DEBUG |
823 TraceIC( | 810 TraceIC("KeyedCallIC", key, state, target()); |
824 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); | |
825 #endif | 811 #endif |
826 } | 812 } |
827 } | 813 } |
828 } | 814 } |
829 | 815 |
830 HandleScope scope(isolate()); | 816 HandleScope scope(isolate()); |
831 Handle<Object> result = GetProperty(object, key); | 817 Handle<Object> result = GetProperty(object, key); |
832 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 818 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
833 | 819 |
834 // Make receiver an object if the callee requires it. Strict mode or builtin | 820 // Make receiver an object if the callee requires it. Strict mode or builtin |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 } | 1629 } |
1644 | 1630 |
1645 // If the maximum number of receiver maps has been exceeded, use the generic | 1631 // If the maximum number of receiver maps has been exceeded, use the generic |
1646 // version of the IC. | 1632 // version of the IC. |
1647 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { | 1633 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { |
1648 return generic_stub; | 1634 return generic_stub; |
1649 } | 1635 } |
1650 | 1636 |
1651 PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache(); | 1637 PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache(); |
1652 Code::Flags flags = Code::ComputeFlags(this->kind(), | 1638 Code::Flags flags = Code::ComputeFlags(this->kind(), |
1653 NOT_IN_LOOP, | |
1654 MEGAMORPHIC, | 1639 MEGAMORPHIC, |
1655 strict_mode); | 1640 strict_mode); |
1656 Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags); | 1641 Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags); |
1657 // If there is a cached stub, use it. | 1642 // If there is a cached stub, use it. |
1658 if (!maybe_cached_stub->IsUndefined()) { | 1643 if (!maybe_cached_stub->IsUndefined()) { |
1659 ASSERT(maybe_cached_stub->IsCode()); | 1644 ASSERT(maybe_cached_stub->IsCode()); |
1660 return Code::cast(maybe_cached_stub); | 1645 return Code::cast(maybe_cached_stub); |
1661 } | 1646 } |
1662 // Collect MONOMORPHIC stubs for all target_receiver_maps. | 1647 // Collect MONOMORPHIC stubs for all target_receiver_maps. |
1663 CodeList handler_ics(target_receiver_maps.length()); | 1648 CodeList handler_ics(target_receiver_maps.length()); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1898 TraceIC("KeyedStoreIC", name, state, target()); | 1883 TraceIC("KeyedStoreIC", name, state, target()); |
1899 #endif | 1884 #endif |
1900 } | 1885 } |
1901 | 1886 |
1902 | 1887 |
1903 // ---------------------------------------------------------------------------- | 1888 // ---------------------------------------------------------------------------- |
1904 // Static IC stub generators. | 1889 // Static IC stub generators. |
1905 // | 1890 // |
1906 | 1891 |
1907 static JSFunction* CompileFunction(Isolate* isolate, | 1892 static JSFunction* CompileFunction(Isolate* isolate, |
1908 JSFunction* function, | 1893 JSFunction* function) { |
1909 InLoopFlag in_loop) { | |
1910 // Compile now with optimization. | 1894 // Compile now with optimization. |
1911 HandleScope scope(isolate); | 1895 HandleScope scope(isolate); |
1912 Handle<JSFunction> function_handle(function, isolate); | 1896 Handle<JSFunction> function_handle(function, isolate); |
1913 if (in_loop == IN_LOOP) { | 1897 CompileLazy(function_handle, CLEAR_EXCEPTION); |
1914 CompileLazyInLoop(function_handle, CLEAR_EXCEPTION); | |
1915 } else { | |
1916 CompileLazy(function_handle, CLEAR_EXCEPTION); | |
1917 } | |
1918 return *function_handle; | 1898 return *function_handle; |
1919 } | 1899 } |
1920 | 1900 |
1921 | 1901 |
1922 // Used from ic-<arch>.cc. | 1902 // Used from ic-<arch>.cc. |
1923 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { | 1903 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
1924 NoHandleAllocation na; | 1904 NoHandleAllocation na; |
1925 ASSERT(args.length() == 2); | 1905 ASSERT(args.length() == 2); |
1926 CallIC ic(isolate); | 1906 CallIC ic(isolate); |
1927 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1907 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1928 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 1908 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
1929 MaybeObject* maybe_result = ic.LoadFunction(state, | 1909 MaybeObject* maybe_result = ic.LoadFunction(state, |
1930 extra_ic_state, | 1910 extra_ic_state, |
1931 args.at<Object>(0), | 1911 args.at<Object>(0), |
1932 args.at<String>(1)); | 1912 args.at<String>(1)); |
1933 Object* result; | 1913 Object* result; |
1934 if (!maybe_result->ToObject(&result)) return maybe_result; | 1914 if (!maybe_result->ToObject(&result)) return maybe_result; |
1935 | 1915 |
1936 // The first time the inline cache is updated may be the first time the | 1916 // The first time the inline cache is updated may be the first time the |
1937 // function it references gets called. If the function was lazily compiled | 1917 // function it references gets called. If the function was lazily compiled |
1938 // then the first call will trigger a compilation. We check for this case | 1918 // then the first call will trigger a compilation. We check for this case |
1939 // and we do the compilation immediately, instead of waiting for the stub | 1919 // and we do the compilation immediately, instead of waiting for the stub |
1940 // currently attached to the JSFunction object to trigger compilation. We | 1920 // currently attached to the JSFunction object to trigger compilation. We |
1941 // do this in the case where we know that the inline cache is inside a loop, | 1921 // do this in the case where we know that the inline cache is inside a loop, |
1942 // because then we know that we want to optimize the function. | 1922 // because then we know that we want to optimize the function. |
1943 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { | 1923 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { |
1944 return result; | 1924 return result; |
1945 } | 1925 } |
1946 return CompileFunction(isolate, | 1926 return CompileFunction(isolate, JSFunction::cast(result)); |
1947 JSFunction::cast(result), | |
1948 ic.target()->ic_in_loop()); | |
1949 } | 1927 } |
1950 | 1928 |
1951 | 1929 |
1952 // Used from ic-<arch>.cc. | 1930 // Used from ic-<arch>.cc. |
1953 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { | 1931 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { |
1954 NoHandleAllocation na; | 1932 NoHandleAllocation na; |
1955 ASSERT(args.length() == 2); | 1933 ASSERT(args.length() == 2); |
1956 KeyedCallIC ic(isolate); | 1934 KeyedCallIC ic(isolate); |
1957 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1935 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1958 Object* result; | 1936 Object* result; |
1959 { MaybeObject* maybe_result = | 1937 { MaybeObject* maybe_result = |
1960 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); | 1938 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); |
1961 if (!maybe_result->ToObject(&result)) return maybe_result; | 1939 if (!maybe_result->ToObject(&result)) return maybe_result; |
1962 } | 1940 } |
1963 | 1941 |
1964 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { | 1942 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { |
1965 return result; | 1943 return result; |
1966 } | 1944 } |
1967 return CompileFunction(isolate, | 1945 return CompileFunction(isolate, JSFunction::cast(result)); |
1968 JSFunction::cast(result), | |
1969 ic.target()->ic_in_loop()); | |
1970 } | 1946 } |
1971 | 1947 |
1972 | 1948 |
1973 // Used from ic-<arch>.cc. | 1949 // Used from ic-<arch>.cc. |
1974 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { | 1950 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { |
1975 NoHandleAllocation na; | 1951 NoHandleAllocation na; |
1976 ASSERT(args.length() == 2); | 1952 ASSERT(args.length() == 2); |
1977 LoadIC ic(isolate); | 1953 LoadIC ic(isolate); |
1978 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1954 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1979 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); | 1955 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2532 #undef ADDR | 2508 #undef ADDR |
2533 }; | 2509 }; |
2534 | 2510 |
2535 | 2511 |
2536 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2512 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2537 return IC_utilities[id]; | 2513 return IC_utilities[id]; |
2538 } | 2514 } |
2539 | 2515 |
2540 | 2516 |
2541 } } // namespace v8::internal | 2517 } } // namespace v8::internal |
OLD | NEW |