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 |