Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ic/ic.h" | 5 #include "src/ic/ic.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api-arguments-inl.h" | 8 #include "src/api-arguments-inl.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 831 | 831 |
| 832 Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { | 832 Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { |
| 833 if (FLAG_tf_load_ic_stub) { | 833 if (FLAG_tf_load_ic_stub) { |
| 834 return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate()); | 834 return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate()); |
| 835 } | 835 } |
| 836 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); | 836 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); |
| 837 LoadFieldStub stub(isolate(), index); | 837 LoadFieldStub stub(isolate(), index); |
| 838 return stub.GetCode(); | 838 return stub.GetCode(); |
| 839 } | 839 } |
| 840 | 840 |
| 841 Handle<Object> LoadIC::SimpleFieldLoadFromPrototype(FieldIndex index, | |
| 842 Handle<Map> receiver_map, | |
| 843 Handle<JSObject> holder) { | |
| 844 if (!FLAG_tf_load_ic_stub) return Handle<Object>::null(); | |
|
Jakob Kummerow
2016/10/13 11:59:26
nit: you probably want to make the flag non-readon
Igor Sheludko
2016/10/13 13:20:38
We should just remove this flag once you remove th
| |
| 845 | |
| 846 DCHECK(holder->HasFastProperties()); | |
| 847 | |
| 848 // Primitive maps require custom handler compilation. | |
| 849 if (receiver_map->IsPrimitiveMap()) { | |
| 850 return Handle<Object>::null(); | |
| 851 } | |
| 852 | |
| 853 // Switch to custom compiled handler if the prototype chain contains global | |
| 854 // or dictionary objects. | |
| 855 { | |
| 856 Map* current_map = *receiver_map; | |
| 857 Map* holder_map = holder->map(); | |
| 858 while (current_map != holder_map) { | |
| 859 // Only global objects and objects that do not require access | |
| 860 // checks are allowed in stubs. | |
| 861 DCHECK(current_map->IsJSGlobalProxyMap() || | |
| 862 !current_map->is_access_check_needed()); | |
| 863 | |
| 864 if (current_map->IsJSGlobalObjectMap() || | |
| 865 current_map->IsJSGlobalProxyMap() || | |
| 866 current_map->is_dictionary_map()) { | |
| 867 return Handle<Object>::null(); | |
| 868 } | |
| 869 // Go to the next object in the prototype chain. | |
| 870 JSObject* prototype = JSObject::cast(current_map->prototype()); | |
|
Jakob Kummerow
2016/10/13 11:59:26
nit: use a PrototypeIterator please
Igor Sheludko
2016/10/13 13:20:38
Done.
| |
| 871 current_map = prototype->map(); | |
| 872 } | |
| 873 } | |
| 874 | |
| 875 Handle<Cell> validity_cell = | |
| 876 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | |
| 877 DCHECK(!validity_cell.is_null()); | |
| 878 | |
| 879 Handle<Object> handler = SimpleFieldLoad(index); | |
| 880 DCHECK(handler->IsSmi()); | |
| 881 | |
| 882 Factory* factory = isolate()->factory(); | |
| 883 | |
| 884 Handle<WeakCell> holder_cell = factory->NewWeakCell(holder); | |
| 885 return isolate()->factory()->NewTuple3(validity_cell, holder_cell, handler); | |
|
Jakob Kummerow
2016/10/13 11:59:26
nit: s/isolate()->factory()/factory/
Igor Sheludko
2016/10/13 13:20:38
Done.
| |
| 886 } | |
| 841 | 887 |
| 842 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { | 888 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
| 843 DCHECK(lookup->state() == LookupIterator::ACCESSOR); | 889 DCHECK(lookup->state() == LookupIterator::ACCESSOR); |
| 844 Isolate* isolate = lookup->isolate(); | 890 Isolate* isolate = lookup->isolate(); |
| 845 Handle<Object> accessors = lookup->GetAccessors(); | 891 Handle<Object> accessors = lookup->GetAccessors(); |
| 846 if (accessors->IsAccessorInfo()) { | 892 if (accessors->IsAccessorInfo()) { |
| 847 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 893 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
| 848 if (info->getter() != NULL && | 894 if (info->getter() != NULL && |
| 849 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { | 895 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { |
| 850 return false; | 896 return false; |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1135 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); | 1181 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); |
| 1136 return isolate()->builtins()->LoadIC_Normal(); | 1182 return isolate()->builtins()->LoadIC_Normal(); |
| 1137 } | 1183 } |
| 1138 | 1184 |
| 1139 // -------------- Fields -------------- | 1185 // -------------- Fields -------------- |
| 1140 if (lookup->property_details().type() == DATA) { | 1186 if (lookup->property_details().type() == DATA) { |
| 1141 FieldIndex field = lookup->GetFieldIndex(); | 1187 FieldIndex field = lookup->GetFieldIndex(); |
| 1142 if (receiver_is_holder) { | 1188 if (receiver_is_holder) { |
| 1143 return SimpleFieldLoad(field); | 1189 return SimpleFieldLoad(field); |
| 1144 } | 1190 } |
| 1191 Handle<Object> handler = | |
| 1192 SimpleFieldLoadFromPrototype(field, map, holder); | |
| 1193 if (!handler.is_null()) { | |
| 1194 return handler; | |
| 1195 } | |
| 1145 break; // Custom-compiled handler. | 1196 break; // Custom-compiled handler. |
| 1146 } | 1197 } |
| 1147 | 1198 |
| 1148 // -------------- Constant properties -------------- | 1199 // -------------- Constant properties -------------- |
| 1149 DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 1200 DCHECK(lookup->property_details().type() == DATA_CONSTANT); |
| 1150 if (receiver_is_holder) { | 1201 if (receiver_is_holder) { |
| 1151 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); | 1202 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |
| 1152 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); | 1203 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); |
| 1153 return stub.GetCode(); | 1204 return stub.GetCode(); |
| 1154 } | 1205 } |
| (...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2899 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 2950 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 2900 it.Next(); | 2951 it.Next(); |
| 2901 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2952 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2902 Object::GetProperty(&it)); | 2953 Object::GetProperty(&it)); |
| 2903 } | 2954 } |
| 2904 | 2955 |
| 2905 return *result; | 2956 return *result; |
| 2906 } | 2957 } |
| 2907 } // namespace internal | 2958 } // namespace internal |
| 2908 } // namespace v8 | 2959 } // namespace v8 |
| OLD | NEW |