OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 case NORMAL: { | 453 case NORMAL: { |
454 if (!object->IsJSObject()) return; | 454 if (!object->IsJSObject()) return; |
455 if (object->IsGlobalObject()) { | 455 if (object->IsGlobalObject()) { |
456 // The stub generated for the global object picks the value directly | 456 // The stub generated for the global object picks the value directly |
457 // from the property cell. So the property must be directly on the | 457 // from the property cell. So the property must be directly on the |
458 // global object. | 458 // global object. |
459 Handle<GlobalObject> global = Handle<GlobalObject>::cast(object); | 459 Handle<GlobalObject> global = Handle<GlobalObject>::cast(object); |
460 if (lookup->holder() != *global) return; | 460 if (lookup->holder() != *global) return; |
461 JSGlobalPropertyCell* cell = | 461 JSGlobalPropertyCell* cell = |
462 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); | 462 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
463 if (cell->value()->IsJSFunction()) { | 463 if (!cell->value()->IsJSFunction()) return; |
464 JSFunction* function = JSFunction::cast(cell->value()); | 464 JSFunction* function = JSFunction::cast(cell->value()); |
465 code = StubCache::ComputeCallGlobal(argc, in_loop, *name, *global, | 465 code = StubCache::ComputeCallGlobal(argc, in_loop, *name, *global, |
466 cell, function); | 466 cell, function); |
467 } | |
468 } else { | 467 } else { |
469 // There is only one shared stub for calling normalized | 468 // There is only one shared stub for calling normalized |
470 // properties. It does not traverse the prototype chain, so the | 469 // properties. It does not traverse the prototype chain, so the |
471 // property must be found in the receiver for the stub to be | 470 // property must be found in the receiver for the stub to be |
472 // applicable. | 471 // applicable. |
473 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 472 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
474 if (lookup->holder() != *receiver) return; | 473 if (lookup->holder() != *receiver) return; |
475 code = StubCache::ComputeCallNormal(argc, in_loop, *name, *receiver); | 474 code = StubCache::ComputeCallNormal(argc, in_loop, *name, *receiver); |
476 } | 475 } |
477 break; | 476 break; |
478 } | 477 } |
479 case INTERCEPTOR: { | 478 case INTERCEPTOR: { |
480 ASSERT(HasInterceptorGetter(lookup->holder())); | 479 ASSERT(HasInterceptorGetter(lookup->holder())); |
481 code = StubCache::ComputeCallInterceptor(argc, *name, *object, | 480 code = StubCache::ComputeCallInterceptor(argc, *name, *object, |
482 lookup->holder()); | 481 lookup->holder()); |
483 break; | 482 break; |
484 } | 483 } |
485 default: | 484 default: |
486 return; | 485 return; |
487 } | 486 } |
488 } | 487 } |
489 | 488 |
490 // If we're unable to compute the stub (not enough memory left), we | 489 // If we're unable to compute the stub (not enough memory left), we |
491 // simply avoid updating the caches. | 490 // simply avoid updating the caches. |
492 if (code->IsFailure()) return; | 491 if (code == NULL || code->IsFailure()) return; |
493 | 492 |
494 // Patch the call site depending on the state of the cache. | 493 // Patch the call site depending on the state of the cache. |
495 if (state == UNINITIALIZED || | 494 if (state == UNINITIALIZED || |
496 state == PREMONOMORPHIC || | 495 state == PREMONOMORPHIC || |
497 state == MONOMORPHIC || | 496 state == MONOMORPHIC || |
498 state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 497 state == MONOMORPHIC_PROTOTYPE_FAILURE) { |
499 set_target(Code::cast(code)); | 498 set_target(Code::cast(code)); |
500 } | 499 } |
501 | 500 |
502 #ifdef DEBUG | 501 #ifdef DEBUG |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 lookup->holder()); | 692 lookup->holder()); |
694 break; | 693 break; |
695 } | 694 } |
696 default: | 695 default: |
697 return; | 696 return; |
698 } | 697 } |
699 } | 698 } |
700 | 699 |
701 // If we're unable to compute the stub (not enough memory left), we | 700 // If we're unable to compute the stub (not enough memory left), we |
702 // simply avoid updating the caches. | 701 // simply avoid updating the caches. |
703 if (code->IsFailure()) return; | 702 if (code == NULL || code->IsFailure()) return; |
704 | 703 |
705 // Patch the call site depending on the state of the cache. | 704 // Patch the call site depending on the state of the cache. |
706 if (state == UNINITIALIZED || state == PREMONOMORPHIC || | 705 if (state == UNINITIALIZED || state == PREMONOMORPHIC || |
707 state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 706 state == MONOMORPHIC_PROTOTYPE_FAILURE) { |
708 set_target(Code::cast(code)); | 707 set_target(Code::cast(code)); |
709 } else if (state == MONOMORPHIC) { | 708 } else if (state == MONOMORPHIC) { |
710 set_target(megamorphic_stub()); | 709 set_target(megamorphic_stub()); |
711 } | 710 } |
712 | 711 |
713 #ifdef DEBUG | 712 #ifdef DEBUG |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 // Always rewrite to the generic case so that we do not | 882 // Always rewrite to the generic case so that we do not |
884 // repeatedly try to rewrite. | 883 // repeatedly try to rewrite. |
885 code = generic_stub(); | 884 code = generic_stub(); |
886 break; | 885 break; |
887 } | 886 } |
888 } | 887 } |
889 } | 888 } |
890 | 889 |
891 // If we're unable to compute the stub (not enough memory left), we | 890 // If we're unable to compute the stub (not enough memory left), we |
892 // simply avoid updating the caches. | 891 // simply avoid updating the caches. |
893 if (code->IsFailure()) return; | 892 if (code == NULL || code->IsFailure()) return; |
894 | 893 |
895 // Patch the call site depending on the state of the cache. Make | 894 // Patch the call site depending on the state of the cache. Make |
896 // sure to always rewrite from monomorphic to megamorphic. | 895 // sure to always rewrite from monomorphic to megamorphic. |
897 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 896 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); |
898 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 897 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { |
899 set_target(Code::cast(code)); | 898 set_target(Code::cast(code)); |
900 } else if (state == MONOMORPHIC) { | 899 } else if (state == MONOMORPHIC) { |
901 set_target(megamorphic_stub()); | 900 set_target(megamorphic_stub()); |
902 } | 901 } |
903 | 902 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); | 1034 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); |
1036 code = StubCache::ComputeStoreInterceptor(*name, *receiver); | 1035 code = StubCache::ComputeStoreInterceptor(*name, *receiver); |
1037 break; | 1036 break; |
1038 } | 1037 } |
1039 default: | 1038 default: |
1040 return; | 1039 return; |
1041 } | 1040 } |
1042 | 1041 |
1043 // If we're unable to compute the stub (not enough memory left), we | 1042 // If we're unable to compute the stub (not enough memory left), we |
1044 // simply avoid updating the caches. | 1043 // simply avoid updating the caches. |
1045 if (code->IsFailure()) return; | 1044 if (code == NULL || code->IsFailure()) return; |
1046 | 1045 |
1047 // Patch the call site depending on the state of the cache. | 1046 // Patch the call site depending on the state of the cache. |
1048 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 1047 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { |
1049 set_target(Code::cast(code)); | 1048 set_target(Code::cast(code)); |
1050 } else if (state == MONOMORPHIC) { | 1049 } else if (state == MONOMORPHIC) { |
1051 // Only move to mega morphic if the target changes. | 1050 // Only move to mega morphic if the target changes. |
1052 if (target() != Code::cast(code)) set_target(megamorphic_stub()); | 1051 if (target() != Code::cast(code)) set_target(megamorphic_stub()); |
1053 } | 1052 } |
1054 | 1053 |
1055 #ifdef DEBUG | 1054 #ifdef DEBUG |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 default: { | 1156 default: { |
1158 // Always rewrite to the generic case so that we do not | 1157 // Always rewrite to the generic case so that we do not |
1159 // repeatedly try to rewrite. | 1158 // repeatedly try to rewrite. |
1160 code = generic_stub(); | 1159 code = generic_stub(); |
1161 break; | 1160 break; |
1162 } | 1161 } |
1163 } | 1162 } |
1164 | 1163 |
1165 // If we're unable to compute the stub (not enough memory left), we | 1164 // If we're unable to compute the stub (not enough memory left), we |
1166 // simply avoid updating the caches. | 1165 // simply avoid updating the caches. |
1167 if (code->IsFailure()) return; | 1166 if (code == NULL || code->IsFailure()) return; |
1168 | 1167 |
1169 // Patch the call site depending on the state of the cache. Make | 1168 // Patch the call site depending on the state of the cache. Make |
1170 // sure to always rewrite from monomorphic to megamorphic. | 1169 // sure to always rewrite from monomorphic to megamorphic. |
1171 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 1170 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); |
1172 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 1171 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { |
1173 set_target(Code::cast(code)); | 1172 set_target(Code::cast(code)); |
1174 } else if (state == MONOMORPHIC) { | 1173 } else if (state == MONOMORPHIC) { |
1175 set_target(megamorphic_stub()); | 1174 set_target(megamorphic_stub()); |
1176 } | 1175 } |
1177 | 1176 |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1356 #undef ADDR | 1355 #undef ADDR |
1357 }; | 1356 }; |
1358 | 1357 |
1359 | 1358 |
1360 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1359 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1361 return IC_utilities[id]; | 1360 return IC_utilities[id]; |
1362 } | 1361 } |
1363 | 1362 |
1364 | 1363 |
1365 } } // namespace v8::internal | 1364 } } // namespace v8::internal |
OLD | NEW |