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

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: Fix presubmit 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
OLDNEW
1 // Copyright 2006-2009 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
11 // with the distribution. 11 // with the distribution.
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 case Code::COMPARE_IC: 287 case Code::COMPARE_IC:
288 // Clearing these is tricky and does not 288 // Clearing these is tricky and does not
289 // make any performance difference. 289 // make any performance difference.
290 return; 290 return;
291 default: UNREACHABLE(); 291 default: UNREACHABLE();
292 } 292 }
293 } 293 }
294 294
295 295
296 void CallICBase::Clear(Address address, Code* target) { 296 void CallICBase::Clear(Address address, Code* target) {
297 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state());
297 State state = target->ic_state(); 298 State state = target->ic_state();
298 if (state == UNINITIALIZED) return; 299 if (state == UNINITIALIZED) return;
299 Code* code = 300 Code* code =
300 Isolate::Current()->stub_cache()->FindCallInitialize( 301 Isolate::Current()->stub_cache()->FindCallInitialize(
301 target->arguments_count(), 302 target->arguments_count(),
302 target->ic_in_loop(), 303 target->ic_in_loop(),
304 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET,
303 target->kind()); 305 target->kind());
304 SetTargetAtAddress(address, code); 306 SetTargetAtAddress(address, code);
305 } 307 }
306 308
307 309
308 void KeyedLoadIC::Clear(Address address, Code* target) { 310 void KeyedLoadIC::Clear(Address address, Code* target) {
309 if (target->ic_state() == UNINITIALIZED) return; 311 if (target->ic_state() == UNINITIALIZED) return;
310 // Make sure to also clear the map used in inline fast cases. If we 312 // Make sure to also clear the map used in inline fast cases. If we
311 // do not clear these maps, cached code can keep objects alive 313 // do not clear these maps, cached code can keep objects alive
312 // through the embedded maps. 314 // through the embedded maps.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 argc * kPointerSize)); 545 argc * kPointerSize));
544 switch (function->shared()->builtin_function_id()) { 546 switch (function->shared()->builtin_function_id()) {
545 case kStringCharCodeAt: 547 case kStringCharCodeAt:
546 case kStringCharAt: 548 case kStringCharAt:
547 if (object->IsString()) { 549 if (object->IsString()) {
548 String* string = String::cast(*object); 550 String* string = String::cast(*object);
549 // Check there's the right string value or wrapper in the receiver slot. 551 // Check there's the right string value or wrapper in the receiver slot.
550 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); 552 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
551 // If we're in the default (fastest) state and the index is 553 // If we're in the default (fastest) state and the index is
552 // out of bounds, update the state to record this fact. 554 // out of bounds, update the state to record this fact.
553 if (*extra_ic_state == DEFAULT_STRING_STUB && 555 if (StringStubState::decode(*extra_ic_state) == DEFAULT_STRING_STUB &&
554 argc >= 1 && args[1]->IsNumber()) { 556 argc >= 1 && args[1]->IsNumber()) {
555 double index; 557 double index;
556 if (args[1]->IsSmi()) { 558 if (args[1]->IsSmi()) {
557 index = Smi::cast(args[1])->value(); 559 index = Smi::cast(args[1])->value();
558 } else { 560 } else {
559 ASSERT(args[1]->IsHeapNumber()); 561 ASSERT(args[1]->IsHeapNumber());
560 index = DoubleToInteger(HeapNumber::cast(args[1])->value()); 562 index = DoubleToInteger(HeapNumber::cast(args[1])->value());
561 } 563 }
562 if (index < 0 || index >= string->length()) { 564 if (index < 0 || index >= string->length()) {
563 *extra_ic_state = STRING_INDEX_OUT_OF_BOUNDS; 565 *extra_ic_state =
566 StringStubState::update(*extra_ic_state,
567 STRING_INDEX_OUT_OF_BOUNDS);
564 return true; 568 return true;
565 } 569 }
566 } 570 }
567 } 571 }
568 break; 572 break;
569 default: 573 default:
570 return false; 574 return false;
571 } 575 }
572 return false; 576 return false;
573 } 577 }
574 578
575 579
576 MaybeObject* CallICBase::ComputeMonomorphicStub( 580 MaybeObject* CallICBase::ComputeMonomorphicStub(
577 LookupResult* lookup, 581 LookupResult* lookup,
578 State state, 582 State state,
579 Code::ExtraICState extra_ic_state, 583 Code::ExtraICState extra_ic_state,
580 Handle<Object> object, 584 Handle<Object> object,
581 Handle<String> name) { 585 Handle<String> name) {
582 int argc = target()->arguments_count(); 586 int argc = target()->arguments_count();
583 InLoopFlag in_loop = target()->ic_in_loop(); 587 InLoopFlag in_loop = target()->ic_in_loop();
584 MaybeObject* maybe_code = NULL; 588 MaybeObject* maybe_code = NULL;
585 switch (lookup->type()) { 589 switch (lookup->type()) {
586 case FIELD: { 590 case FIELD: {
587 int index = lookup->GetFieldIndex(); 591 int index = lookup->GetFieldIndex();
588 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, 592 maybe_code = isolate()->stub_cache()->ComputeCallField(argc,
589 in_loop, 593 in_loop,
590 kind_, 594 kind_,
595 extra_ic_state,
591 *name, 596 *name,
592 *object, 597 *object,
593 lookup->holder(), 598 lookup->holder(),
594 index); 599 index);
595 break; 600 break;
596 } 601 }
597 case CONSTANT_FUNCTION: { 602 case CONSTANT_FUNCTION: {
598 // Get the constant function and compute the code stub for this 603 // Get the constant function and compute the code stub for this
599 // call; used for rewriting to monomorphic state and making sure 604 // call; used for rewriting to monomorphic state and making sure
600 // that the code stub is in the stub cache. 605 // that the code stub is in the stub cache.
(...skipping 15 matching lines...) Expand all
616 621
617 if (lookup->holder()->IsGlobalObject()) { 622 if (lookup->holder()->IsGlobalObject()) {
618 GlobalObject* global = GlobalObject::cast(lookup->holder()); 623 GlobalObject* global = GlobalObject::cast(lookup->holder());
619 JSGlobalPropertyCell* cell = 624 JSGlobalPropertyCell* cell =
620 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 625 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
621 if (!cell->value()->IsJSFunction()) return NULL; 626 if (!cell->value()->IsJSFunction()) return NULL;
622 JSFunction* function = JSFunction::cast(cell->value()); 627 JSFunction* function = JSFunction::cast(cell->value());
623 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, 628 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc,
624 in_loop, 629 in_loop,
625 kind_, 630 kind_,
631 extra_ic_state,
626 *name, 632 *name,
627 *receiver, 633 *receiver,
628 global, 634 global,
629 cell, 635 cell,
630 function); 636 function);
631 } else { 637 } else {
632 // There is only one shared stub for calling normalized 638 // There is only one shared stub for calling normalized
633 // properties. It does not traverse the prototype chain, so the 639 // properties. It does not traverse the prototype chain, so the
634 // property must be found in the receiver for the stub to be 640 // property must be found in the receiver for the stub to be
635 // applicable. 641 // applicable.
636 if (lookup->holder() != *receiver) return NULL; 642 if (lookup->holder() != *receiver) return NULL;
637 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, 643 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc,
638 in_loop, 644 in_loop,
639 kind_, 645 kind_,
646 extra_ic_state,
640 *name, 647 *name,
641 *receiver); 648 *receiver);
642 } 649 }
643 break; 650 break;
644 } 651 }
645 case INTERCEPTOR: { 652 case INTERCEPTOR: {
646 ASSERT(HasInterceptorGetter(lookup->holder())); 653 ASSERT(HasInterceptorGetter(lookup->holder()));
647 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( 654 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor(
648 argc, 655 argc,
649 kind_, 656 kind_,
657 extra_ic_state,
650 *name, 658 *name,
651 *object, 659 *object,
652 lookup->holder()); 660 lookup->holder());
653 break; 661 break;
654 } 662 }
655 default: 663 default:
656 maybe_code = NULL; 664 maybe_code = NULL;
657 break; 665 break;
658 } 666 }
659 return maybe_code; 667 return maybe_code;
(...skipping 18 matching lines...) Expand all
678 686
679 // Compute the number of arguments. 687 // Compute the number of arguments.
680 int argc = target()->arguments_count(); 688 int argc = target()->arguments_count();
681 InLoopFlag in_loop = target()->ic_in_loop(); 689 InLoopFlag in_loop = target()->ic_in_loop();
682 MaybeObject* maybe_code = NULL; 690 MaybeObject* maybe_code = NULL;
683 bool had_proto_failure = false; 691 bool had_proto_failure = false;
684 if (state == UNINITIALIZED) { 692 if (state == UNINITIALIZED) {
685 // This is the first time we execute this inline cache. 693 // This is the first time we execute this inline cache.
686 // Set the target to the pre monomorphic stub to delay 694 // Set the target to the pre monomorphic stub to delay
687 // setting the monomorphic state. 695 // setting the monomorphic state.
688 maybe_code = isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, 696 maybe_code =
689 in_loop, 697 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc,
690 kind_); 698 in_loop,
699 kind_,
700 extra_ic_state);
691 } else if (state == MONOMORPHIC) { 701 } else if (state == MONOMORPHIC) {
692 if (kind_ == Code::CALL_IC && 702 if (kind_ == Code::CALL_IC &&
693 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 703 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
694 maybe_code = ComputeMonomorphicStub(lookup, 704 maybe_code = ComputeMonomorphicStub(lookup,
695 state, 705 state,
696 extra_ic_state, 706 extra_ic_state,
697 object, 707 object,
698 name); 708 name);
699 } else if (kind_ == Code::CALL_IC && 709 } else if (kind_ == Code::CALL_IC &&
700 TryRemoveInvalidPrototypeDependentStub(target(), 710 TryRemoveInvalidPrototypeDependentStub(target(),
701 *object, 711 *object,
702 *name)) { 712 *name)) {
703 had_proto_failure = true; 713 had_proto_failure = true;
704 maybe_code = ComputeMonomorphicStub(lookup, 714 maybe_code = ComputeMonomorphicStub(lookup,
705 state, 715 state,
706 extra_ic_state, 716 extra_ic_state,
707 object, 717 object,
708 name); 718 name);
709 } else { 719 } else {
710 maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(argc, 720 maybe_code =
711 in_loop, 721 isolate()->stub_cache()->ComputeCallMegamorphic(argc,
712 kind_); 722 in_loop,
723 kind_,
724 extra_ic_state);
713 } 725 }
714 } else { 726 } else {
715 maybe_code = ComputeMonomorphicStub(lookup, 727 maybe_code = ComputeMonomorphicStub(lookup,
716 state, 728 state,
717 extra_ic_state, 729 extra_ic_state,
718 object, 730 object,
719 name); 731 name);
720 } 732 }
721 733
722 // If we're unable to compute the stub (not enough memory left), we 734 // 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
760 } 772 }
761 773
762 if (object->IsUndefined() || object->IsNull()) { 774 if (object->IsUndefined() || object->IsNull()) {
763 return TypeError("non_object_property_call", object, key); 775 return TypeError("non_object_property_call", object, key);
764 } 776 }
765 777
766 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { 778 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
767 int argc = target()->arguments_count(); 779 int argc = target()->arguments_count();
768 InLoopFlag in_loop = target()->ic_in_loop(); 780 InLoopFlag in_loop = target()->ic_in_loop();
769 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( 781 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
770 argc, in_loop, Code::KEYED_CALL_IC); 782 argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState);
771 Object* code; 783 Object* code;
772 if (maybe_code->ToObject(&code)) { 784 if (maybe_code->ToObject(&code)) {
773 set_target(Code::cast(code)); 785 set_target(Code::cast(code));
774 #ifdef DEBUG 786 #ifdef DEBUG
775 TraceIC( 787 TraceIC(
776 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); 788 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
777 #endif 789 #endif
778 } 790 }
779 } 791 }
780 792
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 #undef ADDR 2202 #undef ADDR
2191 }; 2203 };
2192 2204
2193 2205
2194 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2206 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2195 return IC_utilities[id]; 2207 return IC_utilities[id];
2196 } 2208 }
2197 2209
2198 2210
2199 } } // namespace v8::internal 2211 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698