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

Side by Side Diff: src/ic.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments. Created 9 years, 7 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/ic.h ('k') | src/objects-inl.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 case Code::COMPARE_IC: 311 case Code::COMPARE_IC:
312 // Clearing these is tricky and does not 312 // Clearing these is tricky and does not
313 // make any performance difference. 313 // make any performance difference.
314 return; 314 return;
315 default: UNREACHABLE(); 315 default: UNREACHABLE();
316 } 316 }
317 } 317 }
318 318
319 319
320 void CallICBase::Clear(Address address, Code* target) { 320 void CallICBase::Clear(Address address, Code* target) {
321 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state());
321 State state = target->ic_state(); 322 State state = target->ic_state();
322 if (state == UNINITIALIZED) return; 323 if (state == UNINITIALIZED) return;
323 Code* code = 324 Code* code =
324 Isolate::Current()->stub_cache()->FindCallInitialize( 325 Isolate::Current()->stub_cache()->FindCallInitialize(
325 target->arguments_count(), 326 target->arguments_count(),
326 target->ic_in_loop(), 327 target->ic_in_loop(),
328 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET,
327 target->kind()); 329 target->kind());
328 SetTargetAtAddress(address, code); 330 SetTargetAtAddress(address, code);
329 } 331 }
330 332
331 333
332 void KeyedLoadIC::Clear(Address address, Code* target) { 334 void KeyedLoadIC::Clear(Address address, Code* target) {
333 if (target->ic_state() == UNINITIALIZED) return; 335 if (target->ic_state() == UNINITIALIZED) return;
334 // Make sure to also clear the map used in inline fast cases. If we 336 // Make sure to also clear the map used in inline fast cases. If we
335 // do not clear these maps, cached code can keep objects alive 337 // do not clear these maps, cached code can keep objects alive
336 // through the embedded maps. 338 // through the embedded maps.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 argc * kPointerSize)); 569 argc * kPointerSize));
568 switch (function->shared()->builtin_function_id()) { 570 switch (function->shared()->builtin_function_id()) {
569 case kStringCharCodeAt: 571 case kStringCharCodeAt:
570 case kStringCharAt: 572 case kStringCharAt:
571 if (object->IsString()) { 573 if (object->IsString()) {
572 String* string = String::cast(*object); 574 String* string = String::cast(*object);
573 // Check there's the right string value or wrapper in the receiver slot. 575 // Check there's the right string value or wrapper in the receiver slot.
574 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); 576 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
575 // If we're in the default (fastest) state and the index is 577 // If we're in the default (fastest) state and the index is
576 // out of bounds, update the state to record this fact. 578 // out of bounds, update the state to record this fact.
577 if (*extra_ic_state == DEFAULT_STRING_STUB && 579 if (StringStubState::decode(*extra_ic_state) == DEFAULT_STRING_STUB &&
578 argc >= 1 && args[1]->IsNumber()) { 580 argc >= 1 && args[1]->IsNumber()) {
579 double index; 581 double index;
580 if (args[1]->IsSmi()) { 582 if (args[1]->IsSmi()) {
581 index = Smi::cast(args[1])->value(); 583 index = Smi::cast(args[1])->value();
582 } else { 584 } else {
583 ASSERT(args[1]->IsHeapNumber()); 585 ASSERT(args[1]->IsHeapNumber());
584 index = DoubleToInteger(HeapNumber::cast(args[1])->value()); 586 index = DoubleToInteger(HeapNumber::cast(args[1])->value());
585 } 587 }
586 if (index < 0 || index >= string->length()) { 588 if (index < 0 || index >= string->length()) {
587 *extra_ic_state = STRING_INDEX_OUT_OF_BOUNDS; 589 *extra_ic_state =
590 StringStubState::update(*extra_ic_state,
591 STRING_INDEX_OUT_OF_BOUNDS);
588 return true; 592 return true;
589 } 593 }
590 } 594 }
591 } 595 }
592 break; 596 break;
593 default: 597 default:
594 return false; 598 return false;
595 } 599 }
596 return false; 600 return false;
597 } 601 }
598 602
599 603
600 MaybeObject* CallICBase::ComputeMonomorphicStub( 604 MaybeObject* CallICBase::ComputeMonomorphicStub(
601 LookupResult* lookup, 605 LookupResult* lookup,
602 State state, 606 State state,
603 Code::ExtraICState extra_ic_state, 607 Code::ExtraICState extra_ic_state,
604 Handle<Object> object, 608 Handle<Object> object,
605 Handle<String> name) { 609 Handle<String> name) {
606 int argc = target()->arguments_count(); 610 int argc = target()->arguments_count();
607 InLoopFlag in_loop = target()->ic_in_loop(); 611 InLoopFlag in_loop = target()->ic_in_loop();
608 MaybeObject* maybe_code = NULL; 612 MaybeObject* maybe_code = NULL;
609 switch (lookup->type()) { 613 switch (lookup->type()) {
610 case FIELD: { 614 case FIELD: {
611 int index = lookup->GetFieldIndex(); 615 int index = lookup->GetFieldIndex();
612 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, 616 maybe_code = isolate()->stub_cache()->ComputeCallField(argc,
613 in_loop, 617 in_loop,
614 kind_, 618 kind_,
619 extra_ic_state,
615 *name, 620 *name,
616 *object, 621 *object,
617 lookup->holder(), 622 lookup->holder(),
618 index); 623 index);
619 break; 624 break;
620 } 625 }
621 case CONSTANT_FUNCTION: { 626 case CONSTANT_FUNCTION: {
622 // Get the constant function and compute the code stub for this 627 // Get the constant function and compute the code stub for this
623 // call; used for rewriting to monomorphic state and making sure 628 // call; used for rewriting to monomorphic state and making sure
624 // that the code stub is in the stub cache. 629 // that the code stub is in the stub cache.
(...skipping 15 matching lines...) Expand all
640 645
641 if (lookup->holder()->IsGlobalObject()) { 646 if (lookup->holder()->IsGlobalObject()) {
642 GlobalObject* global = GlobalObject::cast(lookup->holder()); 647 GlobalObject* global = GlobalObject::cast(lookup->holder());
643 JSGlobalPropertyCell* cell = 648 JSGlobalPropertyCell* cell =
644 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 649 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
645 if (!cell->value()->IsJSFunction()) return NULL; 650 if (!cell->value()->IsJSFunction()) return NULL;
646 JSFunction* function = JSFunction::cast(cell->value()); 651 JSFunction* function = JSFunction::cast(cell->value());
647 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, 652 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc,
648 in_loop, 653 in_loop,
649 kind_, 654 kind_,
655 extra_ic_state,
650 *name, 656 *name,
651 *receiver, 657 *receiver,
652 global, 658 global,
653 cell, 659 cell,
654 function); 660 function);
655 } else { 661 } else {
656 // There is only one shared stub for calling normalized 662 // There is only one shared stub for calling normalized
657 // properties. It does not traverse the prototype chain, so the 663 // properties. It does not traverse the prototype chain, so the
658 // property must be found in the receiver for the stub to be 664 // property must be found in the receiver for the stub to be
659 // applicable. 665 // applicable.
660 if (lookup->holder() != *receiver) return NULL; 666 if (lookup->holder() != *receiver) return NULL;
661 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, 667 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc,
662 in_loop, 668 in_loop,
663 kind_, 669 kind_,
670 extra_ic_state,
664 *name, 671 *name,
665 *receiver); 672 *receiver);
666 } 673 }
667 break; 674 break;
668 } 675 }
669 case INTERCEPTOR: { 676 case INTERCEPTOR: {
670 ASSERT(HasInterceptorGetter(lookup->holder())); 677 ASSERT(HasInterceptorGetter(lookup->holder()));
671 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( 678 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor(
672 argc, 679 argc,
673 kind_, 680 kind_,
681 extra_ic_state,
674 *name, 682 *name,
675 *object, 683 *object,
676 lookup->holder()); 684 lookup->holder());
677 break; 685 break;
678 } 686 }
679 default: 687 default:
680 maybe_code = NULL; 688 maybe_code = NULL;
681 break; 689 break;
682 } 690 }
683 return maybe_code; 691 return maybe_code;
(...skipping 18 matching lines...) Expand all
702 710
703 // Compute the number of arguments. 711 // Compute the number of arguments.
704 int argc = target()->arguments_count(); 712 int argc = target()->arguments_count();
705 InLoopFlag in_loop = target()->ic_in_loop(); 713 InLoopFlag in_loop = target()->ic_in_loop();
706 MaybeObject* maybe_code = NULL; 714 MaybeObject* maybe_code = NULL;
707 bool had_proto_failure = false; 715 bool had_proto_failure = false;
708 if (state == UNINITIALIZED) { 716 if (state == UNINITIALIZED) {
709 // This is the first time we execute this inline cache. 717 // This is the first time we execute this inline cache.
710 // Set the target to the pre monomorphic stub to delay 718 // Set the target to the pre monomorphic stub to delay
711 // setting the monomorphic state. 719 // setting the monomorphic state.
712 maybe_code = isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, 720 maybe_code =
713 in_loop, 721 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc,
714 kind_); 722 in_loop,
723 kind_,
724 extra_ic_state);
715 } else if (state == MONOMORPHIC) { 725 } else if (state == MONOMORPHIC) {
716 if (kind_ == Code::CALL_IC && 726 if (kind_ == Code::CALL_IC &&
717 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 727 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
718 maybe_code = ComputeMonomorphicStub(lookup, 728 maybe_code = ComputeMonomorphicStub(lookup,
719 state, 729 state,
720 extra_ic_state, 730 extra_ic_state,
721 object, 731 object,
722 name); 732 name);
723 } else if (kind_ == Code::CALL_IC && 733 } else if (kind_ == Code::CALL_IC &&
724 TryRemoveInvalidPrototypeDependentStub(target(), 734 TryRemoveInvalidPrototypeDependentStub(target(),
725 *object, 735 *object,
726 *name)) { 736 *name)) {
727 had_proto_failure = true; 737 had_proto_failure = true;
728 maybe_code = ComputeMonomorphicStub(lookup, 738 maybe_code = ComputeMonomorphicStub(lookup,
729 state, 739 state,
730 extra_ic_state, 740 extra_ic_state,
731 object, 741 object,
732 name); 742 name);
733 } else { 743 } else {
734 maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(argc, 744 maybe_code =
735 in_loop, 745 isolate()->stub_cache()->ComputeCallMegamorphic(argc,
736 kind_); 746 in_loop,
747 kind_,
748 extra_ic_state);
737 } 749 }
738 } else { 750 } else {
739 maybe_code = ComputeMonomorphicStub(lookup, 751 maybe_code = ComputeMonomorphicStub(lookup,
740 state, 752 state,
741 extra_ic_state, 753 extra_ic_state,
742 object, 754 object,
743 name); 755 name);
744 } 756 }
745 757
746 // If we're unable to compute the stub (not enough memory left), we 758 // If we're unable to compute the stub (not enough memory left), we
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } 796 }
785 797
786 if (object->IsUndefined() || object->IsNull()) { 798 if (object->IsUndefined() || object->IsNull()) {
787 return TypeError("non_object_property_call", object, key); 799 return TypeError("non_object_property_call", object, key);
788 } 800 }
789 801
790 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { 802 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
791 int argc = target()->arguments_count(); 803 int argc = target()->arguments_count();
792 InLoopFlag in_loop = target()->ic_in_loop(); 804 InLoopFlag in_loop = target()->ic_in_loop();
793 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( 805 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
794 argc, in_loop, Code::KEYED_CALL_IC); 806 argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState);
795 Object* code; 807 Object* code;
796 if (maybe_code->ToObject(&code)) { 808 if (maybe_code->ToObject(&code)) {
797 set_target(Code::cast(code)); 809 set_target(Code::cast(code));
798 #ifdef DEBUG 810 #ifdef DEBUG
799 TraceIC( 811 TraceIC(
800 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); 812 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
801 #endif 813 #endif
802 } 814 }
803 } 815 }
804 816
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 #undef ADDR 2568 #undef ADDR
2557 }; 2569 };
2558 2570
2559 2571
2560 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2572 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2561 return IC_utilities[id]; 2573 return IC_utilities[id];
2562 } 2574 }
2563 2575
2564 2576
2565 } } // namespace v8::internal 2577 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698