| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 case Code::KEYED_LOAD_IC: | 302 case Code::KEYED_LOAD_IC: |
| 303 return KeyedLoadIC::Clear(address, target); | 303 return KeyedLoadIC::Clear(address, target); |
| 304 case Code::STORE_IC: return StoreIC::Clear(address, target); | 304 case Code::STORE_IC: return StoreIC::Clear(address, target); |
| 305 case Code::KEYED_STORE_IC: | 305 case Code::KEYED_STORE_IC: |
| 306 return KeyedStoreIC::Clear(address, target); | 306 return KeyedStoreIC::Clear(address, target); |
| 307 case Code::CALL_IC: return CallIC::Clear(address, target); | 307 case Code::CALL_IC: return CallIC::Clear(address, target); |
| 308 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); | 308 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); |
| 309 case Code::UNARY_OP_IC: | 309 case Code::UNARY_OP_IC: |
| 310 case Code::BINARY_OP_IC: | 310 case Code::BINARY_OP_IC: |
| 311 case Code::COMPARE_IC: | 311 case Code::COMPARE_IC: |
| 312 case Code::TO_BOOLEAN_IC: |
| 312 // Clearing these is tricky and does not | 313 // Clearing these is tricky and does not |
| 313 // make any performance difference. | 314 // make any performance difference. |
| 314 return; | 315 return; |
| 315 default: UNREACHABLE(); | 316 default: UNREACHABLE(); |
| 316 } | 317 } |
| 317 } | 318 } |
| 318 | 319 |
| 319 | 320 |
| 320 void CallICBase::Clear(Address address, Code* target) { | 321 void CallICBase::Clear(Address address, Code* target) { |
| 321 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); | 322 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 ReceiverToObjectIfRequired(result, object); | 836 ReceiverToObjectIfRequired(result, object); |
| 836 | 837 |
| 837 if (result->IsJSFunction()) return *result; | 838 if (result->IsJSFunction()) return *result; |
| 838 result = Handle<Object>(TryCallAsFunction(*result)); | 839 result = Handle<Object>(TryCallAsFunction(*result)); |
| 839 if (result->IsJSFunction()) return *result; | 840 if (result->IsJSFunction()) return *result; |
| 840 | 841 |
| 841 return TypeError("property_not_function", object, key); | 842 return TypeError("property_not_function", object, key); |
| 842 } | 843 } |
| 843 | 844 |
| 844 | 845 |
| 845 #ifdef DEBUG | |
| 846 #define TRACE_IC_NAMED(msg, name) \ | |
| 847 if (FLAG_trace_ic) PrintF(msg, *(name)->ToCString()) | |
| 848 #else | |
| 849 #define TRACE_IC_NAMED(msg, name) | |
| 850 #endif | |
| 851 | |
| 852 | |
| 853 MaybeObject* LoadIC::Load(State state, | 846 MaybeObject* LoadIC::Load(State state, |
| 854 Handle<Object> object, | 847 Handle<Object> object, |
| 855 Handle<String> name) { | 848 Handle<String> name) { |
| 856 // If the object is undefined or null it's illegal to try to get any | 849 // If the object is undefined or null it's illegal to try to get any |
| 857 // of its properties; throw a TypeError in that case. | 850 // of its properties; throw a TypeError in that case. |
| 858 if (object->IsUndefined() || object->IsNull()) { | 851 if (object->IsUndefined() || object->IsNull()) { |
| 859 return TypeError("non_object_property_load", object, name); | 852 return TypeError("non_object_property_load", object, name); |
| 860 } | 853 } |
| 861 | 854 |
| 862 if (FLAG_use_ic) { | 855 if (FLAG_use_ic) { |
| (...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 // Used from ic_<arch>.cc. | 2492 // Used from ic_<arch>.cc. |
| 2500 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { | 2493 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { |
| 2501 NoHandleAllocation na; | 2494 NoHandleAllocation na; |
| 2502 ASSERT(args.length() == 3); | 2495 ASSERT(args.length() == 3); |
| 2503 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2496 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
| 2504 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2497 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
| 2505 return ic.target(); | 2498 return ic.target(); |
| 2506 } | 2499 } |
| 2507 | 2500 |
| 2508 | 2501 |
| 2502 RUNTIME_FUNCTION(MaybeObject*, ToBoolean_Patch) { |
| 2503 ASSERT(args.length() == 3); |
| 2504 |
| 2505 HandleScope scope(isolate); |
| 2506 Handle<Object> object = args.at<Object>(0); |
| 2507 Register tos = Register::from_code(args.smi_at(1)); |
| 2508 ToBooleanStub::Types old_types(args.smi_at(2)); |
| 2509 |
| 2510 ToBooleanStub::Types new_types(old_types); |
| 2511 bool to_boolean_value = new_types.Record(object); |
| 2512 old_types.TraceTransition(new_types); |
| 2513 |
| 2514 ToBooleanStub stub(tos, new_types); |
| 2515 Handle<Code> code = stub.GetCode(); |
| 2516 ToBooleanIC ic(isolate); |
| 2517 ic.patch(*code); |
| 2518 return Smi::FromInt(to_boolean_value ? 1 : 0); |
| 2519 } |
| 2520 |
| 2521 |
| 2522 void ToBooleanIC::patch(Code* code) { |
| 2523 set_target(code); |
| 2524 } |
| 2525 |
| 2526 |
| 2509 static const Address IC_utilities[] = { | 2527 static const Address IC_utilities[] = { |
| 2510 #define ADDR(name) FUNCTION_ADDR(name), | 2528 #define ADDR(name) FUNCTION_ADDR(name), |
| 2511 IC_UTIL_LIST(ADDR) | 2529 IC_UTIL_LIST(ADDR) |
| 2512 NULL | 2530 NULL |
| 2513 #undef ADDR | 2531 #undef ADDR |
| 2514 }; | 2532 }; |
| 2515 | 2533 |
| 2516 | 2534 |
| 2517 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2535 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2518 return IC_utilities[id]; | 2536 return IC_utilities[id]; |
| 2519 } | 2537 } |
| 2520 | 2538 |
| 2521 | 2539 |
| 2522 } } // namespace v8::internal | 2540 } } // namespace v8::internal |
| OLD | NEW |