Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/ic.cc

Issue 422023003: Encapsulate the holder in the PropertyHolderCompilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/codegen.h" 10 #include "src/codegen.h"
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 Handle<JSFunction>::cast(object)->should_have_prototype() && 935 Handle<JSFunction>::cast(object)->should_have_prototype() &&
936 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) { 936 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) {
937 Handle<Code> stub; 937 Handle<Code> stub;
938 FunctionPrototypeStub function_prototype_stub(isolate()); 938 FunctionPrototypeStub function_prototype_stub(isolate());
939 return function_prototype_stub.GetCode(); 939 return function_prototype_stub.GetCode();
940 } 940 }
941 941
942 Handle<HeapType> type = receiver_type(); 942 Handle<HeapType> type = receiver_type();
943 Handle<JSObject> holder(lookup->holder()); 943 Handle<JSObject> holder(lookup->holder());
944 bool receiver_is_holder = object.is_identical_to(holder); 944 bool receiver_is_holder = object.is_identical_to(holder);
945 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), cache_holder); 945 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder,
946 cache_holder);
946 947
947 switch (lookup->type()) { 948 switch (lookup->type()) {
948 case FIELD: { 949 case FIELD: {
949 FieldIndex field = lookup->GetFieldIndex(); 950 FieldIndex field = lookup->GetFieldIndex();
950 if (receiver_is_holder) { 951 if (receiver_is_holder) {
951 return SimpleFieldLoad(field); 952 return SimpleFieldLoad(field);
952 } 953 }
953 return compiler.CompileLoadField(holder, name, field, 954 return compiler.CompileLoadField(name, field, lookup->representation());
954 lookup->representation());
955 } 955 }
956 case CONSTANT: { 956 case CONSTANT: {
957 Handle<Object> constant(lookup->GetConstant(), isolate()); 957 Handle<Object> constant(lookup->GetConstant(), isolate());
958 return compiler.CompileLoadConstant(holder, name, constant); 958 return compiler.CompileLoadConstant(name, constant);
959 } 959 }
960 case NORMAL: 960 case NORMAL:
961 if (kind() != Code::LOAD_IC) break; 961 if (kind() != Code::LOAD_IC) break;
962 if (holder->IsGlobalObject()) { 962 if (holder->IsGlobalObject()) {
963 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 963 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
964 Handle<PropertyCell> cell( 964 Handle<PropertyCell> cell(
965 global->GetPropertyCell(lookup), isolate()); 965 global->GetPropertyCell(lookup), isolate());
966 Handle<Code> code = compiler.CompileLoadGlobal(global, cell, name, 966 Handle<Code> code =
967 lookup->IsDontDelete()); 967 compiler.CompileLoadGlobal(cell, name, lookup->IsDontDelete());
968 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 968 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
969 CacheHolderFlag flag; 969 CacheHolderFlag flag;
970 Handle<Map> stub_holder_map = 970 Handle<Map> stub_holder_map =
971 GetHandlerCacheHolder(*type, receiver_is_holder, isolate(), &flag); 971 GetHandlerCacheHolder(*type, receiver_is_holder, isolate(), &flag);
972 Map::UpdateCodeCache(stub_holder_map, name, code); 972 Map::UpdateCodeCache(stub_holder_map, name, code);
973 return code; 973 return code;
974 } 974 }
975 // There is only one shared stub for loading normalized 975 // There is only one shared stub for loading normalized
976 // properties. It does not traverse the prototype chain, so the 976 // properties. It does not traverse the prototype chain, so the
977 // property must be found in the object for the stub to be 977 // property must be found in the object for the stub to be
(...skipping 16 matching lines...) Expand all
994 994
995 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 995 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
996 if (callback->IsExecutableAccessorInfo()) { 996 if (callback->IsExecutableAccessorInfo()) {
997 Handle<ExecutableAccessorInfo> info = 997 Handle<ExecutableAccessorInfo> info =
998 Handle<ExecutableAccessorInfo>::cast(callback); 998 Handle<ExecutableAccessorInfo>::cast(callback);
999 if (v8::ToCData<Address>(info->getter()) == 0) break; 999 if (v8::ToCData<Address>(info->getter()) == 0) break;
1000 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, 1000 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info,
1001 type)) { 1001 type)) {
1002 break; 1002 break;
1003 } 1003 }
1004 return compiler.CompileLoadCallback(holder, name, info); 1004 if (holder->IsGlobalObject()) break;
1005 return compiler.CompileLoadCallback(name, info);
1005 } else if (callback->IsAccessorPair()) { 1006 } else if (callback->IsAccessorPair()) {
1006 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), 1007 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
1007 isolate()); 1008 isolate());
1008 if (!getter->IsJSFunction()) break; 1009 if (!getter->IsJSFunction()) break;
1009 if (holder->IsGlobalObject()) break; 1010 if (holder->IsGlobalObject()) break;
1010 if (!holder->HasFastProperties()) break; 1011 if (!holder->HasFastProperties()) break;
1011 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1012 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1012 if (!object->IsJSObject() && 1013 if (!object->IsJSObject() &&
1013 !function->IsBuiltin() && 1014 !function->IsBuiltin() &&
1014 function->shared()->strict_mode() == SLOPPY) { 1015 function->shared()->strict_mode() == SLOPPY) {
1015 // Calling sloppy non-builtins with a value as the receiver 1016 // Calling sloppy non-builtins with a value as the receiver
1016 // requires boxing. 1017 // requires boxing.
1017 break; 1018 break;
1018 } 1019 }
1019 CallOptimization call_optimization(function); 1020 CallOptimization call_optimization(function);
1020 if (call_optimization.is_simple_api_call() && 1021 if (call_optimization.is_simple_api_call() &&
1021 call_optimization.IsCompatibleReceiver(object, holder)) { 1022 call_optimization.IsCompatibleReceiver(object, holder)) {
1022 return compiler.CompileLoadCallback(holder, name, call_optimization); 1023 return compiler.CompileLoadCallback(name, call_optimization);
1023 } 1024 }
1024 return compiler.CompileLoadViaGetter(holder, name, function); 1025 return compiler.CompileLoadViaGetter(name, function);
1025 } 1026 }
1026 // TODO(dcarney): Handle correctly. 1027 // TODO(dcarney): Handle correctly.
1027 ASSERT(callback->IsDeclaredAccessorInfo()); 1028 ASSERT(callback->IsDeclaredAccessorInfo());
1028 break; 1029 break;
1029 } 1030 }
1030 case INTERCEPTOR: 1031 case INTERCEPTOR:
1031 ASSERT(HasInterceptorGetter(*holder)); 1032 ASSERT(HasInterceptorGetter(*holder));
1032 return compiler.CompileLoadInterceptor(holder, name); 1033 return compiler.CompileLoadInterceptor(name);
1033 default: 1034 default:
1034 break; 1035 break;
1035 } 1036 }
1036 1037
1037 return slow_stub(); 1038 return slow_stub();
1038 } 1039 }
1039 1040
1040 1041
1041 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { 1042 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
1042 // This helper implements a few common fast cases for converting 1043 // This helper implements a few common fast cases for converting
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 Handle<Object> object, Handle<String> name, 1388 Handle<Object> object, Handle<String> name,
1388 Handle<Object> value, 1389 Handle<Object> value,
1389 CacheHolderFlag cache_holder) { 1390 CacheHolderFlag cache_holder) {
1390 if (object->IsAccessCheckNeeded()) return slow_stub(); 1391 if (object->IsAccessCheckNeeded()) return slow_stub();
1391 ASSERT(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS || 1392 ASSERT(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS ||
1392 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject())); 1393 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject()));
1393 // This is currently guaranteed by checks in StoreIC::Store. 1394 // This is currently guaranteed by checks in StoreIC::Store.
1394 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1395 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1395 1396
1396 Handle<JSObject> holder(lookup->holder()); 1397 Handle<JSObject> holder(lookup->holder());
1397 NamedStoreHandlerCompiler compiler(isolate(), receiver_type()); 1398 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1398 1399
1399 if (lookup->IsTransition()) { 1400 if (lookup->IsTransition()) {
1400 // Explicitly pass in the receiver map since LookupForWrite may have 1401 // Explicitly pass in the receiver map since LookupForWrite may have
1401 // stored something else than the receiver in the holder. 1402 // stored something else than the receiver in the holder.
1402 Handle<Map> transition(lookup->GetTransitionTarget()); 1403 Handle<Map> transition(lookup->GetTransitionTarget());
1403 PropertyDetails details = lookup->GetPropertyDetails(); 1404 PropertyDetails details = lookup->GetPropertyDetails();
1404 1405
1405 if (details.type() != CALLBACKS && details.attributes() == NONE) { 1406 if (details.type() != CALLBACKS && details.attributes() == NONE) {
1406 return compiler.CompileStoreTransition( 1407 return compiler.CompileStoreTransition(lookup, transition, name);
1407 receiver, lookup, transition, name);
1408 } 1408 }
1409 } else { 1409 } else {
1410 switch (lookup->type()) { 1410 switch (lookup->type()) {
1411 case FIELD: 1411 case FIELD:
1412 return compiler.CompileStoreField(receiver, lookup, name); 1412 return compiler.CompileStoreField(lookup, name);
1413 case NORMAL: 1413 case NORMAL:
1414 if (kind() == Code::KEYED_STORE_IC) break; 1414 if (kind() == Code::KEYED_STORE_IC) break;
1415 if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) { 1415 if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
1416 // The stub generated for the global object picks the value directly 1416 // The stub generated for the global object picks the value directly
1417 // from the property cell. So the property must be directly on the 1417 // from the property cell. So the property must be directly on the
1418 // global object. 1418 // global object.
1419 PrototypeIterator iter(isolate(), receiver); 1419 PrototypeIterator iter(isolate(), receiver);
1420 Handle<GlobalObject> global = 1420 Handle<GlobalObject> global =
1421 receiver->IsJSGlobalProxy() 1421 receiver->IsJSGlobalProxy()
1422 ? Handle<GlobalObject>::cast( 1422 ? Handle<GlobalObject>::cast(
(...skipping 14 matching lines...) Expand all
1437 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 1437 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
1438 if (callback->IsExecutableAccessorInfo()) { 1438 if (callback->IsExecutableAccessorInfo()) {
1439 Handle<ExecutableAccessorInfo> info = 1439 Handle<ExecutableAccessorInfo> info =
1440 Handle<ExecutableAccessorInfo>::cast(callback); 1440 Handle<ExecutableAccessorInfo>::cast(callback);
1441 if (v8::ToCData<Address>(info->setter()) == 0) break; 1441 if (v8::ToCData<Address>(info->setter()) == 0) break;
1442 if (!holder->HasFastProperties()) break; 1442 if (!holder->HasFastProperties()) break;
1443 if (!ExecutableAccessorInfo::IsCompatibleReceiverType( 1443 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(
1444 isolate(), info, receiver_type())) { 1444 isolate(), info, receiver_type())) {
1445 break; 1445 break;
1446 } 1446 }
1447 return compiler.CompileStoreCallback(receiver, holder, name, info); 1447 return compiler.CompileStoreCallback(receiver, name, info);
1448 } else if (callback->IsAccessorPair()) { 1448 } else if (callback->IsAccessorPair()) {
1449 Handle<Object> setter( 1449 Handle<Object> setter(
1450 Handle<AccessorPair>::cast(callback)->setter(), isolate()); 1450 Handle<AccessorPair>::cast(callback)->setter(), isolate());
1451 if (!setter->IsJSFunction()) break; 1451 if (!setter->IsJSFunction()) break;
1452 if (holder->IsGlobalObject()) break; 1452 if (holder->IsGlobalObject()) break;
1453 if (!holder->HasFastProperties()) break; 1453 if (!holder->HasFastProperties()) break;
1454 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 1454 Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
1455 CallOptimization call_optimization(function); 1455 CallOptimization call_optimization(function);
1456 if (call_optimization.is_simple_api_call() && 1456 if (call_optimization.is_simple_api_call() &&
1457 call_optimization.IsCompatibleReceiver(receiver, holder)) { 1457 call_optimization.IsCompatibleReceiver(receiver, holder)) {
1458 return compiler.CompileStoreCallback( 1458 return compiler.CompileStoreCallback(receiver, name,
1459 receiver, holder, name, call_optimization); 1459 call_optimization);
1460 } 1460 }
1461 return compiler.CompileStoreViaSetter( 1461 return compiler.CompileStoreViaSetter(
1462 receiver, holder, name, Handle<JSFunction>::cast(setter)); 1462 receiver, name, Handle<JSFunction>::cast(setter));
1463 } 1463 }
1464 // TODO(dcarney): Handle correctly. 1464 // TODO(dcarney): Handle correctly.
1465 ASSERT(callback->IsDeclaredAccessorInfo()); 1465 ASSERT(callback->IsDeclaredAccessorInfo());
1466 break; 1466 break;
1467 } 1467 }
1468 case INTERCEPTOR: 1468 case INTERCEPTOR:
1469 if (kind() == Code::KEYED_STORE_IC) break; 1469 if (kind() == Code::KEYED_STORE_IC) break;
1470 ASSERT(HasInterceptorSetter(*holder)); 1470 ASSERT(HasInterceptorSetter(*holder));
1471 return compiler.CompileStoreInterceptor(receiver, name); 1471 return compiler.CompileStoreInterceptor(name);
1472 case CONSTANT: 1472 case CONSTANT:
1473 break; 1473 break;
1474 case NONEXISTENT: 1474 case NONEXISTENT:
1475 case HANDLER: 1475 case HANDLER:
1476 UNREACHABLE(); 1476 UNREACHABLE();
1477 break; 1477 break;
1478 } 1478 }
1479 } 1479 }
1480 return slow_stub(); 1480 return slow_stub();
1481 } 1481 }
(...skipping 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 #undef ADDR 3053 #undef ADDR
3054 }; 3054 };
3055 3055
3056 3056
3057 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3057 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3058 return IC_utilities[id]; 3058 return IC_utilities[id];
3059 } 3059 }
3060 3060
3061 3061
3062 } } // namespace v8::internal 3062 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698