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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 case CONSTANT_FUNCTION: { | 416 case CONSTANT_FUNCTION: { |
417 // Get the constant function and compute the code stub for this | 417 // Get the constant function and compute the code stub for this |
418 // call; used for rewriting to monomorphic state and making sure | 418 // call; used for rewriting to monomorphic state and making sure |
419 // that the code stub is in the stub cache. | 419 // that the code stub is in the stub cache. |
420 JSFunction* function = lookup->GetConstantFunction(); | 420 JSFunction* function = lookup->GetConstantFunction(); |
421 code = StubCache::ComputeCallConstant(argc, in_loop, *name, *object, | 421 code = StubCache::ComputeCallConstant(argc, in_loop, *name, *object, |
422 lookup->holder(), function); | 422 lookup->holder(), function); |
423 break; | 423 break; |
424 } | 424 } |
425 case NORMAL: { | 425 case NORMAL: { |
426 // There is only one shared stub for calling normalized | |
427 // properties. It does not traverse the prototype chain, so the | |
428 // property must be found in the receiver for the stub to be | |
429 // applicable. | |
430 if (!object->IsJSObject()) return; | 426 if (!object->IsJSObject()) return; |
431 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 427 if (object->IsJSGlobalObject()) { |
432 if (lookup->holder() != *receiver) return; | 428 // The stub generated for the global object picks the value directly |
433 code = StubCache::ComputeCallNormal(argc, in_loop, *name, *receiver); | 429 // from the property cell. So the property must be directly on the |
| 430 // global object. |
| 431 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object); |
| 432 if (lookup->holder() != *global) return; |
| 433 JSGlobalPropertyCell* cell = |
| 434 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
| 435 if (cell->value()->IsJSFunction()) { |
| 436 JSFunction* function = JSFunction::cast(cell->value()); |
| 437 code = StubCache::ComputeCallGlobal(argc, in_loop, *name, *global, |
| 438 cell, function); |
| 439 } |
| 440 } else { |
| 441 // There is only one shared stub for calling normalized |
| 442 // properties. It does not traverse the prototype chain, so the |
| 443 // property must be found in the receiver for the stub to be |
| 444 // applicable. |
| 445 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 446 if (lookup->holder() != *receiver) return; |
| 447 code = StubCache::ComputeCallNormal(argc, in_loop, *name, *receiver); |
| 448 } |
434 break; | 449 break; |
435 } | 450 } |
436 case INTERCEPTOR: { | 451 case INTERCEPTOR: { |
437 code = StubCache::ComputeCallInterceptor(argc, *name, *object, | 452 code = StubCache::ComputeCallInterceptor(argc, *name, *object, |
438 lookup->holder()); | 453 lookup->holder()); |
439 break; | 454 break; |
440 } | 455 } |
441 default: | 456 default: |
442 return; | 457 return; |
443 } | 458 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 lookup->GetFieldIndex()); | 622 lookup->GetFieldIndex()); |
608 break; | 623 break; |
609 } | 624 } |
610 case CONSTANT_FUNCTION: { | 625 case CONSTANT_FUNCTION: { |
611 Object* constant = lookup->GetConstantFunction(); | 626 Object* constant = lookup->GetConstantFunction(); |
612 code = StubCache::ComputeLoadConstant(*name, *receiver, | 627 code = StubCache::ComputeLoadConstant(*name, *receiver, |
613 lookup->holder(), constant); | 628 lookup->holder(), constant); |
614 break; | 629 break; |
615 } | 630 } |
616 case NORMAL: { | 631 case NORMAL: { |
617 // There is only one shared stub for loading normalized | 632 if (object->IsJSGlobalObject()) { |
618 // properties. It does not traverse the prototype chain, so the | 633 // The stub generated for the global object picks the value directly |
619 // property must be found in the receiver for the stub to be | 634 // from the property cell. So the property must be directly on the |
620 // applicable. | 635 // global object. |
621 if (lookup->holder() != *receiver) return; | 636 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object); |
622 code = StubCache::ComputeLoadNormal(*name, *receiver); | 637 if (lookup->holder() != *global) return; |
| 638 JSGlobalPropertyCell* cell = |
| 639 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
| 640 code = StubCache::ComputeLoadGlobal(*name, *global, cell); |
| 641 } else { |
| 642 // There is only one shared stub for loading normalized |
| 643 // properties. It does not traverse the prototype chain, so the |
| 644 // property must be found in the receiver for the stub to be |
| 645 // applicable. |
| 646 if (lookup->holder() != *receiver) return; |
| 647 code = StubCache::ComputeLoadNormal(*name, *receiver); |
| 648 } |
623 break; | 649 break; |
624 } | 650 } |
625 case CALLBACKS: { | 651 case CALLBACKS: { |
626 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; | 652 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; |
627 AccessorInfo* callback = | 653 AccessorInfo* callback = |
628 AccessorInfo::cast(lookup->GetCallbackObject()); | 654 AccessorInfo::cast(lookup->GetCallbackObject()); |
629 if (v8::ToCData<Address>(callback->getter()) == 0) return; | 655 if (v8::ToCData<Address>(callback->getter()) == 0) return; |
630 code = StubCache::ComputeLoadCallback(*name, *receiver, | 656 code = StubCache::ComputeLoadCallback(*name, *receiver, |
631 lookup->holder(), callback); | 657 lookup->holder(), callback); |
632 break; | 658 break; |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 } | 972 } |
947 case MAP_TRANSITION: { | 973 case MAP_TRANSITION: { |
948 if (lookup->GetAttributes() != NONE) return; | 974 if (lookup->GetAttributes() != NONE) return; |
949 HandleScope scope; | 975 HandleScope scope; |
950 ASSERT(type == MAP_TRANSITION); | 976 ASSERT(type == MAP_TRANSITION); |
951 Handle<Map> transition(lookup->GetTransitionMap()); | 977 Handle<Map> transition(lookup->GetTransitionMap()); |
952 int index = transition->PropertyIndexFor(*name); | 978 int index = transition->PropertyIndexFor(*name); |
953 code = StubCache::ComputeStoreField(*name, *receiver, index, *transition); | 979 code = StubCache::ComputeStoreField(*name, *receiver, index, *transition); |
954 break; | 980 break; |
955 } | 981 } |
| 982 case NORMAL: { |
| 983 if (!receiver->IsJSGlobalObject()) { |
| 984 return; |
| 985 } |
| 986 // The stub generated for the global object picks the value directly |
| 987 // from the property cell. So the property must be directly on the |
| 988 // global object. |
| 989 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver); |
| 990 JSGlobalPropertyCell* cell = |
| 991 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); |
| 992 code = StubCache::ComputeStoreGlobal(*name, *global, cell); |
| 993 break; |
| 994 } |
956 case CALLBACKS: { | 995 case CALLBACKS: { |
957 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; | 996 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; |
958 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 997 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
959 if (v8::ToCData<Address>(callback->setter()) == 0) return; | 998 if (v8::ToCData<Address>(callback->setter()) == 0) return; |
960 code = StubCache::ComputeStoreCallback(*name, *receiver, callback); | 999 code = StubCache::ComputeStoreCallback(*name, *receiver, callback); |
961 break; | 1000 break; |
962 } | 1001 } |
963 case INTERCEPTOR: { | 1002 case INTERCEPTOR: { |
964 code = StubCache::ComputeStoreInterceptor(*name, *receiver); | 1003 code = StubCache::ComputeStoreInterceptor(*name, *receiver); |
965 break; | 1004 break; |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 #undef ADDR | 1323 #undef ADDR |
1285 }; | 1324 }; |
1286 | 1325 |
1287 | 1326 |
1288 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1327 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1289 return IC_utilities[id]; | 1328 return IC_utilities[id]; |
1290 } | 1329 } |
1291 | 1330 |
1292 | 1331 |
1293 } } // namespace v8::internal | 1332 } } // namespace v8::internal |
OLD | NEW |