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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 if (target->is_debug_break()) return; | 340 if (target->is_debug_break()) return; |
341 | 341 |
342 switch (target->kind()) { | 342 switch (target->kind()) { |
343 case Code::LOAD_IC: return LoadIC::Clear(address, target); | 343 case Code::LOAD_IC: return LoadIC::Clear(address, target); |
344 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target); | 344 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target); |
345 case Code::STORE_IC: return StoreIC::Clear(address, target); | 345 case Code::STORE_IC: return StoreIC::Clear(address, target); |
346 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target); | 346 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target); |
347 case Code::CALL_IC: return CallIC::Clear(address, target); | 347 case Code::CALL_IC: return CallIC::Clear(address, target); |
348 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); | 348 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); |
349 case Code::COMPARE_IC: return CompareIC::Clear(address, target); | 349 case Code::COMPARE_IC: return CompareIC::Clear(address, target); |
| 350 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); |
350 case Code::UNARY_OP_IC: | 351 case Code::UNARY_OP_IC: |
351 case Code::BINARY_OP_IC: | 352 case Code::BINARY_OP_IC: |
352 case Code::TO_BOOLEAN_IC: | 353 case Code::TO_BOOLEAN_IC: |
353 // Clearing these is tricky and does not | 354 // Clearing these is tricky and does not |
354 // make any performance difference. | 355 // make any performance difference. |
355 return; | 356 return; |
356 default: UNREACHABLE(); | 357 default: UNREACHABLE(); |
357 } | 358 } |
358 } | 359 } |
359 | 360 |
(...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2763 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. | 2764 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. |
2764 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { | 2765 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { |
2765 NoHandleAllocation na(isolate); | 2766 NoHandleAllocation na(isolate); |
2766 ASSERT(args.length() == 3); | 2767 ASSERT(args.length() == 3); |
2767 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2768 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2768 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2769 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2769 return ic.target(); | 2770 return ic.target(); |
2770 } | 2771 } |
2771 | 2772 |
2772 | 2773 |
| 2774 Code* CompareNilIC::GetRawUninitialized(EqualityKind kind, |
| 2775 NilValue nil) { |
| 2776 CompareNilICStub stub(kind, nil); |
| 2777 Code* code = NULL; |
| 2778 CHECK(stub.FindCodeInCache(&code, Isolate::Current())); |
| 2779 return code; |
| 2780 } |
| 2781 |
| 2782 |
| 2783 void CompareNilIC::Clear(Address address, Code* target) { |
| 2784 if (target->ic_state() == UNINITIALIZED) return; |
| 2785 Code::ExtraICState state = target->extended_extra_ic_state(); |
| 2786 |
| 2787 EqualityKind kind = |
| 2788 CompareNilICStub::EqualityKindFromExtraICState(state); |
| 2789 NilValue nil = |
| 2790 CompareNilICStub::NilValueFromExtraICState(state); |
| 2791 |
| 2792 SetTargetAtAddress(address, GetRawUninitialized(kind, nil)); |
| 2793 } |
| 2794 |
| 2795 |
| 2796 MaybeObject* CompareNilIC::DoCompareNilSlow(EqualityKind kind, |
| 2797 NilValue nil, |
| 2798 Handle<Object> object) { |
| 2799 if (kind == kStrictEquality) { |
| 2800 if (nil == kNullValue) { |
| 2801 return Smi::FromInt(object->IsNull()); |
| 2802 } else { |
| 2803 return Smi::FromInt(object->IsUndefined()); |
| 2804 } |
| 2805 } |
| 2806 if (object->IsNull() || object->IsUndefined()) { |
| 2807 return Smi::FromInt(true); |
| 2808 } |
| 2809 return Smi::FromInt(object->IsUndetectableObject()); |
| 2810 } |
| 2811 |
| 2812 |
| 2813 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
| 2814 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
| 2815 |
| 2816 // Extract the current supported types from the patched IC and calculate what |
| 2817 // types must be supported as a result of the miss. |
| 2818 bool already_monomorphic; |
| 2819 CompareNilICStub::Types types = |
| 2820 CompareNilICStub::GetPatchedICFlags(extra_ic_state, |
| 2821 object, &already_monomorphic); |
| 2822 |
| 2823 EqualityKind kind = |
| 2824 CompareNilICStub::EqualityKindFromExtraICState(extra_ic_state); |
| 2825 NilValue nil = |
| 2826 CompareNilICStub::NilValueFromExtraICState(extra_ic_state); |
| 2827 |
| 2828 // Find or create the specialized stub to support the new set of types. |
| 2829 CompareNilICStub stub(kind, nil, types); |
| 2830 Handle<Code> code; |
| 2831 if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) { |
| 2832 Handle<Map> monomorphic_map(already_monomorphic |
| 2833 ? target()->FindFirstMap() |
| 2834 : HeapObject::cast(*object)->map()); |
| 2835 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, |
| 2836 nil, |
| 2837 stub.GetTypes()); |
| 2838 } else { |
| 2839 code = stub.GetCode(isolate()); |
| 2840 } |
| 2841 |
| 2842 patch(*code); |
| 2843 |
| 2844 return DoCompareNilSlow(kind, nil, object); |
| 2845 } |
| 2846 |
| 2847 |
| 2848 void CompareNilIC::patch(Code* code) { |
| 2849 set_target(code); |
| 2850 } |
| 2851 |
| 2852 |
| 2853 RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) { |
| 2854 HandleScope scope(isolate); |
| 2855 Handle<Object> object = args.at<Object>(0); |
| 2856 CompareNilIC ic(isolate); |
| 2857 return ic.CompareNil(object); |
| 2858 } |
| 2859 |
| 2860 |
2773 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { | 2861 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { |
2774 UNREACHABLE(); | 2862 UNREACHABLE(); |
2775 CHECK(false); | 2863 CHECK(false); |
2776 return isolate->heap()->undefined_value(); | 2864 return isolate->heap()->undefined_value(); |
2777 } | 2865 } |
2778 | 2866 |
2779 | 2867 |
2780 RUNTIME_FUNCTION(MaybeObject*, ToBoolean_Patch) { | 2868 RUNTIME_FUNCTION(MaybeObject*, ToBoolean_Patch) { |
2781 ASSERT(args.length() == 3); | 2869 ASSERT(args.length() == 3); |
2782 | 2870 |
(...skipping 26 matching lines...) Expand all Loading... |
2809 #undef ADDR | 2897 #undef ADDR |
2810 }; | 2898 }; |
2811 | 2899 |
2812 | 2900 |
2813 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2901 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2814 return IC_utilities[id]; | 2902 return IC_utilities[id]; |
2815 } | 2903 } |
2816 | 2904 |
2817 | 2905 |
2818 } } // namespace v8::internal | 2906 } } // namespace v8::internal |
OLD | NEW |