| OLD | NEW |
| 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 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 | 581 |
| 582 if (FLAG_use_ic) { | 582 if (FLAG_use_ic) { |
| 583 // Use specialized code for getting prototype of functions. | 583 // Use specialized code for getting prototype of functions. |
| 584 if (object->IsJSFunction() && | 584 if (object->IsJSFunction() && |
| 585 String::Equals(isolate()->factory()->prototype_string(), name) && | 585 String::Equals(isolate()->factory()->prototype_string(), name) && |
| 586 Handle<JSFunction>::cast(object)->should_have_prototype()) { | 586 Handle<JSFunction>::cast(object)->should_have_prototype()) { |
| 587 Handle<Code> stub; | 587 Handle<Code> stub; |
| 588 if (state() == UNINITIALIZED) { | 588 if (state() == UNINITIALIZED) { |
| 589 stub = pre_monomorphic_stub(); | 589 stub = pre_monomorphic_stub(); |
| 590 } else if (state() == PREMONOMORPHIC) { | 590 } else if (state() == PREMONOMORPHIC) { |
| 591 FunctionPrototypeStub function_prototype_stub(kind()); | 591 FunctionPrototypeStub function_prototype_stub(isolate(), kind()); |
| 592 stub = function_prototype_stub.GetCode(isolate()); | 592 stub = function_prototype_stub.GetCode(isolate()); |
| 593 } else if (state() != MEGAMORPHIC) { | 593 } else if (state() != MEGAMORPHIC) { |
| 594 ASSERT(state() != GENERIC); | 594 ASSERT(state() != GENERIC); |
| 595 stub = megamorphic_stub(); | 595 stub = megamorphic_stub(); |
| 596 } | 596 } |
| 597 if (!stub.is_null()) { | 597 if (!stub.is_null()) { |
| 598 set_target(*stub); | 598 set_target(*stub); |
| 599 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); | 599 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); |
| 600 } | 600 } |
| 601 return Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); | 601 return Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 | 844 |
| 845 Handle<Code> LoadIC::megamorphic_stub() { | 845 Handle<Code> LoadIC::megamorphic_stub() { |
| 846 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state()); | 846 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state()); |
| 847 } | 847 } |
| 848 | 848 |
| 849 | 849 |
| 850 Handle<Code> LoadIC::SimpleFieldLoad(int offset, | 850 Handle<Code> LoadIC::SimpleFieldLoad(int offset, |
| 851 bool inobject, | 851 bool inobject, |
| 852 Representation representation) { | 852 Representation representation) { |
| 853 if (kind() == Code::LOAD_IC) { | 853 if (kind() == Code::LOAD_IC) { |
| 854 LoadFieldStub stub(inobject, offset, representation); | 854 LoadFieldStub stub(isolate(), inobject, offset, representation); |
| 855 return stub.GetCode(isolate()); | 855 return stub.GetCode(isolate()); |
| 856 } else { | 856 } else { |
| 857 KeyedLoadFieldStub stub(inobject, offset, representation); | 857 KeyedLoadFieldStub stub(isolate(), inobject, offset, representation); |
| 858 return stub.GetCode(isolate()); | 858 return stub.GetCode(isolate()); |
| 859 } | 859 } |
| 860 } | 860 } |
| 861 | 861 |
| 862 | 862 |
| 863 void LoadIC::UpdateCaches(LookupResult* lookup, | 863 void LoadIC::UpdateCaches(LookupResult* lookup, |
| 864 Handle<Object> object, | 864 Handle<Object> object, |
| 865 Handle<String> name) { | 865 Handle<String> name) { |
| 866 if (state() == UNINITIALIZED) { | 866 if (state() == UNINITIALIZED) { |
| 867 // This is the first time we execute this inline cache. | 867 // This is the first time we execute this inline cache. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 InlineCacheHolderFlag cache_holder) { | 933 InlineCacheHolderFlag cache_holder) { |
| 934 if (object->IsString() && | 934 if (object->IsString() && |
| 935 String::Equals(isolate()->factory()->length_string(), name)) { | 935 String::Equals(isolate()->factory()->length_string(), name)) { |
| 936 int length_index = String::kLengthOffset / kPointerSize; | 936 int length_index = String::kLengthOffset / kPointerSize; |
| 937 return SimpleFieldLoad(length_index); | 937 return SimpleFieldLoad(length_index); |
| 938 } | 938 } |
| 939 | 939 |
| 940 if (object->IsStringWrapper() && | 940 if (object->IsStringWrapper() && |
| 941 String::Equals(isolate()->factory()->length_string(), name)) { | 941 String::Equals(isolate()->factory()->length_string(), name)) { |
| 942 if (kind() == Code::LOAD_IC) { | 942 if (kind() == Code::LOAD_IC) { |
| 943 StringLengthStub string_length_stub; | 943 StringLengthStub string_length_stub(isolate()); |
| 944 return string_length_stub.GetCode(isolate()); | 944 return string_length_stub.GetCode(isolate()); |
| 945 } else { | 945 } else { |
| 946 KeyedStringLengthStub string_length_stub; | 946 KeyedStringLengthStub string_length_stub(isolate()); |
| 947 return string_length_stub.GetCode(isolate()); | 947 return string_length_stub.GetCode(isolate()); |
| 948 } | 948 } |
| 949 } | 949 } |
| 950 | 950 |
| 951 Handle<HeapType> type = CurrentTypeOf(object, isolate()); | 951 Handle<HeapType> type = CurrentTypeOf(object, isolate()); |
| 952 Handle<JSObject> holder(lookup->holder()); | 952 Handle<JSObject> holder(lookup->holder()); |
| 953 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); | 953 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); |
| 954 | 954 |
| 955 switch (lookup->type()) { | 955 switch (lookup->type()) { |
| 956 case FIELD: { | 956 case FIELD: { |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) { | 1417 if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) { |
| 1418 // The stub generated for the global object picks the value directly | 1418 // The stub generated for the global object picks the value directly |
| 1419 // from the property cell. So the property must be directly on the | 1419 // from the property cell. So the property must be directly on the |
| 1420 // global object. | 1420 // global object. |
| 1421 Handle<GlobalObject> global = receiver->IsJSGlobalProxy() | 1421 Handle<GlobalObject> global = receiver->IsJSGlobalProxy() |
| 1422 ? handle(GlobalObject::cast(receiver->GetPrototype())) | 1422 ? handle(GlobalObject::cast(receiver->GetPrototype())) |
| 1423 : Handle<GlobalObject>::cast(receiver); | 1423 : Handle<GlobalObject>::cast(receiver); |
| 1424 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); | 1424 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); |
| 1425 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); | 1425 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); |
| 1426 StoreGlobalStub stub( | 1426 StoreGlobalStub stub( |
| 1427 union_type->IsConstant(), receiver->IsJSGlobalProxy()); | 1427 isolate(), union_type->IsConstant(), receiver->IsJSGlobalProxy()); |
| 1428 Handle<Code> code = stub.GetCodeCopyFromTemplate( | 1428 Handle<Code> code = stub.GetCodeCopyFromTemplate( |
| 1429 isolate(), global, cell); | 1429 isolate(), global, cell); |
| 1430 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1430 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1431 HeapObject::UpdateMapCodeCache(receiver, name, code); | 1431 HeapObject::UpdateMapCodeCache(receiver, name, code); |
| 1432 return code; | 1432 return code; |
| 1433 } | 1433 } |
| 1434 ASSERT(holder.is_identical_to(receiver)); | 1434 ASSERT(holder.is_identical_to(receiver)); |
| 1435 return isolate()->builtins()->StoreIC_Normal(); | 1435 return isolate()->builtins()->StoreIC_Normal(); |
| 1436 case CALLBACKS: { | 1436 case CALLBACKS: { |
| 1437 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1437 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
| (...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2505 | 2505 |
| 2506 // Check if we have a string operation here. | 2506 // Check if we have a string operation here. |
| 2507 Handle<Code> target; | 2507 Handle<Code> target; |
| 2508 if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) { | 2508 if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) { |
| 2509 // Setup the allocation site on-demand. | 2509 // Setup the allocation site on-demand. |
| 2510 if (allocation_site.is_null()) { | 2510 if (allocation_site.is_null()) { |
| 2511 allocation_site = isolate()->factory()->NewAllocationSite(); | 2511 allocation_site = isolate()->factory()->NewAllocationSite(); |
| 2512 } | 2512 } |
| 2513 | 2513 |
| 2514 // Install the stub with an allocation site. | 2514 // Install the stub with an allocation site. |
| 2515 BinaryOpICWithAllocationSiteStub stub(state); | 2515 BinaryOpICWithAllocationSiteStub stub(isolate(), state); |
| 2516 target = stub.GetCodeCopyFromTemplate(isolate(), allocation_site); | 2516 target = stub.GetCodeCopyFromTemplate(isolate(), allocation_site); |
| 2517 | 2517 |
| 2518 // Sanity check the trampoline stub. | 2518 // Sanity check the trampoline stub. |
| 2519 ASSERT_EQ(*allocation_site, target->FindFirstAllocationSite()); | 2519 ASSERT_EQ(*allocation_site, target->FindFirstAllocationSite()); |
| 2520 } else { | 2520 } else { |
| 2521 // Install the generic stub. | 2521 // Install the generic stub. |
| 2522 BinaryOpICStub stub(state); | 2522 BinaryOpICStub stub(isolate(), state); |
| 2523 target = stub.GetCode(isolate()); | 2523 target = stub.GetCode(isolate()); |
| 2524 | 2524 |
| 2525 // Sanity check the generic stub. | 2525 // Sanity check the generic stub. |
| 2526 ASSERT_EQ(NULL, target->FindFirstAllocationSite()); | 2526 ASSERT_EQ(NULL, target->FindFirstAllocationSite()); |
| 2527 } | 2527 } |
| 2528 set_target(*target); | 2528 set_target(*target); |
| 2529 | 2529 |
| 2530 if (FLAG_trace_ic) { | 2530 if (FLAG_trace_ic) { |
| 2531 char buffer[150]; | 2531 char buffer[150]; |
| 2532 NoAllocationStringAllocator allocator( | 2532 NoAllocationStringAllocator allocator( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2584 Handle<Object> result; | 2584 Handle<Object> result; |
| 2585 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2585 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 2586 isolate, | 2586 isolate, |
| 2587 result, | 2587 result, |
| 2588 ic.Transition(allocation_site, left, right)); | 2588 ic.Transition(allocation_site, left, right)); |
| 2589 return *result; | 2589 return *result; |
| 2590 } | 2590 } |
| 2591 | 2591 |
| 2592 | 2592 |
| 2593 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { | 2593 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { |
| 2594 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2594 ICCompareStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
| 2595 Code* code = NULL; | 2595 Code* code = NULL; |
| 2596 CHECK(stub.FindCodeInCache(&code, isolate)); | 2596 CHECK(stub.FindCodeInCache(&code, isolate)); |
| 2597 return code; | 2597 return code; |
| 2598 } | 2598 } |
| 2599 | 2599 |
| 2600 | 2600 |
| 2601 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { | 2601 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { |
| 2602 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2602 ICCompareStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
| 2603 return stub.GetCode(isolate); | 2603 return stub.GetCode(isolate); |
| 2604 } | 2604 } |
| 2605 | 2605 |
| 2606 | 2606 |
| 2607 const char* CompareIC::GetStateName(State state) { | 2607 const char* CompareIC::GetStateName(State state) { |
| 2608 switch (state) { | 2608 switch (state) { |
| 2609 case UNINITIALIZED: return "UNINITIALIZED"; | 2609 case UNINITIALIZED: return "UNINITIALIZED"; |
| 2610 case SMI: return "SMI"; | 2610 case SMI: return "SMI"; |
| 2611 case NUMBER: return "NUMBER"; | 2611 case NUMBER: return "NUMBER"; |
| 2612 case INTERNALIZED_STRING: return "INTERNALIZED_STRING"; | 2612 case INTERNALIZED_STRING: return "INTERNALIZED_STRING"; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 | 2765 |
| 2766 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { | 2766 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
| 2767 HandleScope scope(isolate()); | 2767 HandleScope scope(isolate()); |
| 2768 State previous_left, previous_right, previous_state; | 2768 State previous_left, previous_right, previous_state; |
| 2769 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, | 2769 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, |
| 2770 &previous_right, &previous_state, NULL); | 2770 &previous_right, &previous_state, NULL); |
| 2771 State new_left = NewInputState(previous_left, x); | 2771 State new_left = NewInputState(previous_left, x); |
| 2772 State new_right = NewInputState(previous_right, y); | 2772 State new_right = NewInputState(previous_right, y); |
| 2773 State state = TargetState(previous_state, previous_left, previous_right, | 2773 State state = TargetState(previous_state, previous_left, previous_right, |
| 2774 HasInlinedSmiCode(address()), x, y); | 2774 HasInlinedSmiCode(address()), x, y); |
| 2775 ICCompareStub stub(op_, new_left, new_right, state); | 2775 ICCompareStub stub(isolate(), op_, new_left, new_right, state); |
| 2776 if (state == KNOWN_OBJECT) { | 2776 if (state == KNOWN_OBJECT) { |
| 2777 stub.set_known_map( | 2777 stub.set_known_map( |
| 2778 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); | 2778 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); |
| 2779 } | 2779 } |
| 2780 Handle<Code> new_target = stub.GetCode(isolate()); | 2780 Handle<Code> new_target = stub.GetCode(isolate()); |
| 2781 set_target(*new_target); | 2781 set_target(*new_target); |
| 2782 | 2782 |
| 2783 if (FLAG_trace_ic) { | 2783 if (FLAG_trace_ic) { |
| 2784 PrintF("[CompareIC in "); | 2784 PrintF("[CompareIC in "); |
| 2785 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); | 2785 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2811 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2811 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
| 2812 } | 2812 } |
| 2813 | 2813 |
| 2814 | 2814 |
| 2815 void CompareNilIC::Clear(Address address, | 2815 void CompareNilIC::Clear(Address address, |
| 2816 Code* target, | 2816 Code* target, |
| 2817 ConstantPoolArray* constant_pool) { | 2817 ConstantPoolArray* constant_pool) { |
| 2818 if (IsCleared(target)) return; | 2818 if (IsCleared(target)) return; |
| 2819 ExtraICState state = target->extra_ic_state(); | 2819 ExtraICState state = target->extra_ic_state(); |
| 2820 | 2820 |
| 2821 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); | 2821 CompareNilICStub stub(target->GetIsolate(), |
| 2822 state, |
| 2823 HydrogenCodeStub::UNINITIALIZED); |
| 2822 stub.ClearState(); | 2824 stub.ClearState(); |
| 2823 | 2825 |
| 2824 Code* code = NULL; | 2826 Code* code = NULL; |
| 2825 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); | 2827 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); |
| 2826 | 2828 |
| 2827 SetTargetAtAddress(address, code, constant_pool); | 2829 SetTargetAtAddress(address, code, constant_pool); |
| 2828 } | 2830 } |
| 2829 | 2831 |
| 2830 | 2832 |
| 2831 Handle<Object> CompareNilIC::DoCompareNilSlow(Isolate* isolate, | 2833 Handle<Object> CompareNilIC::DoCompareNilSlow(Isolate* isolate, |
| 2832 NilValue nil, | 2834 NilValue nil, |
| 2833 Handle<Object> object) { | 2835 Handle<Object> object) { |
| 2834 if (object->IsNull() || object->IsUndefined()) { | 2836 if (object->IsNull() || object->IsUndefined()) { |
| 2835 return handle(Smi::FromInt(true), isolate); | 2837 return handle(Smi::FromInt(true), isolate); |
| 2836 } | 2838 } |
| 2837 return handle(Smi::FromInt(object->IsUndetectableObject()), isolate); | 2839 return handle(Smi::FromInt(object->IsUndetectableObject()), isolate); |
| 2838 } | 2840 } |
| 2839 | 2841 |
| 2840 | 2842 |
| 2841 Handle<Object> CompareNilIC::CompareNil(Handle<Object> object) { | 2843 Handle<Object> CompareNilIC::CompareNil(Handle<Object> object) { |
| 2842 ExtraICState extra_ic_state = target()->extra_ic_state(); | 2844 ExtraICState extra_ic_state = target()->extra_ic_state(); |
| 2843 | 2845 |
| 2844 CompareNilICStub stub(extra_ic_state); | 2846 CompareNilICStub stub(isolate(), extra_ic_state); |
| 2845 | 2847 |
| 2846 // Extract the current supported types from the patched IC and calculate what | 2848 // Extract the current supported types from the patched IC and calculate what |
| 2847 // types must be supported as a result of the miss. | 2849 // types must be supported as a result of the miss. |
| 2848 bool already_monomorphic = stub.IsMonomorphic(); | 2850 bool already_monomorphic = stub.IsMonomorphic(); |
| 2849 | 2851 |
| 2850 stub.UpdateStatus(object); | 2852 stub.UpdateStatus(object); |
| 2851 | 2853 |
| 2852 NilValue nil = stub.GetNilValue(); | 2854 NilValue nil = stub.GetNilValue(); |
| 2853 | 2855 |
| 2854 // Find or create the specialized stub to support the new set of types. | 2856 // Find or create the specialized stub to support the new set of types. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2916 return Builtins::SHR; | 2918 return Builtins::SHR; |
| 2917 break; | 2919 break; |
| 2918 case Token::SHL: | 2920 case Token::SHL: |
| 2919 return Builtins::SHL; | 2921 return Builtins::SHL; |
| 2920 break; | 2922 break; |
| 2921 } | 2923 } |
| 2922 } | 2924 } |
| 2923 | 2925 |
| 2924 | 2926 |
| 2925 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { | 2927 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { |
| 2926 ToBooleanStub stub(target()->extra_ic_state()); | 2928 ToBooleanStub stub(isolate(), target()->extra_ic_state()); |
| 2927 bool to_boolean_value = stub.UpdateStatus(object); | 2929 bool to_boolean_value = stub.UpdateStatus(object); |
| 2928 Handle<Code> code = stub.GetCode(isolate()); | 2930 Handle<Code> code = stub.GetCode(isolate()); |
| 2929 set_target(*code); | 2931 set_target(*code); |
| 2930 return handle(Smi::FromInt(to_boolean_value ? 1 : 0), isolate()); | 2932 return handle(Smi::FromInt(to_boolean_value ? 1 : 0), isolate()); |
| 2931 } | 2933 } |
| 2932 | 2934 |
| 2933 | 2935 |
| 2934 RUNTIME_FUNCTION(ToBooleanIC_Miss) { | 2936 RUNTIME_FUNCTION(ToBooleanIC_Miss) { |
| 2935 ASSERT(args.length() == 1); | 2937 ASSERT(args.length() == 1); |
| 2936 HandleScope scope(isolate); | 2938 HandleScope scope(isolate); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2947 #undef ADDR | 2949 #undef ADDR |
| 2948 }; | 2950 }; |
| 2949 | 2951 |
| 2950 | 2952 |
| 2951 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2953 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2952 return IC_utilities[id]; | 2954 return IC_utilities[id]; |
| 2953 } | 2955 } |
| 2954 | 2956 |
| 2955 | 2957 |
| 2956 } } // namespace v8::internal | 2958 } } // namespace v8::internal |
| OLD | NEW |