| 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 |