| 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 |