| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 #ifdef DEBUG | 141 #ifdef DEBUG |
| 142 StackFrameIterator it(isolate); | 142 StackFrameIterator it(isolate); |
| 143 for (int i = 0; i < depth + 1; i++) it.Advance(); | 143 for (int i = 0; i < depth + 1; i++) it.Advance(); |
| 144 StackFrame* frame = it.frame(); | 144 StackFrame* frame = it.frame(); |
| 145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); | 145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); |
| 146 #endif | 146 #endif |
| 147 fp_ = fp; | 147 fp_ = fp; |
| 148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); | 148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
| 149 target_ = handle(raw_target(), isolate); | 149 target_ = handle(raw_target(), isolate); |
| 150 state_ = target_->ic_state(); | 150 state_ = target_->ic_state(); |
| 151 extra_ic_state_ = target_->extra_ic_state(); | 151 extra_ic_state_ = target_->needs_extended_extra_ic_state(target_->kind()) |
| 152 ? target_->extended_extra_ic_state() |
| 153 : target_->extra_ic_state(); |
| 152 } | 154 } |
| 153 | 155 |
| 154 | 156 |
| 155 #ifdef ENABLE_DEBUGGER_SUPPORT | 157 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 156 Address IC::OriginalCodeAddress() const { | 158 Address IC::OriginalCodeAddress() const { |
| 157 HandleScope scope(isolate()); | 159 HandleScope scope(isolate()); |
| 158 // Compute the JavaScript frame for the frame pointer of this IC | 160 // Compute the JavaScript frame for the frame pointer of this IC |
| 159 // structure. We need this to be able to find the function | 161 // structure. We need this to be able to find the function |
| 160 // corresponding to the frame. | 162 // corresponding to the frame. |
| 161 StackFrameIterator it(isolate()); | 163 StackFrameIterator it(isolate()); |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 | 638 |
| 637 number_of_valid_types++; | 639 number_of_valid_types++; |
| 638 if (handler_to_overwrite >= 0) { | 640 if (handler_to_overwrite >= 0) { |
| 639 handlers.Set(handler_to_overwrite, code); | 641 handlers.Set(handler_to_overwrite, code); |
| 640 } else { | 642 } else { |
| 641 types.Add(type); | 643 types.Add(type); |
| 642 handlers.Add(code); | 644 handlers.Add(code); |
| 643 } | 645 } |
| 644 | 646 |
| 645 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 647 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
| 646 kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state()); | 648 &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
| 647 set_target(*ic); | 649 set_target(*ic); |
| 648 return true; | 650 return true; |
| 649 } | 651 } |
| 650 | 652 |
| 651 | 653 |
| 652 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 654 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
| 653 return object->IsJSGlobalObject() | 655 return object->IsJSGlobalObject() |
| 654 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) | 656 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) |
| 655 : HeapType::OfCurrently(object, isolate); | 657 : HeapType::OfCurrently(object, isolate); |
| 656 } | 658 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 | 690 |
| 689 template | 691 template |
| 690 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); | 692 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); |
| 691 | 693 |
| 692 | 694 |
| 693 void IC::UpdateMonomorphicIC(Handle<HeapType> type, | 695 void IC::UpdateMonomorphicIC(Handle<HeapType> type, |
| 694 Handle<Code> handler, | 696 Handle<Code> handler, |
| 695 Handle<String> name) { | 697 Handle<String> name) { |
| 696 if (!handler->is_handler()) return set_target(*handler); | 698 if (!handler->is_handler()) return set_target(*handler); |
| 697 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 699 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
| 698 kind(), name, type, handler, extra_ic_state()); | 700 name, type, handler, extra_ic_state()); |
| 699 set_target(*ic); | 701 set_target(*ic); |
| 700 } | 702 } |
| 701 | 703 |
| 702 | 704 |
| 703 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 705 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
| 704 TypeHandleList types; | 706 TypeHandleList types; |
| 705 CodeHandleList handlers; | 707 CodeHandleList handlers; |
| 706 target()->FindAllTypes(&types); | 708 target()->FindAllTypes(&types); |
| 707 if (!target()->FindHandlers(&handlers, types.length())) return; | 709 if (!target()->FindHandlers(&handlers, types.length())) return; |
| 708 for (int i = 0; i < types.length(); i++) { | 710 for (int i = 0; i < types.length(); i++) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 | 840 |
| 839 Handle<Code> IC::ComputeHandler(LookupResult* lookup, | 841 Handle<Code> IC::ComputeHandler(LookupResult* lookup, |
| 840 Handle<Object> object, | 842 Handle<Object> object, |
| 841 Handle<String> name, | 843 Handle<String> name, |
| 842 Handle<Object> value) { | 844 Handle<Object> value) { |
| 843 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); | 845 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); |
| 844 Handle<HeapObject> stub_holder(GetCodeCacheHolder( | 846 Handle<HeapObject> stub_holder(GetCodeCacheHolder( |
| 845 isolate(), *object, cache_holder)); | 847 isolate(), *object, cache_holder)); |
| 846 | 848 |
| 847 Handle<Code> code = isolate()->stub_cache()->FindHandler( | 849 Handle<Code> code = isolate()->stub_cache()->FindHandler( |
| 848 name, handle(stub_holder->map()), kind(), cache_holder, | 850 name, handle(stub_holder->map()), kind(), cache_holder); |
| 849 lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL); | 851 if (!code.is_null()) return code; |
| 850 if (!code.is_null()) { | |
| 851 return code; | |
| 852 } | |
| 853 | 852 |
| 854 code = CompileHandler(lookup, object, name, value, cache_holder); | 853 code = CompileHandler(lookup, object, name, value, cache_holder); |
| 855 ASSERT(code->is_handler()); | 854 ASSERT(code->is_handler()); |
| 856 | 855 |
| 857 if (code->type() != Code::NORMAL) { | 856 if (code->type() != Code::NORMAL) { |
| 858 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 857 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 859 } | 858 } |
| 860 | 859 |
| 861 return code; | 860 return code; |
| 862 } | 861 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 | 1056 |
| 1058 | 1057 |
| 1059 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { | 1058 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { |
| 1060 if (MigrateDeprecated(object)) { | 1059 if (MigrateDeprecated(object)) { |
| 1061 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); | 1060 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); |
| 1062 } | 1061 } |
| 1063 | 1062 |
| 1064 MaybeObject* maybe_object = NULL; | 1063 MaybeObject* maybe_object = NULL; |
| 1065 Handle<Code> stub = generic_stub(); | 1064 Handle<Code> stub = generic_stub(); |
| 1066 | 1065 |
| 1067 // Check for non-string values that can be converted into an | 1066 // Check for values that can be converted into an internalized string directly |
| 1068 // internalized string directly or is representable as a smi. | 1067 // or is representable as a smi. |
| 1069 key = TryConvertKey(key, isolate()); | 1068 key = TryConvertKey(key, isolate()); |
| 1070 | 1069 |
| 1071 if (key->IsInternalizedString()) { | 1070 if (key->IsInternalizedString()) { |
| 1072 maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); | 1071 maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); |
| 1073 if (maybe_object->IsFailure()) return maybe_object; | 1072 if (maybe_object->IsFailure()) return maybe_object; |
| 1074 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { | 1073 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { |
| 1075 ASSERT(!object->IsJSGlobalProxy()); | 1074 ASSERT(!object->IsJSGlobalProxy()); |
| 1076 if (object->IsString() && key->IsNumber()) { | 1075 if (object->IsString() && key->IsNumber()) { |
| 1077 if (state() == UNINITIALIZED) stub = string_stub(); | 1076 if (state() == UNINITIALIZED) stub = string_stub(); |
| 1078 } else if (object->IsJSObject()) { | 1077 } else if (object->IsJSObject()) { |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 if (MigrateDeprecated(object)) { | 1648 if (MigrateDeprecated(object)) { |
| 1650 Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, | 1649 Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, |
| 1651 key, | 1650 key, |
| 1652 value, | 1651 value, |
| 1653 NONE, | 1652 NONE, |
| 1654 strict_mode()); | 1653 strict_mode()); |
| 1655 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1654 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1656 return *result; | 1655 return *result; |
| 1657 } | 1656 } |
| 1658 | 1657 |
| 1659 // Check for non-string values that can be converted into an | 1658 // Check for values that can be converted into an internalized string directly |
| 1660 // internalized string directly or is representable as a smi. | 1659 // or is representable as a smi. |
| 1661 key = TryConvertKey(key, isolate()); | 1660 key = TryConvertKey(key, isolate()); |
| 1662 | 1661 |
| 1663 MaybeObject* maybe_object = NULL; | 1662 MaybeObject* maybe_object = NULL; |
| 1664 Handle<Code> stub = generic_stub(); | 1663 Handle<Code> stub = generic_stub(); |
| 1665 | 1664 |
| 1666 if (key->IsInternalizedString()) { | 1665 if (key->IsInternalizedString()) { |
| 1667 maybe_object = StoreIC::Store(object, | 1666 maybe_object = StoreIC::Store(object, |
| 1668 Handle<String>::cast(key), | 1667 Handle<String>::cast(key), |
| 1669 value, | 1668 value, |
| 1670 JSReceiver::MAY_BE_STORE_FROM_KEYED); | 1669 JSReceiver::MAY_BE_STORE_FROM_KEYED); |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2360 case GENERIC: return Type::Any(zone); | 2359 case GENERIC: return Type::Any(zone); |
| 2361 } | 2360 } |
| 2362 UNREACHABLE(); | 2361 UNREACHABLE(); |
| 2363 return NULL; | 2362 return NULL; |
| 2364 } | 2363 } |
| 2365 | 2364 |
| 2366 | 2365 |
| 2367 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, | 2366 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, |
| 2368 Handle<Object> left, | 2367 Handle<Object> left, |
| 2369 Handle<Object> right) { | 2368 Handle<Object> right) { |
| 2370 State state(target()->extra_ic_state()); | 2369 State state(target()->extended_extra_ic_state()); |
| 2371 | 2370 |
| 2372 // Compute the actual result using the builtin for the binary operation. | 2371 // Compute the actual result using the builtin for the binary operation. |
| 2373 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2372 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
| 2374 TokenToJSBuiltin(state.op())); | 2373 TokenToJSBuiltin(state.op())); |
| 2375 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); | 2374 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); |
| 2376 bool caught_exception; | 2375 bool caught_exception; |
| 2377 Handle<Object> result = Execution::Call( | 2376 Handle<Object> result = Execution::Call( |
| 2378 isolate(), function, left, 1, &right, &caught_exception); | 2377 isolate(), function, left, 1, &right, &caught_exception); |
| 2379 if (caught_exception) return Failure::Exception(); | 2378 if (caught_exception) return Failure::Exception(); |
| 2380 | 2379 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2676 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { | 2675 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { |
| 2677 HandleScope scope(isolate); | 2676 HandleScope scope(isolate); |
| 2678 ASSERT(args.length() == 3); | 2677 ASSERT(args.length() == 3); |
| 2679 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2678 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
| 2680 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2679 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
| 2681 } | 2680 } |
| 2682 | 2681 |
| 2683 | 2682 |
| 2684 void CompareNilIC::Clear(Address address, Code* target) { | 2683 void CompareNilIC::Clear(Address address, Code* target) { |
| 2685 if (IsCleared(target)) return; | 2684 if (IsCleared(target)) return; |
| 2686 ExtraICState state = target->extra_ic_state(); | 2685 ExtraICState state = target->extended_extra_ic_state(); |
| 2687 | 2686 |
| 2688 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); | 2687 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); |
| 2689 stub.ClearState(); | 2688 stub.ClearState(); |
| 2690 | 2689 |
| 2691 Code* code = NULL; | 2690 Code* code = NULL; |
| 2692 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); | 2691 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); |
| 2693 | 2692 |
| 2694 SetTargetAtAddress(address, code); | 2693 SetTargetAtAddress(address, code); |
| 2695 } | 2694 } |
| 2696 | 2695 |
| 2697 | 2696 |
| 2698 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, | 2697 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, |
| 2699 Handle<Object> object) { | 2698 Handle<Object> object) { |
| 2700 if (object->IsNull() || object->IsUndefined()) { | 2699 if (object->IsNull() || object->IsUndefined()) { |
| 2701 return Smi::FromInt(true); | 2700 return Smi::FromInt(true); |
| 2702 } | 2701 } |
| 2703 return Smi::FromInt(object->IsUndetectableObject()); | 2702 return Smi::FromInt(object->IsUndetectableObject()); |
| 2704 } | 2703 } |
| 2705 | 2704 |
| 2706 | 2705 |
| 2707 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 2706 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
| 2708 ExtraICState extra_ic_state = target()->extra_ic_state(); | 2707 ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
| 2709 | 2708 |
| 2710 CompareNilICStub stub(extra_ic_state); | 2709 CompareNilICStub stub(extra_ic_state); |
| 2711 | 2710 |
| 2712 // Extract the current supported types from the patched IC and calculate what | 2711 // Extract the current supported types from the patched IC and calculate what |
| 2713 // types must be supported as a result of the miss. | 2712 // types must be supported as a result of the miss. |
| 2714 bool already_monomorphic = stub.IsMonomorphic(); | 2713 bool already_monomorphic = stub.IsMonomorphic(); |
| 2715 | 2714 |
| 2716 stub.UpdateStatus(object); | 2715 stub.UpdateStatus(object); |
| 2717 | 2716 |
| 2718 NilValue nil = stub.GetNilValue(); | 2717 NilValue nil = stub.GetNilValue(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2782 return Builtins::SHR; | 2781 return Builtins::SHR; |
| 2783 break; | 2782 break; |
| 2784 case Token::SHL: | 2783 case Token::SHL: |
| 2785 return Builtins::SHL; | 2784 return Builtins::SHL; |
| 2786 break; | 2785 break; |
| 2787 } | 2786 } |
| 2788 } | 2787 } |
| 2789 | 2788 |
| 2790 | 2789 |
| 2791 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) { | 2790 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) { |
| 2792 ToBooleanStub stub(target()->extra_ic_state()); | 2791 ToBooleanStub stub(target()->extended_extra_ic_state()); |
| 2793 bool to_boolean_value = stub.UpdateStatus(object); | 2792 bool to_boolean_value = stub.UpdateStatus(object); |
| 2794 Handle<Code> code = stub.GetCode(isolate()); | 2793 Handle<Code> code = stub.GetCode(isolate()); |
| 2795 set_target(*code); | 2794 set_target(*code); |
| 2796 return Smi::FromInt(to_boolean_value ? 1 : 0); | 2795 return Smi::FromInt(to_boolean_value ? 1 : 0); |
| 2797 } | 2796 } |
| 2798 | 2797 |
| 2799 | 2798 |
| 2800 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { | 2799 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { |
| 2801 ASSERT(args.length() == 1); | 2800 ASSERT(args.length() == 1); |
| 2802 HandleScope scope(isolate); | 2801 HandleScope scope(isolate); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2813 #undef ADDR | 2812 #undef ADDR |
| 2814 }; | 2813 }; |
| 2815 | 2814 |
| 2816 | 2815 |
| 2817 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2816 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2818 return IC_utilities[id]; | 2817 return IC_utilities[id]; |
| 2819 } | 2818 } |
| 2820 | 2819 |
| 2821 | 2820 |
| 2822 } } // namespace v8::internal | 2821 } } // namespace v8::internal |
| OLD | NEW |