OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ic/ic.h" | 5 #include "src/ic/ic.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 if (target->is_debug_stub()) return; | 458 if (target->is_debug_stub()) return; |
459 | 459 |
460 switch (target->kind()) { | 460 switch (target->kind()) { |
461 case Code::LOAD_IC: | 461 case Code::LOAD_IC: |
462 case Code::KEYED_LOAD_IC: | 462 case Code::KEYED_LOAD_IC: |
463 case Code::STORE_IC: | 463 case Code::STORE_IC: |
464 case Code::KEYED_STORE_IC: | 464 case Code::KEYED_STORE_IC: |
465 return; | 465 return; |
466 case Code::COMPARE_IC: | 466 case Code::COMPARE_IC: |
467 return CompareIC::Clear(isolate, address, target, constant_pool); | 467 return CompareIC::Clear(isolate, address, target, constant_pool); |
| 468 case Code::COMPARE_NIL_IC: |
| 469 return CompareNilIC::Clear(address, target, constant_pool); |
468 case Code::CALL_IC: // CallICs are vector-based and cleared differently. | 470 case Code::CALL_IC: // CallICs are vector-based and cleared differently. |
469 case Code::BINARY_OP_IC: | 471 case Code::BINARY_OP_IC: |
470 case Code::TO_BOOLEAN_IC: | 472 case Code::TO_BOOLEAN_IC: |
471 // Clearing these is tricky and does not | 473 // Clearing these is tricky and does not |
472 // make any performance difference. | 474 // make any performance difference. |
473 return; | 475 return; |
474 default: | 476 default: |
475 UNREACHABLE(); | 477 UNREACHABLE(); |
476 } | 478 } |
477 } | 479 } |
(...skipping 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 RUNTIME_FUNCTION(Runtime_CompareIC_Miss) { | 2707 RUNTIME_FUNCTION(Runtime_CompareIC_Miss) { |
2706 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2708 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2707 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); | 2709 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); |
2708 HandleScope scope(isolate); | 2710 HandleScope scope(isolate); |
2709 DCHECK(args.length() == 3); | 2711 DCHECK(args.length() == 3); |
2710 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2712 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2711 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2713 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2712 } | 2714 } |
2713 | 2715 |
2714 | 2716 |
| 2717 void CompareNilIC::Clear(Address address, Code* target, Address constant_pool) { |
| 2718 if (IsCleared(target)) return; |
| 2719 ExtraICState state = target->extra_ic_state(); |
| 2720 |
| 2721 CompareNilICStub stub(target->GetIsolate(), state, |
| 2722 HydrogenCodeStub::UNINITIALIZED); |
| 2723 stub.ClearState(); |
| 2724 |
| 2725 Code* code = NULL; |
| 2726 CHECK(stub.FindCodeInCache(&code)); |
| 2727 |
| 2728 SetTargetAtAddress(address, code, constant_pool); |
| 2729 } |
| 2730 |
| 2731 |
| 2732 Handle<Object> CompareNilIC::CompareNil(Handle<Object> object) { |
| 2733 ExtraICState extra_ic_state = target()->extra_ic_state(); |
| 2734 |
| 2735 CompareNilICStub stub(isolate(), extra_ic_state); |
| 2736 |
| 2737 // Extract the current supported types from the patched IC and calculate what |
| 2738 // types must be supported as a result of the miss. |
| 2739 bool already_monomorphic = stub.IsMonomorphic(); |
| 2740 |
| 2741 stub.UpdateStatus(object); |
| 2742 |
| 2743 // Find or create the specialized stub to support the new set of types. |
| 2744 Handle<Code> code; |
| 2745 if (stub.IsMonomorphic()) { |
| 2746 Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL |
| 2747 ? FirstTargetMap() |
| 2748 : HeapObject::cast(*object)->map()); |
| 2749 code = PropertyICCompiler::ComputeCompareNil(monomorphic_map, &stub); |
| 2750 } else { |
| 2751 code = stub.GetCode(); |
| 2752 } |
| 2753 set_target(*code); |
| 2754 return isolate()->factory()->ToBoolean(object->IsUndetectableObject()); |
| 2755 } |
| 2756 |
| 2757 |
| 2758 RUNTIME_FUNCTION(Runtime_CompareNilIC_Miss) { |
| 2759 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2760 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); |
| 2761 HandleScope scope(isolate); |
| 2762 Handle<Object> object = args.at<Object>(0); |
| 2763 CompareNilIC ic(isolate); |
| 2764 return *ic.CompareNil(object); |
| 2765 } |
| 2766 |
| 2767 |
2715 RUNTIME_FUNCTION(Runtime_Unreachable) { | 2768 RUNTIME_FUNCTION(Runtime_Unreachable) { |
2716 UNREACHABLE(); | 2769 UNREACHABLE(); |
2717 CHECK(false); | 2770 CHECK(false); |
2718 return isolate->heap()->undefined_value(); | 2771 return isolate->heap()->undefined_value(); |
2719 } | 2772 } |
2720 | 2773 |
2721 | 2774 |
2722 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { | 2775 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { |
2723 ToBooleanStub stub(isolate(), target()->extra_ic_state()); | 2776 ToBooleanStub stub(isolate(), target()->extra_ic_state()); |
2724 bool to_boolean_value = stub.UpdateStatus(object); | 2777 bool to_boolean_value = stub.UpdateStatus(object); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2903 KeyedLoadICNexus nexus(vector, vector_slot); | 2956 KeyedLoadICNexus nexus(vector, vector_slot); |
2904 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2957 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2905 ic.UpdateState(receiver, key); | 2958 ic.UpdateState(receiver, key); |
2906 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2959 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
2907 } | 2960 } |
2908 | 2961 |
2909 return *result; | 2962 return *result; |
2910 } | 2963 } |
2911 } // namespace internal | 2964 } // namespace internal |
2912 } // namespace v8 | 2965 } // namespace v8 |
OLD | NEW |