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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 | 891 |
892 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { | 892 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { |
893 bool receiver_is_holder = | 893 bool receiver_is_holder = |
894 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); | 894 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); |
895 CacheHolderFlag flag; | 895 CacheHolderFlag flag; |
896 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( | 896 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( |
897 *receiver_type(), receiver_is_holder, isolate(), &flag); | 897 *receiver_type(), receiver_is_holder, isolate(), &flag); |
898 | 898 |
899 Handle<Code> code = PropertyHandlerCompiler::Find( | 899 Handle<Code> code = PropertyHandlerCompiler::Find( |
900 lookup->name(), stub_holder_map, kind(), flag, | 900 lookup->name(), stub_holder_map, kind(), flag, |
901 lookup->holder_map()->is_dictionary_map() ? Code::NORMAL : Code::FAST); | 901 lookup->is_dictionary_holder() ? Code::NORMAL : Code::FAST); |
902 // Use the cached value if it exists, and if it is different from the | 902 // Use the cached value if it exists, and if it is different from the |
903 // handler that just missed. | 903 // handler that just missed. |
904 if (!code.is_null()) { | 904 if (!code.is_null()) { |
905 if (!maybe_handler_.is_null() && | 905 if (!maybe_handler_.is_null() && |
906 !maybe_handler_.ToHandleChecked().is_identical_to(code)) { | 906 !maybe_handler_.ToHandleChecked().is_identical_to(code)) { |
907 return code; | 907 return code; |
908 } | 908 } |
909 if (maybe_handler_.is_null()) { | 909 if (maybe_handler_.is_null()) { |
910 // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs. | 910 // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs. |
911 // In MEGAMORPHIC case, check if the handler in the megamorphic stub | 911 // In MEGAMORPHIC case, check if the handler in the megamorphic stub |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 } | 1026 } |
1027 return compiler.CompileLoadViaGetter(lookup->name(), function); | 1027 return compiler.CompileLoadViaGetter(lookup->name(), function); |
1028 } | 1028 } |
1029 // TODO(dcarney): Handle correctly. | 1029 // TODO(dcarney): Handle correctly. |
1030 DCHECK(accessors->IsDeclaredAccessorInfo()); | 1030 DCHECK(accessors->IsDeclaredAccessorInfo()); |
1031 return slow_stub(); | 1031 return slow_stub(); |
1032 } | 1032 } |
1033 | 1033 |
1034 // -------------- Dictionary properties -------------- | 1034 // -------------- Dictionary properties -------------- |
1035 DCHECK(lookup->state() == LookupIterator::DATA); | 1035 DCHECK(lookup->state() == LookupIterator::DATA); |
1036 if (lookup->property_encoding() == LookupIterator::DICTIONARY) { | 1036 if (lookup->is_dictionary_holder()) { |
1037 if (kind() != Code::LOAD_IC) return slow_stub(); | 1037 if (kind() != Code::LOAD_IC) return slow_stub(); |
1038 if (holder->IsGlobalObject()) { | 1038 if (holder->IsGlobalObject()) { |
1039 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, | 1039 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, |
1040 cache_holder); | 1040 cache_holder); |
1041 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 1041 Handle<PropertyCell> cell = lookup->GetPropertyCell(); |
1042 Handle<Code> code = compiler.CompileLoadGlobal(cell, lookup->name(), | 1042 Handle<Code> code = compiler.CompileLoadGlobal(cell, lookup->name(), |
1043 lookup->IsConfigurable()); | 1043 lookup->IsConfigurable()); |
1044 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1044 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
1045 CacheHolderFlag flag; | 1045 CacheHolderFlag flag; |
1046 Handle<Map> stub_holder_map = | 1046 Handle<Map> stub_holder_map = |
1047 GetHandlerCacheHolder(*type, receiver_is_holder, isolate(), &flag); | 1047 GetHandlerCacheHolder(*type, receiver_is_holder, isolate(), &flag); |
1048 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); | 1048 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); |
1049 return code; | 1049 return code; |
1050 } | 1050 } |
1051 // There is only one shared stub for loading normalized | 1051 // There is only one shared stub for loading normalized |
1052 // properties. It does not traverse the prototype chain, so the | 1052 // properties. It does not traverse the prototype chain, so the |
1053 // property must be found in the object for the stub to be | 1053 // property must be found in the object for the stub to be |
1054 // applicable. | 1054 // applicable. |
1055 if (!receiver_is_holder) return slow_stub(); | 1055 if (!receiver_is_holder) return slow_stub(); |
1056 return isolate()->builtins()->LoadIC_Normal(); | 1056 return isolate()->builtins()->LoadIC_Normal(); |
1057 } | 1057 } |
1058 | 1058 |
1059 // -------------- Fields -------------- | 1059 // -------------- Fields -------------- |
1060 DCHECK(lookup->property_encoding() == LookupIterator::DESCRIPTOR); | |
1061 if (lookup->property_details().type() == FIELD) { | 1060 if (lookup->property_details().type() == FIELD) { |
1062 FieldIndex field = lookup->GetFieldIndex(); | 1061 FieldIndex field = lookup->GetFieldIndex(); |
1063 if (receiver_is_holder) { | 1062 if (receiver_is_holder) { |
1064 return SimpleFieldLoad(field); | 1063 return SimpleFieldLoad(field); |
1065 } | 1064 } |
1066 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, | 1065 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, |
1067 cache_holder); | 1066 cache_holder); |
1068 return compiler.CompileLoadField(lookup->name(), field); | 1067 return compiler.CompileLoadField(lookup->name(), field); |
1069 } | 1068 } |
1070 | 1069 |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 return compiler.CompileStoreViaSetter(receiver, lookup->name(), | 1447 return compiler.CompileStoreViaSetter(receiver, lookup->name(), |
1449 Handle<JSFunction>::cast(setter)); | 1448 Handle<JSFunction>::cast(setter)); |
1450 } | 1449 } |
1451 // TODO(dcarney): Handle correctly. | 1450 // TODO(dcarney): Handle correctly. |
1452 DCHECK(accessors->IsDeclaredAccessorInfo()); | 1451 DCHECK(accessors->IsDeclaredAccessorInfo()); |
1453 return slow_stub(); | 1452 return slow_stub(); |
1454 } | 1453 } |
1455 | 1454 |
1456 // -------------- Dictionary properties -------------- | 1455 // -------------- Dictionary properties -------------- |
1457 DCHECK(lookup->state() == LookupIterator::DATA); | 1456 DCHECK(lookup->state() == LookupIterator::DATA); |
1458 if (lookup->property_encoding() == LookupIterator::DICTIONARY) { | 1457 if (lookup->is_dictionary_holder()) { |
1459 if (holder->IsGlobalObject()) { | 1458 if (holder->IsGlobalObject()) { |
1460 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 1459 Handle<PropertyCell> cell = lookup->GetPropertyCell(); |
1461 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); | 1460 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); |
1462 StoreGlobalStub stub(isolate(), union_type->IsConstant(), | 1461 StoreGlobalStub stub(isolate(), union_type->IsConstant(), |
1463 receiver->IsJSGlobalProxy()); | 1462 receiver->IsJSGlobalProxy()); |
1464 Handle<Code> code = stub.GetCodeCopyFromTemplate( | 1463 Handle<Code> code = stub.GetCodeCopyFromTemplate( |
1465 Handle<GlobalObject>::cast(holder), cell); | 1464 Handle<GlobalObject>::cast(holder), cell); |
1466 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1465 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
1467 HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code); | 1466 HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code); |
1468 return code; | 1467 return code; |
1469 } | 1468 } |
1470 DCHECK(holder.is_identical_to(receiver)); | 1469 DCHECK(holder.is_identical_to(receiver)); |
1471 return isolate()->builtins()->StoreIC_Normal(); | 1470 return isolate()->builtins()->StoreIC_Normal(); |
1472 } | 1471 } |
1473 | 1472 |
1474 // -------------- Fields -------------- | 1473 // -------------- Fields -------------- |
1475 DCHECK(lookup->property_encoding() == LookupIterator::DESCRIPTOR); | |
1476 if (lookup->property_details().type() == FIELD) { | 1474 if (lookup->property_details().type() == FIELD) { |
1477 bool use_stub = true; | 1475 bool use_stub = true; |
1478 if (lookup->representation().IsHeapObject()) { | 1476 if (lookup->representation().IsHeapObject()) { |
1479 // Only use a generic stub if no types need to be tracked. | 1477 // Only use a generic stub if no types need to be tracked. |
1480 Handle<HeapType> field_type = lookup->GetFieldType(); | 1478 Handle<HeapType> field_type = lookup->GetFieldType(); |
1481 HeapType::Iterator<Map> it = field_type->Classes(); | 1479 HeapType::Iterator<Map> it = field_type->Classes(); |
1482 use_stub = it.Done(); | 1480 use_stub = it.Done(); |
1483 } | 1481 } |
1484 if (use_stub) { | 1482 if (use_stub) { |
1485 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | 1483 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |
(...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3201 static const Address IC_utilities[] = { | 3199 static const Address IC_utilities[] = { |
3202 #define ADDR(name) FUNCTION_ADDR(name), | 3200 #define ADDR(name) FUNCTION_ADDR(name), |
3203 IC_UTIL_LIST(ADDR) NULL | 3201 IC_UTIL_LIST(ADDR) NULL |
3204 #undef ADDR | 3202 #undef ADDR |
3205 }; | 3203 }; |
3206 | 3204 |
3207 | 3205 |
3208 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3206 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
3209 } | 3207 } |
3210 } // namespace v8::internal | 3208 } // namespace v8::internal |
OLD | NEW |