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

Side by Side Diff: src/ic.cc

Issue 6344005: Introduce extra IC state to record additional feedback from IC-s. (Closed)
Patch Set: Use the extra state in string IC stubs Created 9 years, 11 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
« no previous file with comments | « src/ic.h ('k') | src/objects.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 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 // Change the receiver to the result of calling ToObject on it. 475 // Change the receiver to the result of calling ToObject on it.
476 const int argc = this->target()->arguments_count(); 476 const int argc = this->target()->arguments_count();
477 StackFrameLocator locator; 477 StackFrameLocator locator;
478 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 478 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
479 int index = frame->ComputeExpressionsCount() - (argc + 1); 479 int index = frame->ComputeExpressionsCount() - (argc + 1);
480 frame->SetExpression(index, *Factory::ToObject(object)); 480 frame->SetExpression(index, *Factory::ToObject(object));
481 } 481 }
482 482
483 483
484 MaybeObject* CallICBase::LoadFunction(State state, 484 MaybeObject* CallICBase::LoadFunction(State state,
485 Code::ExtraICState extra_ic_state,
485 Handle<Object> object, 486 Handle<Object> object,
486 Handle<String> name) { 487 Handle<String> name) {
487 // If the object is undefined or null it's illegal to try to get any 488 // If the object is undefined or null it's illegal to try to get any
488 // of its properties; throw a TypeError in that case. 489 // of its properties; throw a TypeError in that case.
489 if (object->IsUndefined() || object->IsNull()) { 490 if (object->IsUndefined() || object->IsNull()) {
490 return TypeError("non_object_property_call", object, name); 491 return TypeError("non_object_property_call", object, name);
491 } 492 }
492 493
493 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { 494 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
494 ReceiverToObject(object); 495 ReceiverToObject(object);
(...skipping 25 matching lines...) Expand all
520 // If the object does not have the requested property, check which 521 // If the object does not have the requested property, check which
521 // exception we need to throw. 522 // exception we need to throw.
522 if (IsContextual(object)) { 523 if (IsContextual(object)) {
523 return ReferenceError("not_defined", name); 524 return ReferenceError("not_defined", name);
524 } 525 }
525 return TypeError("undefined_method", object, name); 526 return TypeError("undefined_method", object, name);
526 } 527 }
527 528
528 // Lookup is valid: Update inline cache and stub cache. 529 // Lookup is valid: Update inline cache and stub cache.
529 if (FLAG_use_ic) { 530 if (FLAG_use_ic) {
530 UpdateCaches(&lookup, state, object, name); 531 UpdateCaches(&lookup, state, extra_ic_state, object, name);
531 } 532 }
532 533
533 // Get the property. 534 // Get the property.
534 PropertyAttributes attr; 535 PropertyAttributes attr;
535 Object* result; 536 Object* result;
536 { MaybeObject* maybe_result = 537 { MaybeObject* maybe_result =
537 object->GetProperty(*object, &lookup, *name, &attr); 538 object->GetProperty(*object, &lookup, *name, &attr);
538 if (!maybe_result->ToObject(&result)) return maybe_result; 539 if (!maybe_result->ToObject(&result)) return maybe_result;
539 } 540 }
540 if (lookup.type() == INTERCEPTOR) { 541 if (lookup.type() == INTERCEPTOR) {
(...skipping 30 matching lines...) Expand all
571 MaybeObject* answer = result; 572 MaybeObject* answer = result;
572 if (!result->IsJSFunction()) { 573 if (!result->IsJSFunction()) {
573 answer = TypeError("property_not_function", object, name); 574 answer = TypeError("property_not_function", object, name);
574 } 575 }
575 return answer; 576 return answer;
576 } 577 }
577 578
578 579
579 void CallICBase::UpdateCaches(LookupResult* lookup, 580 void CallICBase::UpdateCaches(LookupResult* lookup,
580 State state, 581 State state,
582 Code::ExtraICState extra_ic_state,
581 Handle<Object> object, 583 Handle<Object> object,
582 Handle<String> name) { 584 Handle<String> name) {
583 // Bail out if we didn't find a result. 585 // Bail out if we didn't find a result.
584 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 586 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
585 587
586 if (lookup->holder() != *object && 588 if (lookup->holder() != *object &&
587 HasNormalObjectsInPrototypeChain(lookup, object->GetPrototype())) { 589 HasNormalObjectsInPrototypeChain(lookup, object->GetPrototype())) {
588 // Suppress optimization for prototype chains with slow properties objects 590 // Suppress optimization for prototype chains with slow properties objects
589 // in the middle. 591 // in the middle.
590 return; 592 return;
(...skipping 26 matching lines...) Expand all
617 break; 619 break;
618 } 620 }
619 case CONSTANT_FUNCTION: { 621 case CONSTANT_FUNCTION: {
620 // Get the constant function and compute the code stub for this 622 // Get the constant function and compute the code stub for this
621 // call; used for rewriting to monomorphic state and making sure 623 // call; used for rewriting to monomorphic state and making sure
622 // that the code stub is in the stub cache. 624 // that the code stub is in the stub cache.
623 JSFunction* function = lookup->GetConstantFunction(); 625 JSFunction* function = lookup->GetConstantFunction();
624 maybe_code = StubCache::ComputeCallConstant(argc, 626 maybe_code = StubCache::ComputeCallConstant(argc,
625 in_loop, 627 in_loop,
626 kind_, 628 kind_,
629 extra_ic_state,
627 *name, 630 *name,
628 *object, 631 *object,
629 lookup->holder(), 632 lookup->holder(),
630 function); 633 function);
631 break; 634 break;
632 } 635 }
633 case NORMAL: { 636 case NORMAL: {
634 if (!object->IsJSObject()) return; 637 if (!object->IsJSObject()) return;
635 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 638 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
636 639
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 703 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
701 name, state, target(), in_loop ? " (in-loop)" : ""); 704 name, state, target(), in_loop ? " (in-loop)" : "");
702 #endif 705 #endif
703 } 706 }
704 707
705 708
706 MaybeObject* KeyedCallIC::LoadFunction(State state, 709 MaybeObject* KeyedCallIC::LoadFunction(State state,
707 Handle<Object> object, 710 Handle<Object> object,
708 Handle<Object> key) { 711 Handle<Object> key) {
709 if (key->IsSymbol()) { 712 if (key->IsSymbol()) {
710 return CallICBase::LoadFunction(state, object, Handle<String>::cast(key)); 713 return CallICBase::LoadFunction(state,
714 Code::kNoExtraICState,
715 object,
716 Handle<String>::cast(key));
711 } 717 }
712 718
713 if (object->IsUndefined() || object->IsNull()) { 719 if (object->IsUndefined() || object->IsNull()) {
714 return TypeError("non_object_property_call", object, key); 720 return TypeError("non_object_property_call", object, key);
715 } 721 }
716 722
717 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { 723 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
718 ReceiverToObject(object); 724 ReceiverToObject(object);
719 } 725 }
720 726
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 } else { 1637 } else {
1632 CompileLazy(function_handle, CLEAR_EXCEPTION); 1638 CompileLazy(function_handle, CLEAR_EXCEPTION);
1633 } 1639 }
1634 return *function_handle; 1640 return *function_handle;
1635 } 1641 }
1636 1642
1637 1643
1638 // Used from ic-<arch>.cc. 1644 // Used from ic-<arch>.cc.
1639 MUST_USE_RESULT MaybeObject* CallIC_Miss(Arguments args) { 1645 MUST_USE_RESULT MaybeObject* CallIC_Miss(Arguments args) {
1640 NoHandleAllocation na; 1646 NoHandleAllocation na;
1641 ASSERT(args.length() == 2); 1647 ASSERT(args.length() == 2 || args.length() == 3);
1642 CallIC ic; 1648 CallIC ic;
1643 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1649 IC::State state;
1650 Code::ExtraICState extra_ic_state;
1651 if (args.length() == 2) {
Mads Ager (chromium) 2011/01/17 14:06:00 As discussed offline I would like to keep all the
1652 state = IC::StateFrom(ic.target(), args[0], args[1]);
1653 extra_ic_state = Code::kNoExtraICState;
1654 } else {
1655 ASSERT(args.length() == 3);
1656 ASSERT(ic.target()->ic_state() == MONOMORPHIC);
1657 // Extra IC state change is requested. Use PREMONOMORPHIC to
1658 // trigger generating a new stub.
1659 state = PREMONOMORPHIC;
1660 extra_ic_state = static_cast<Code::ExtraICState>(
1661 Smi::cast(args[2])->value());
1662 }
1663 MaybeObject* maybe_result = ic.LoadFunction(state,
1664 extra_ic_state,
1665 args.at<Object>(0),
1666 args.at<String>(1));
1644 Object* result; 1667 Object* result;
1645 { MaybeObject* maybe_result = 1668 if (!maybe_result->ToObject(&result)) return maybe_result;
1646 ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
1647 if (!maybe_result->ToObject(&result)) return maybe_result;
1648 }
1649 1669
1650 // The first time the inline cache is updated may be the first time the 1670 // The first time the inline cache is updated may be the first time the
1651 // function it references gets called. If the function was lazily compiled 1671 // function it references gets called. If the function was lazily compiled
1652 // then the first call will trigger a compilation. We check for this case 1672 // then the first call will trigger a compilation. We check for this case
1653 // and we do the compilation immediately, instead of waiting for the stub 1673 // and we do the compilation immediately, instead of waiting for the stub
1654 // currently attached to the JSFunction object to trigger compilation. We 1674 // currently attached to the JSFunction object to trigger compilation. We
1655 // do this in the case where we know that the inline cache is inside a loop, 1675 // do this in the case where we know that the inline cache is inside a loop,
1656 // because then we know that we want to optimize the function. 1676 // because then we know that we want to optimize the function.
1657 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { 1677 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
1658 return result; 1678 return result;
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 #undef ADDR 2184 #undef ADDR
2165 }; 2185 };
2166 2186
2167 2187
2168 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2188 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2169 return IC_utilities[id]; 2189 return IC_utilities[id];
2170 } 2190 }
2171 2191
2172 2192
2173 } } // namespace v8::internal 2193 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698