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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 if (raw_frame->is_internal()) { | 82 if (raw_frame->is_internal()) { |
83 Code* apply_builtin = isolate()->builtins()->builtin( | 83 Code* apply_builtin = isolate()->builtins()->builtin( |
84 Builtins::kFunctionApply); | 84 Builtins::kFunctionApply); |
85 if (raw_frame->unchecked_code() == apply_builtin) { | 85 if (raw_frame->unchecked_code() == apply_builtin) { |
86 PrintF("apply from "); | 86 PrintF("apply from "); |
87 it.Advance(); | 87 it.Advance(); |
88 raw_frame = it.frame(); | 88 raw_frame = it.frame(); |
89 } | 89 } |
90 } | 90 } |
91 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); | 91 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
92 Code::ExtraICState extra_state = new_target->extra_ic_state(); | 92 ExtraICState extra_state = new_target->extra_ic_state(); |
93 const char* modifier = | 93 const char* modifier = |
94 GetTransitionMarkModifier(Code::GetKeyedAccessStoreMode(extra_state)); | 94 GetTransitionMarkModifier( |
| 95 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); |
95 PrintF(" (%c->%c%s)", | 96 PrintF(" (%c->%c%s)", |
96 TransitionMarkFromState(state()), | 97 TransitionMarkFromState(state()), |
97 TransitionMarkFromState(new_state), | 98 TransitionMarkFromState(new_state), |
98 modifier); | 99 modifier); |
99 name->Print(); | 100 name->Print(); |
100 PrintF("]\n"); | 101 PrintF("]\n"); |
101 } | 102 } |
102 } | 103 } |
103 | 104 |
104 #define TRACE_GENERIC_IC(isolate, type, reason) \ | 105 #define TRACE_GENERIC_IC(isolate, type, reason) \ |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 526 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
526 if (IsCleared(target)) return; | 527 if (IsCleared(target)) return; |
527 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 528 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); |
528 } | 529 } |
529 | 530 |
530 | 531 |
531 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 532 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
532 if (IsCleared(target)) return; | 533 if (IsCleared(target)) return; |
533 SetTargetAtAddress(address, | 534 SetTargetAtAddress(address, |
534 *pre_monomorphic_stub( | 535 *pre_monomorphic_stub( |
535 isolate, Code::GetStrictMode(target->extra_ic_state()))); | 536 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); |
536 } | 537 } |
537 | 538 |
538 | 539 |
539 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 540 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
540 if (IsCleared(target)) return; | 541 if (IsCleared(target)) return; |
541 SetTargetAtAddress(address, | 542 SetTargetAtAddress(address, |
542 *pre_monomorphic_stub( | 543 *pre_monomorphic_stub( |
543 isolate, Code::GetStrictMode(target->extra_ic_state()))); | 544 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); |
544 } | 545 } |
545 | 546 |
546 | 547 |
547 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { | 548 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { |
548 ASSERT(target->major_key() == CodeStub::CompareIC); | 549 ASSERT(target->major_key() == CodeStub::CompareIC); |
549 CompareIC::State handler_state; | 550 CompareIC::State handler_state; |
550 Token::Value op; | 551 Token::Value op; |
551 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, | 552 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, |
552 &handler_state, &op); | 553 &handler_state, &op); |
553 // Only clear CompareICs that can retain objects. | 554 // Only clear CompareICs that can retain objects. |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 ElementsKind kind = array->map()->elements_kind(); | 816 ElementsKind kind = array->map()->elements_kind(); |
816 if (IsFastObjectElementsKind(kind) && | 817 if (IsFastObjectElementsKind(kind) && |
817 array->map() == isolate()->get_initial_js_array_map(kind)) { | 818 array->map() == isolate()->get_initial_js_array_map(kind)) { |
818 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc); | 819 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc); |
819 stub = stub_gen.GetCode(isolate()); | 820 stub = stub_gen.GetCode(isolate()); |
820 } | 821 } |
821 } | 822 } |
822 | 823 |
823 if (stub.is_null()) { | 824 if (stub.is_null()) { |
824 stub = isolate()->stub_cache()->ComputeCallMegamorphic( | 825 stub = isolate()->stub_cache()->ComputeCallMegamorphic( |
825 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); | 826 argc, Code::KEYED_CALL_IC, kNoExtraICState); |
826 if (object->IsJSObject()) { | 827 if (object->IsJSObject()) { |
827 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 828 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
828 if (receiver->elements()->map() == | 829 if (receiver->elements()->map() == |
829 isolate()->heap()->non_strict_arguments_elements_map()) { | 830 isolate()->heap()->non_strict_arguments_elements_map()) { |
830 stub = isolate()->stub_cache()->ComputeCallArguments(argc); | 831 stub = isolate()->stub_cache()->ComputeCallArguments(argc); |
831 } | 832 } |
832 } | 833 } |
833 ASSERT(!stub.is_null()); | 834 ASSERT(!stub.is_null()); |
834 } | 835 } |
835 set_target(*stub); | 836 set_target(*stub); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 | 999 |
999 number_of_valid_types++; | 1000 number_of_valid_types++; |
1000 if (handler_to_overwrite >= 0) { | 1001 if (handler_to_overwrite >= 0) { |
1001 handlers.Set(handler_to_overwrite, code); | 1002 handlers.Set(handler_to_overwrite, code); |
1002 } else { | 1003 } else { |
1003 types.Add(type); | 1004 types.Add(type); |
1004 handlers.Add(code); | 1005 handlers.Add(code); |
1005 } | 1006 } |
1006 | 1007 |
1007 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1008 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
1008 &types, &handlers, number_of_valid_types, name, strict_mode()); | 1009 &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
1009 set_target(*ic); | 1010 set_target(*ic); |
1010 return true; | 1011 return true; |
1011 } | 1012 } |
1012 | 1013 |
1013 | 1014 |
1014 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 1015 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
1015 Type* type = object->IsJSGlobalObject() | 1016 Type* type = object->IsJSGlobalObject() |
1016 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) | 1017 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) |
1017 : Type::OfCurrently(object); | 1018 : Type::OfCurrently(object); |
1018 return handle(type, isolate); | 1019 return handle(type, isolate); |
(...skipping 17 matching lines...) Expand all Loading... |
1036 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); | 1037 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); |
1037 return Type::Class(map); | 1038 return Type::Class(map); |
1038 } | 1039 } |
1039 | 1040 |
1040 | 1041 |
1041 void IC::UpdateMonomorphicIC(Handle<Type> type, | 1042 void IC::UpdateMonomorphicIC(Handle<Type> type, |
1042 Handle<Code> handler, | 1043 Handle<Code> handler, |
1043 Handle<String> name) { | 1044 Handle<String> name) { |
1044 if (!handler->is_handler()) return set_target(*handler); | 1045 if (!handler->is_handler()) return set_target(*handler); |
1045 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1046 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
1046 name, type, handler, strict_mode()); | 1047 name, type, handler, extra_ic_state()); |
1047 set_target(*ic); | 1048 set_target(*ic); |
1048 } | 1049 } |
1049 | 1050 |
1050 | 1051 |
1051 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1052 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1052 TypeHandleList types; | 1053 TypeHandleList types; |
1053 CodeHandleList handlers; | 1054 CodeHandleList handlers; |
1054 target()->FindAllTypes(&types); | 1055 target()->FindAllTypes(&types); |
1055 if (!target()->FindHandlers(&handlers, types.length())) return; | 1056 if (!target()->FindHandlers(&handlers, types.length())) return; |
1056 for (int i = 0; i < types.length(); i++) { | 1057 for (int i = 0; i < types.length(); i++) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 | 1171 |
1171 | 1172 |
1172 Handle<Code> IC::ComputeHandler(LookupResult* lookup, | 1173 Handle<Code> IC::ComputeHandler(LookupResult* lookup, |
1173 Handle<Object> object, | 1174 Handle<Object> object, |
1174 Handle<String> name, | 1175 Handle<String> name, |
1175 Handle<Object> value) { | 1176 Handle<Object> value) { |
1176 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); | 1177 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); |
1177 Handle<HeapObject> stub_holder(GetCodeCacheHolder( | 1178 Handle<HeapObject> stub_holder(GetCodeCacheHolder( |
1178 isolate(), *object, cache_holder)); | 1179 isolate(), *object, cache_holder)); |
1179 | 1180 |
| 1181 StrictModeFlag strict_mode = kNonStrictMode; |
| 1182 if (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC) { |
| 1183 strict_mode = StoreIC::GetStrictMode(extra_ic_state()); |
| 1184 } |
1180 Handle<Code> code = isolate()->stub_cache()->FindHandler( | 1185 Handle<Code> code = isolate()->stub_cache()->FindHandler( |
1181 name, handle(stub_holder->map()), kind(), cache_holder, strict_mode()); | 1186 name, handle(stub_holder->map()), kind(), cache_holder, strict_mode); |
1182 if (!code.is_null()) return code; | 1187 if (!code.is_null()) return code; |
1183 | 1188 |
1184 code = CompileHandler(lookup, object, name, value, cache_holder); | 1189 code = CompileHandler(lookup, object, name, value, cache_holder); |
1185 ASSERT(code->is_handler()); | 1190 ASSERT(code->is_handler()); |
1186 | 1191 |
1187 if (code->type() != Code::NORMAL) { | 1192 if (code->type() != Code::NORMAL) { |
1188 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 1193 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
1189 } | 1194 } |
1190 | 1195 |
1191 return code; | 1196 return code; |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 // stores into properties in dictionary mode), then there will be not | 1751 // stores into properties in dictionary mode), then there will be not |
1747 // receiver maps in the target. | 1752 // receiver maps in the target. |
1748 return generic_stub(); | 1753 return generic_stub(); |
1749 } | 1754 } |
1750 | 1755 |
1751 // There are several special cases where an IC that is MONOMORPHIC can still | 1756 // There are several special cases where an IC that is MONOMORPHIC can still |
1752 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1757 // transition to a different GetNonTransitioningStoreMode IC that handles a |
1753 // superset of the original IC. Handle those here if the receiver map hasn't | 1758 // superset of the original IC. Handle those here if the receiver map hasn't |
1754 // changed or it has transitioned to a more general kind. | 1759 // changed or it has transitioned to a more general kind. |
1755 KeyedAccessStoreMode old_store_mode = | 1760 KeyedAccessStoreMode old_store_mode = |
1756 Code::GetKeyedAccessStoreMode(target()->extra_ic_state()); | 1761 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); |
1757 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1762 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); |
1758 if (state() == MONOMORPHIC) { | 1763 if (state() == MONOMORPHIC) { |
1759 // If the "old" and "new" maps are in the same elements map family, stay | 1764 // If the "old" and "new" maps are in the same elements map family, stay |
1760 // MONOMORPHIC and use the map for the most generic ElementsKind. | 1765 // MONOMORPHIC and use the map for the most generic ElementsKind. |
1761 Handle<Map> transitioned_receiver_map = receiver_map; | 1766 Handle<Map> transitioned_receiver_map = receiver_map; |
1762 if (IsTransitionStoreMode(store_mode)) { | 1767 if (IsTransitionStoreMode(store_mode)) { |
1763 transitioned_receiver_map = | 1768 transitioned_receiver_map = |
1764 ComputeTransitionedMap(receiver, store_mode); | 1769 ComputeTransitionedMap(receiver, store_mode); |
1765 } | 1770 } |
1766 if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) { | 1771 if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) { |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2337 case NUMBER: return "Number"; | 2342 case NUMBER: return "Number"; |
2338 case ODDBALL: return "Oddball"; | 2343 case ODDBALL: return "Oddball"; |
2339 case STRING: return "String"; | 2344 case STRING: return "String"; |
2340 case GENERIC: return "Generic"; | 2345 case GENERIC: return "Generic"; |
2341 default: return "Invalid"; | 2346 default: return "Invalid"; |
2342 } | 2347 } |
2343 } | 2348 } |
2344 | 2349 |
2345 | 2350 |
2346 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { | 2351 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { |
2347 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 2352 ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
2348 BinaryOpStub stub(extra_ic_state); | 2353 BinaryOpStub stub(extra_ic_state); |
2349 | 2354 |
2350 Handle<Type> left_type = stub.GetLeftType(isolate()); | 2355 Handle<Type> left_type = stub.GetLeftType(isolate()); |
2351 Handle<Type> right_type = stub.GetRightType(isolate()); | 2356 Handle<Type> right_type = stub.GetRightType(isolate()); |
2352 bool smi_was_enabled = left_type->Maybe(Type::Smi()) && | 2357 bool smi_was_enabled = left_type->Maybe(Type::Smi()) && |
2353 right_type->Maybe(Type::Smi()); | 2358 right_type->Maybe(Type::Smi()); |
2354 | 2359 |
2355 Maybe<Handle<Object> > result = stub.Result(left, right, isolate()); | 2360 Maybe<Handle<Object> > result = stub.Result(left, right, isolate()); |
2356 if (!result.has_value) return Failure::Exception(); | 2361 if (!result.has_value) return Failure::Exception(); |
2357 | 2362 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2630 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { | 2635 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { |
2631 HandleScope scope(isolate); | 2636 HandleScope scope(isolate); |
2632 ASSERT(args.length() == 3); | 2637 ASSERT(args.length() == 3); |
2633 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2638 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2634 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2639 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2635 } | 2640 } |
2636 | 2641 |
2637 | 2642 |
2638 void CompareNilIC::Clear(Address address, Code* target) { | 2643 void CompareNilIC::Clear(Address address, Code* target) { |
2639 if (IsCleared(target)) return; | 2644 if (IsCleared(target)) return; |
2640 Code::ExtraICState state = target->extended_extra_ic_state(); | 2645 ExtraICState state = target->extended_extra_ic_state(); |
2641 | 2646 |
2642 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); | 2647 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); |
2643 stub.ClearState(); | 2648 stub.ClearState(); |
2644 | 2649 |
2645 Code* code = NULL; | 2650 Code* code = NULL; |
2646 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); | 2651 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); |
2647 | 2652 |
2648 SetTargetAtAddress(address, code); | 2653 SetTargetAtAddress(address, code); |
2649 } | 2654 } |
2650 | 2655 |
2651 | 2656 |
2652 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, | 2657 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, |
2653 Handle<Object> object) { | 2658 Handle<Object> object) { |
2654 if (object->IsNull() || object->IsUndefined()) { | 2659 if (object->IsNull() || object->IsUndefined()) { |
2655 return Smi::FromInt(true); | 2660 return Smi::FromInt(true); |
2656 } | 2661 } |
2657 return Smi::FromInt(object->IsUndetectableObject()); | 2662 return Smi::FromInt(object->IsUndetectableObject()); |
2658 } | 2663 } |
2659 | 2664 |
2660 | 2665 |
2661 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 2666 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
2662 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 2667 ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
2663 | 2668 |
2664 CompareNilICStub stub(extra_ic_state); | 2669 CompareNilICStub stub(extra_ic_state); |
2665 | 2670 |
2666 // Extract the current supported types from the patched IC and calculate what | 2671 // Extract the current supported types from the patched IC and calculate what |
2667 // types must be supported as a result of the miss. | 2672 // types must be supported as a result of the miss. |
2668 bool already_monomorphic = stub.IsMonomorphic(); | 2673 bool already_monomorphic = stub.IsMonomorphic(); |
2669 | 2674 |
2670 stub.UpdateStatus(object); | 2675 stub.UpdateStatus(object); |
2671 | 2676 |
2672 NilValue nil = stub.GetNilValue(); | 2677 NilValue nil = stub.GetNilValue(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 #undef ADDR | 2772 #undef ADDR |
2768 }; | 2773 }; |
2769 | 2774 |
2770 | 2775 |
2771 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2776 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2772 return IC_utilities[id]; | 2777 return IC_utilities[id]; |
2773 } | 2778 } |
2774 | 2779 |
2775 | 2780 |
2776 } } // namespace v8::internal | 2781 } } // namespace v8::internal |
OLD | NEW |