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