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 (Smi::FromInt(object->IsNull() || object->IsUndefined())) { | |
mvstanton
2013/04/23 09:27:30
Do you intend to have Smi::FromInt(... in the if s
danno
2013/04/23 16:14:47
Done.
danno
2013/04/23 16:14:47
Done.
| |
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 |