| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 // Return the address in the original code. This is the place where | 148 // Return the address in the original code. This is the place where |
| 149 // the call which has been overwritten by the DebugBreakXXX resides | 149 // the call which has been overwritten by the DebugBreakXXX resides |
| 150 // and the place where the inline cache system should look. | 150 // and the place where the inline cache system should look. |
| 151 intptr_t delta = | 151 intptr_t delta = |
| 152 original_code->instruction_start() - code->instruction_start(); | 152 original_code->instruction_start() - code->instruction_start(); |
| 153 return addr + delta; | 153 return addr + delta; |
| 154 } | 154 } |
| 155 #endif | 155 #endif |
| 156 | 156 |
| 157 | 157 |
| 158 static bool HasNormalObjectsInPrototypeChain(Isolate* isolate, | |
| 159 LookupResult* lookup, | |
| 160 Object* receiver) { | |
| 161 Object* end = lookup->IsProperty() | |
| 162 ? lookup->holder() : Object::cast(isolate->heap()->null_value()); | |
| 163 for (Object* current = receiver; | |
| 164 current != end; | |
| 165 current = current->GetPrototype()) { | |
| 166 if (current->IsJSObject() && | |
| 167 !JSObject::cast(current)->HasFastProperties() && | |
| 168 !current->IsJSGlobalProxy() && | |
| 169 !current->IsJSGlobalObject()) { | |
| 170 return true; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 return false; | |
| 175 } | |
| 176 | |
| 177 | |
| 178 static bool TryRemoveInvalidPrototypeDependentStub(Code* target, | 158 static bool TryRemoveInvalidPrototypeDependentStub(Code* target, |
| 179 Object* receiver, | 159 Object* receiver, |
| 180 Object* name) { | 160 Object* name) { |
| 181 InlineCacheHolderFlag cache_holder = | 161 InlineCacheHolderFlag cache_holder = |
| 182 Code::ExtractCacheHolderFromFlags(target->flags()); | 162 Code::ExtractCacheHolderFromFlags(target->flags()); |
| 183 | 163 |
| 184 if (cache_holder == OWN_MAP && !receiver->IsJSObject()) { | 164 if (cache_holder == OWN_MAP && !receiver->IsJSObject()) { |
| 185 // The stub was generated for JSObject but called for non-JSObject. | 165 // The stub was generated for JSObject but called for non-JSObject. |
| 186 // IC::GetCodeCacheHolder is not applicable. | 166 // IC::GetCodeCacheHolder is not applicable. |
| 187 return false; | 167 return false; |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 | 659 |
| 680 | 660 |
| 681 void CallICBase::UpdateCaches(LookupResult* lookup, | 661 void CallICBase::UpdateCaches(LookupResult* lookup, |
| 682 State state, | 662 State state, |
| 683 Code::ExtraICState extra_ic_state, | 663 Code::ExtraICState extra_ic_state, |
| 684 Handle<Object> object, | 664 Handle<Object> object, |
| 685 Handle<String> name) { | 665 Handle<String> name) { |
| 686 // Bail out if we didn't find a result. | 666 // Bail out if we didn't find a result. |
| 687 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; | 667 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; |
| 688 | 668 |
| 689 if (lookup->holder() != *object && | |
| 690 HasNormalObjectsInPrototypeChain( | |
| 691 isolate(), lookup, object->GetPrototype())) { | |
| 692 // Suppress optimization for prototype chains with slow properties objects | |
| 693 // in the middle. | |
| 694 return; | |
| 695 } | |
| 696 | |
| 697 // Compute the number of arguments. | 669 // Compute the number of arguments. |
| 698 int argc = target()->arguments_count(); | 670 int argc = target()->arguments_count(); |
| 699 Handle<Code> code; | 671 Handle<Code> code; |
| 700 if (state == UNINITIALIZED) { | 672 if (state == UNINITIALIZED) { |
| 701 // This is the first time we execute this inline cache. | 673 // This is the first time we execute this inline cache. |
| 702 // Set the target to the pre monomorphic stub to delay | 674 // Set the target to the pre monomorphic stub to delay |
| 703 // setting the monomorphic state. | 675 // setting the monomorphic state. |
| 704 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( | 676 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( |
| 705 argc, kind_, extra_ic_state); | 677 argc, kind_, extra_ic_state); |
| 706 } else if (state == MONOMORPHIC) { | 678 } else if (state == MONOMORPHIC) { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 State state, | 974 State state, |
| 1003 Handle<Object> object, | 975 Handle<Object> object, |
| 1004 Handle<String> name) { | 976 Handle<String> name) { |
| 1005 // Bail out if the result is not cacheable. | 977 // Bail out if the result is not cacheable. |
| 1006 if (!lookup->IsCacheable()) return; | 978 if (!lookup->IsCacheable()) return; |
| 1007 | 979 |
| 1008 // Loading properties from values is not common, so don't try to | 980 // Loading properties from values is not common, so don't try to |
| 1009 // deal with non-JS objects here. | 981 // deal with non-JS objects here. |
| 1010 if (!object->IsJSObject()) return; | 982 if (!object->IsJSObject()) return; |
| 1011 | 983 |
| 1012 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; | |
| 1013 | |
| 1014 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 984 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1015 Handle<Code> code; | 985 Handle<Code> code; |
| 1016 if (state == UNINITIALIZED) { | 986 if (state == UNINITIALIZED) { |
| 1017 // This is the first time we execute this inline cache. | 987 // This is the first time we execute this inline cache. |
| 1018 // Set the target to the pre monomorphic stub to delay | 988 // Set the target to the pre monomorphic stub to delay |
| 1019 // setting the monomorphic state. | 989 // setting the monomorphic state. |
| 1020 code = pre_monomorphic_stub(); | 990 code = pre_monomorphic_stub(); |
| 1021 } else { | 991 } else { |
| 1022 code = ComputeLoadMonomorphic(lookup, receiver, name); | 992 code = ComputeLoadMonomorphic(lookup, receiver, name); |
| 1023 if (code.is_null()) return; | 993 if (code.is_null()) return; |
| (...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 #undef ADDR | 2529 #undef ADDR |
| 2560 }; | 2530 }; |
| 2561 | 2531 |
| 2562 | 2532 |
| 2563 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2533 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2564 return IC_utilities[id]; | 2534 return IC_utilities[id]; |
| 2565 } | 2535 } |
| 2566 | 2536 |
| 2567 | 2537 |
| 2568 } } // namespace v8::internal | 2538 } } // namespace v8::internal |
| OLD | NEW |