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

Side by Side Diff: src/ic.cc

Issue 25263002: Encapsulate extra_ic_state in CallICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // Change the receiver to the result of calling ToObject on it. 532 // Change the receiver to the result of calling ToObject on it.
533 const int argc = this->target()->arguments_count(); 533 const int argc = this->target()->arguments_count();
534 StackFrameLocator locator(isolate()); 534 StackFrameLocator locator(isolate());
535 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 535 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
536 int index = frame->ComputeExpressionsCount() - (argc + 1); 536 int index = frame->ComputeExpressionsCount() - (argc + 1);
537 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 537 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
538 } 538 }
539 } 539 }
540 540
541 541
542 MaybeObject* CallICBase::LoadFunction(Code::ExtraICState extra_ic_state, 542 MaybeObject* CallICBase::LoadFunction(Handle<Object> object,
543 Handle<Object> object,
544 Handle<String> name) { 543 Handle<String> name) {
545 bool use_ic = FLAG_use_ic; 544 bool use_ic = FLAG_use_ic;
546 if (object->IsJSObject()) { 545 if (object->IsJSObject()) {
547 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 546 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
548 if (receiver->map()->is_deprecated()) { 547 if (receiver->map()->is_deprecated()) {
549 use_ic = false; 548 use_ic = false;
550 JSObject::MigrateInstance(receiver); 549 JSObject::MigrateInstance(receiver);
551 } 550 }
552 } 551 }
553 552
(...skipping 24 matching lines...) Expand all
578 577
579 if (!lookup.IsFound()) { 578 if (!lookup.IsFound()) {
580 // If the object does not have the requested property, check which 579 // If the object does not have the requested property, check which
581 // exception we need to throw. 580 // exception we need to throw.
582 return IsUndeclaredGlobal(object) 581 return IsUndeclaredGlobal(object)
583 ? ReferenceError("not_defined", name) 582 ? ReferenceError("not_defined", name)
584 : TypeError("undefined_method", object, name); 583 : TypeError("undefined_method", object, name);
585 } 584 }
586 585
587 // Lookup is valid: Update inline cache and stub cache. 586 // Lookup is valid: Update inline cache and stub cache.
588 if (use_ic) UpdateCaches(&lookup, extra_ic_state, object, name); 587 if (use_ic) UpdateCaches(&lookup, object, name);
589 588
590 // Get the property. 589 // Get the property.
591 PropertyAttributes attr; 590 PropertyAttributes attr;
592 Handle<Object> result = 591 Handle<Object> result =
593 Object::GetProperty(object, object, &lookup, name, &attr); 592 Object::GetProperty(object, object, &lookup, name, &attr);
594 RETURN_IF_EMPTY_HANDLE(isolate(), result); 593 RETURN_IF_EMPTY_HANDLE(isolate(), result);
595 594
596 if (lookup.IsInterceptor() && attr == ABSENT) { 595 if (lookup.IsInterceptor() && attr == ABSENT) {
597 // If the object does not have the requested property, check which 596 // If the object does not have the requested property, check which
598 // exception we need to throw. 597 // exception we need to throw.
(...skipping 24 matching lines...) Expand all
623 } 622 }
624 623
625 // Try to find a suitable function delegate for the object at hand. 624 // Try to find a suitable function delegate for the object at hand.
626 result = TryCallAsFunction(result); 625 result = TryCallAsFunction(result);
627 if (result->IsJSFunction()) return *result; 626 if (result->IsJSFunction()) return *result;
628 627
629 return TypeError("property_not_function", object, name); 628 return TypeError("property_not_function", object, name);
630 } 629 }
631 630
632 631
633 bool CallICBase::TryUpdateExtraICState(LookupResult* lookup, 632 bool CallIC::TryUpdateExtraICState(LookupResult* lookup,
634 Handle<Object> object, 633 Handle<Object> object) {
635 Code::ExtraICState* extra_ic_state) {
636 ASSERT(kind_ == Code::CALL_IC);
637 if (!lookup->IsConstantFunction()) return false; 634 if (!lookup->IsConstantFunction()) return false;
638 JSFunction* function = lookup->GetConstantFunction(); 635 JSFunction* function = lookup->GetConstantFunction();
639 if (!function->shared()->HasBuiltinFunctionId()) return false; 636 if (!function->shared()->HasBuiltinFunctionId()) return false;
640 637
641 // Fetch the arguments passed to the called function. 638 // Fetch the arguments passed to the called function.
642 const int argc = target()->arguments_count(); 639 const int argc = target()->arguments_count();
643 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top()); 640 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top());
644 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 641 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
645 Arguments args(argc + 1, 642 Arguments args(argc + 1,
646 &Memory::Object_at(fp + 643 &Memory::Object_at(fp +
647 StandardFrameConstants::kCallerSPOffset + 644 StandardFrameConstants::kCallerSPOffset +
648 argc * kPointerSize)); 645 argc * kPointerSize));
649 switch (function->shared()->builtin_function_id()) { 646 switch (function->shared()->builtin_function_id()) {
650 case kStringCharCodeAt: 647 case kStringCharCodeAt:
651 case kStringCharAt: 648 case kStringCharAt:
652 if (object->IsString()) { 649 if (object->IsString()) {
653 String* string = String::cast(*object); 650 String* string = String::cast(*object);
654 // Check there's the right string value or wrapper in the receiver slot. 651 // Check there's the right string value or wrapper in the receiver slot.
655 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); 652 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
656 // If we're in the default (fastest) state and the index is 653 // If we're in the default (fastest) state and the index is
657 // out of bounds, update the state to record this fact. 654 // out of bounds, update the state to record this fact.
658 if (StringStubState::decode(*extra_ic_state) == DEFAULT_STRING_STUB && 655 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB &&
659 argc >= 1 && args[1]->IsNumber()) { 656 argc >= 1 && args[1]->IsNumber()) {
660 double index = DoubleToInteger(args.number_at(1)); 657 double index = DoubleToInteger(args.number_at(1));
661 if (index < 0 || index >= string->length()) { 658 if (index < 0 || index >= string->length()) {
662 *extra_ic_state = 659 extra_ic_state_ =
663 StringStubState::update(*extra_ic_state, 660 StringStubState::update(extra_ic_state(),
664 STRING_INDEX_OUT_OF_BOUNDS); 661 STRING_INDEX_OUT_OF_BOUNDS);
665 return true; 662 return true;
666 } 663 }
667 } 664 }
668 } 665 }
669 break; 666 break;
670 default: 667 default:
671 return false; 668 return false;
672 } 669 }
673 return false; 670 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 ASSERT(HasInterceptorGetter(*holder)); 720 ASSERT(HasInterceptorGetter(*holder));
724 return isolate()->stub_cache()->ComputeCallInterceptor( 721 return isolate()->stub_cache()->ComputeCallInterceptor(
725 argc, kind_, extra_state, name, object, holder); 722 argc, kind_, extra_state, name, object, holder);
726 default: 723 default:
727 return Handle<Code>::null(); 724 return Handle<Code>::null();
728 } 725 }
729 } 726 }
730 727
731 728
732 void CallICBase::UpdateCaches(LookupResult* lookup, 729 void CallICBase::UpdateCaches(LookupResult* lookup,
733 Code::ExtraICState extra_ic_state,
734 Handle<Object> object, 730 Handle<Object> object,
735 Handle<String> name) { 731 Handle<String> name) {
736 // Bail out if we didn't find a result. 732 // Bail out if we didn't find a result.
737 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 733 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
738 734
739 // Compute the number of arguments. 735 // Compute the number of arguments.
740 int argc = target()->arguments_count(); 736 int argc = target()->arguments_count();
741 Handle<Code> code; 737 Handle<Code> code;
742 if (state() == UNINITIALIZED) { 738 if (state() == UNINITIALIZED) {
743 // This is the first time we execute this inline cache. 739 // This is the first time we execute this inline cache.
744 // Set the target to the pre monomorphic stub to delay 740 // Set the target to the pre monomorphic stub to delay
745 // setting the monomorphic state. 741 // setting the monomorphic state.
746 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( 742 code = isolate()->stub_cache()->ComputeCallPreMonomorphic(
747 argc, kind_, extra_ic_state); 743 argc, kind_, extra_ic_state());
748 } else if (state() == MONOMORPHIC) { 744 } else if (state() == MONOMORPHIC) {
749 if (kind_ == Code::CALL_IC && 745 if (kind_ == Code::CALL_IC &&
750 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 746 static_cast<CallIC*>(this)->TryUpdateExtraICState(lookup, object)) {
751 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name); 747 code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name);
752 } else if (TryRemoveInvalidPrototypeDependentStub(*object, *name)) { 748 } else if (TryRemoveInvalidPrototypeDependentStub(*object, *name)) {
753 MarkMonomorphicPrototypeFailure(); 749 MarkMonomorphicPrototypeFailure();
754 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name); 750 code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name);
755 } else { 751 } else {
756 code = isolate()->stub_cache()->ComputeCallMegamorphic( 752 code = isolate()->stub_cache()->ComputeCallMegamorphic(
757 argc, kind_, extra_ic_state); 753 argc, kind_, extra_ic_state());
758 } 754 }
759 } else { 755 } else {
760 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name); 756 code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name);
761 } 757 }
762 758
763 // If there's no appropriate stub we simply avoid updating the caches. 759 // If there's no appropriate stub we simply avoid updating the caches.
764 if (code.is_null()) return; 760 if (code.is_null()) return;
765 761
766 // Patch the call site depending on the state of the cache. 762 // Patch the call site depending on the state of the cache.
767 switch (state()) { 763 switch (state()) {
768 case UNINITIALIZED: 764 case UNINITIALIZED:
769 case MONOMORPHIC_PROTOTYPE_FAILURE: 765 case MONOMORPHIC_PROTOTYPE_FAILURE:
770 case PREMONOMORPHIC: 766 case PREMONOMORPHIC:
(...skipping 19 matching lines...) Expand all
790 break; 786 break;
791 } 787 }
792 788
793 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target()); 789 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target());
794 } 790 }
795 791
796 792
797 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, 793 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object,
798 Handle<Object> key) { 794 Handle<Object> key) {
799 if (key->IsInternalizedString()) { 795 if (key->IsInternalizedString()) {
800 return CallICBase::LoadFunction(Code::kNoExtraICState, 796 return CallICBase::LoadFunction(object, Handle<String>::cast(key));
801 object,
802 Handle<String>::cast(key));
803 } 797 }
804 798
805 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 799 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
806 if (object->IsJSObject()) { 800 if (object->IsJSObject()) {
807 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 801 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
808 if (receiver->map()->is_deprecated()) { 802 if (receiver->map()->is_deprecated()) {
809 use_ic = false; 803 use_ic = false;
810 JSObject::MigrateInstance(receiver); 804 JSObject::MigrateInstance(receiver);
811 } 805 }
812 } 806 }
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 // ---------------------------------------------------------------------------- 2101 // ----------------------------------------------------------------------------
2108 // Static IC stub generators. 2102 // Static IC stub generators.
2109 // 2103 //
2110 2104
2111 // Used from ic-<arch>.cc. 2105 // Used from ic-<arch>.cc.
2112 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { 2106 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
2113 HandleScope scope(isolate); 2107 HandleScope scope(isolate);
2114 ASSERT(args.length() == 2); 2108 ASSERT(args.length() == 2);
2115 CallIC ic(isolate); 2109 CallIC ic(isolate);
2116 ic.UpdateState(args[0], args[1]); 2110 ic.UpdateState(args[0], args[1]);
2117 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2111 MaybeObject* maybe_result = ic.LoadFunction(args.at<Object>(0),
2118 MaybeObject* maybe_result = ic.LoadFunction(extra_ic_state,
2119 args.at<Object>(0),
2120 args.at<String>(1)); 2112 args.at<String>(1));
2121 JSFunction* raw_function; 2113 JSFunction* raw_function;
2122 if (!maybe_result->To(&raw_function)) return maybe_result; 2114 if (!maybe_result->To(&raw_function)) return maybe_result;
2123 2115
2124 // The first time the inline cache is updated may be the first time the 2116 // The first time the inline cache is updated may be the first time the
2125 // function it references gets called. If the function is lazily compiled 2117 // function it references gets called. If the function is lazily compiled
2126 // then the first call will trigger a compilation. We check for this case 2118 // then the first call will trigger a compilation. We check for this case
2127 // and we do the compilation immediately, instead of waiting for the stub 2119 // and we do the compilation immediately, instead of waiting for the stub
2128 // currently attached to the JSFunction object to trigger compilation. 2120 // currently attached to the JSFunction object to trigger compilation.
2129 if (raw_function->is_compiled()) return raw_function; 2121 if (raw_function->is_compiled()) return raw_function;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2313 args.at<Object>(1), 2305 args.at<Object>(1),
2314 args.at<Object>(2), 2306 args.at<Object>(2),
2315 MISS); 2307 MISS);
2316 } 2308 }
2317 2309
2318 2310
2319 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { 2311 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
2320 HandleScope scope(isolate); 2312 HandleScope scope(isolate);
2321 ASSERT(args.length() == 3); 2313 ASSERT(args.length() == 3);
2322 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2314 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2323 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2324 Handle<Object> object = args.at<Object>(0); 2315 Handle<Object> object = args.at<Object>(0);
2325 Handle<Object> key = args.at<Object>(1); 2316 Handle<Object> key = args.at<Object>(1);
2326 Handle<Object> value = args.at<Object>(2); 2317 Handle<Object> value = args.at<Object>(2);
2327 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); 2318 StrictModeFlag strict_mode = ic.strict_mode();
2328 return Runtime::SetObjectProperty(isolate, 2319 return Runtime::SetObjectProperty(isolate,
2329 object, 2320 object,
2330 key, 2321 key,
2331 value, 2322 value,
2332 NONE, 2323 NONE,
2333 strict_mode); 2324 strict_mode);
2334 } 2325 }
2335 2326
2336 2327
2337 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { 2328 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
2338 HandleScope scope(isolate); 2329 HandleScope scope(isolate);
2339 ASSERT(args.length() == 3); 2330 ASSERT(args.length() == 3);
2340 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2331 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2341 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2342 Handle<Object> object = args.at<Object>(0); 2332 Handle<Object> object = args.at<Object>(0);
2343 Handle<Object> key = args.at<Object>(1); 2333 Handle<Object> key = args.at<Object>(1);
2344 Handle<Object> value = args.at<Object>(2); 2334 Handle<Object> value = args.at<Object>(2);
2345 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); 2335 StrictModeFlag strict_mode = ic.strict_mode();
2346 return Runtime::SetObjectProperty(isolate, 2336 return Runtime::SetObjectProperty(isolate,
2347 object, 2337 object,
2348 key, 2338 key,
2349 value, 2339 value,
2350 NONE, 2340 NONE,
2351 strict_mode); 2341 strict_mode);
2352 } 2342 }
2353 2343
2354 2344
2355 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { 2345 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2356 HandleScope scope(isolate); 2346 HandleScope scope(isolate);
2357 ASSERT(args.length() == 3); 2347 ASSERT(args.length() == 3);
2358 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2348 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2359 ic.UpdateState(args[0], args[1]); 2349 ic.UpdateState(args[0], args[1]);
2360 return ic.Store(args.at<Object>(0), 2350 return ic.Store(args.at<Object>(0),
2361 args.at<Object>(1), 2351 args.at<Object>(1),
2362 args.at<Object>(2), 2352 args.at<Object>(2),
2363 MISS_FORCE_GENERIC); 2353 MISS_FORCE_GENERIC);
2364 } 2354 }
2365 2355
2366 2356
2367 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { 2357 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
2368 HandleScope scope(isolate); 2358 HandleScope scope(isolate);
2369 ASSERT(args.length() == 4); 2359 ASSERT(args.length() == 4);
2370 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2360 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2371 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2372 Handle<Object> value = args.at<Object>(0); 2361 Handle<Object> value = args.at<Object>(0);
2373 Handle<Object> key = args.at<Object>(2); 2362 Handle<Object> key = args.at<Object>(2);
2374 Handle<Object> object = args.at<Object>(3); 2363 Handle<Object> object = args.at<Object>(3);
2375 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); 2364 StrictModeFlag strict_mode = ic.strict_mode();
2376 return Runtime::SetObjectProperty(isolate, 2365 return Runtime::SetObjectProperty(isolate,
2377 object, 2366 object,
2378 key, 2367 key,
2379 value, 2368 value,
2380 NONE, 2369 NONE,
2381 strict_mode); 2370 strict_mode);
2382 } 2371 }
2383 2372
2384 2373
2385 void BinaryOpIC::patch(Code* code) { 2374 void BinaryOpIC::patch(Code* code) {
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
2978 #undef ADDR 2967 #undef ADDR
2979 }; 2968 };
2980 2969
2981 2970
2982 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2971 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2983 return IC_utilities[id]; 2972 return IC_utilities[id];
2984 } 2973 }
2985 2974
2986 2975
2987 } } // namespace v8::internal 2976 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698