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 <iostream> | 7 #include <iostream> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/api-arguments-inl.h" | 10 #include "src/api-arguments-inl.h" |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 } | 908 } |
909 | 909 |
910 } // namespace | 910 } // namespace |
911 | 911 |
912 int LoadIC::GetPrototypeCheckCount(Handle<Map> receiver_map, | 912 int LoadIC::GetPrototypeCheckCount(Handle<Map> receiver_map, |
913 Handle<JSObject> holder) { | 913 Handle<JSObject> holder) { |
914 return InitPrototypeChecks<false>(isolate(), receiver_map, holder, | 914 return InitPrototypeChecks<false>(isolate(), receiver_map, holder, |
915 Handle<FixedArray>(), Handle<Name>()); | 915 Handle<FixedArray>(), Handle<Name>()); |
916 } | 916 } |
917 | 917 |
918 Handle<Object> LoadIC::SimpleLoadFromPrototype(Handle<Map> receiver_map, | 918 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, |
919 Handle<JSObject> holder, | 919 Handle<JSObject> holder, |
920 Handle<Name> name, | 920 Handle<Name> name, |
921 Handle<Object> smi_handler) { | 921 Handle<Object> smi_handler) { |
922 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 922 int checks_count = GetPrototypeCheckCount(receiver_map, holder); |
923 DCHECK_LE(0, checks_count); | 923 DCHECK_LE(0, checks_count); |
924 | 924 |
925 if (receiver_map->IsJSGlobalObjectMap()) { | 925 if (receiver_map->IsJSGlobalObjectMap()) { |
926 UNREACHABLE(); | 926 UNREACHABLE(); |
927 } else if (receiver_map->is_dictionary_map()) { | 927 } else if (receiver_map->is_dictionary_map()) { |
928 smi_handler = | 928 smi_handler = |
929 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); | 929 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); |
930 } | 930 } |
931 | 931 |
(...skipping 11 matching lines...) Expand all Loading... |
943 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( | 943 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( |
944 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); | 944 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); |
945 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); | 945 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); |
946 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); | 946 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); |
947 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); | 947 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); |
948 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array, | 948 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array, |
949 name); | 949 name); |
950 return handler_array; | 950 return handler_array; |
951 } | 951 } |
952 | 952 |
953 Handle<Object> LoadIC::SimpleLoadNonExistent(Handle<Map> receiver_map, | 953 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, |
954 Handle<Name> name) { | 954 Handle<Name> name) { |
955 Handle<JSObject> holder; // null handle | 955 Handle<JSObject> holder; // null handle |
956 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 956 int checks_count = GetPrototypeCheckCount(receiver_map, holder); |
957 DCHECK_LE(0, checks_count); | 957 DCHECK_LE(0, checks_count); |
958 | 958 |
959 if (receiver_map->IsJSGlobalObjectMap()) { | 959 if (receiver_map->IsJSGlobalObjectMap()) { |
960 UNREACHABLE(); | 960 UNREACHABLE(); |
961 } | 961 } |
962 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( | 962 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( |
963 isolate(), receiver_map->is_dictionary_map()); | 963 isolate(), receiver_map->is_dictionary_map()); |
964 | 964 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 return; | 1036 return; |
1037 } | 1037 } |
1038 | 1038 |
1039 Handle<Object> code; | 1039 Handle<Object> code; |
1040 if (lookup->state() == LookupIterator::JSPROXY || | 1040 if (lookup->state() == LookupIterator::JSPROXY || |
1041 lookup->state() == LookupIterator::ACCESS_CHECK) { | 1041 lookup->state() == LookupIterator::ACCESS_CHECK) { |
1042 code = slow_stub(); | 1042 code = slow_stub(); |
1043 } else if (!lookup->IsFound()) { | 1043 } else if (!lookup->IsFound()) { |
1044 if (kind() == Code::LOAD_IC) { | 1044 if (kind() == Code::LOAD_IC) { |
1045 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); | 1045 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); |
1046 code = SimpleLoadNonExistent(receiver_map(), lookup->name()); | 1046 code = LoadNonExistent(receiver_map(), lookup->name()); |
1047 } else if (kind() == Code::LOAD_GLOBAL_IC) { | 1047 } else if (kind() == Code::LOAD_GLOBAL_IC) { |
1048 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), | 1048 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
1049 receiver_map()); | 1049 receiver_map()); |
1050 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. | 1050 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
1051 if (code.is_null()) code = slow_stub(); | 1051 if (code.is_null()) code = slow_stub(); |
1052 } else { | 1052 } else { |
1053 code = slow_stub(); | 1053 code = slow_stub(); |
1054 } | 1054 } |
1055 } else { | 1055 } else { |
1056 if (kind() == Code::LOAD_GLOBAL_IC && | 1056 if (kind() == Code::LOAD_GLOBAL_IC && |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 return isolate()->builtins()->LoadIC_Normal(); | 1382 return isolate()->builtins()->LoadIC_Normal(); |
1383 } | 1383 } |
1384 | 1384 |
1385 // -------------- Fields -------------- | 1385 // -------------- Fields -------------- |
1386 if (lookup->property_details().type() == DATA) { | 1386 if (lookup->property_details().type() == DATA) { |
1387 FieldIndex field = lookup->GetFieldIndex(); | 1387 FieldIndex field = lookup->GetFieldIndex(); |
1388 Handle<Object> smi_handler = SimpleFieldLoad(field); | 1388 Handle<Object> smi_handler = SimpleFieldLoad(field); |
1389 if (receiver_is_holder) { | 1389 if (receiver_is_holder) { |
1390 return smi_handler; | 1390 return smi_handler; |
1391 } | 1391 } |
1392 if (FLAG_tf_load_ic_stub && GetPrototypeCheckCount(map, holder) >= 0) { | 1392 if (FLAG_tf_load_ic_stub && kind() != Code::LOAD_GLOBAL_IC) { |
1393 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); | 1393 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); |
1394 return SimpleLoadFromPrototype(map, holder, lookup->name(), | 1394 return LoadFromPrototype(map, holder, lookup->name(), smi_handler); |
1395 smi_handler); | |
1396 } | 1395 } |
1397 break; // Custom-compiled handler. | 1396 break; // Custom-compiled handler. |
1398 } | 1397 } |
1399 | 1398 |
1400 // -------------- Constant properties -------------- | 1399 // -------------- Constant properties -------------- |
1401 DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 1400 DCHECK(lookup->property_details().type() == DATA_CONSTANT); |
1402 if (FLAG_tf_load_ic_stub) { | 1401 if (FLAG_tf_load_ic_stub) { |
1403 Handle<Object> smi_handler = | 1402 Handle<Object> smi_handler = |
1404 LoadHandler::LoadConstant(isolate(), lookup->GetConstantIndex()); | 1403 LoadHandler::LoadConstant(isolate(), lookup->GetConstantIndex()); |
1405 if (receiver_is_holder) { | 1404 if (receiver_is_holder) { |
1406 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); | 1405 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); |
1407 return smi_handler; | 1406 return smi_handler; |
1408 } | 1407 } |
1409 if (GetPrototypeCheckCount(map, holder) >= 0) { | 1408 if (kind() != Code::LOAD_GLOBAL_IC) { |
1410 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); | 1409 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); |
1411 return SimpleLoadFromPrototype(map, holder, lookup->name(), | 1410 return LoadFromPrototype(map, holder, lookup->name(), smi_handler); |
1412 smi_handler); | |
1413 } | 1411 } |
1414 } else { | 1412 } else { |
1415 if (receiver_is_holder) { | 1413 if (receiver_is_holder) { |
1416 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); | 1414 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |
1417 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); | 1415 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); |
1418 return stub.GetCode(); | 1416 return stub.GetCode(); |
1419 } | 1417 } |
1420 } | 1418 } |
1421 break; // Custom-compiled handler. | 1419 break; // Custom-compiled handler. |
1422 } | 1420 } |
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3174 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3172 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
3175 it.Next(); | 3173 it.Next(); |
3176 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3174 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
3177 Object::GetProperty(&it)); | 3175 Object::GetProperty(&it)); |
3178 } | 3176 } |
3179 | 3177 |
3180 return *result; | 3178 return *result; |
3181 } | 3179 } |
3182 } // namespace internal | 3180 } // namespace internal |
3183 } // namespace v8 | 3181 } // namespace v8 |
OLD | NEW |