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

Side by Side Diff: src/ic.cc

Issue 7869009: Remove in-loop tracking for call ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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/objects.h » ('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 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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698