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

Side by Side Diff: src/ic/ic.cc

Issue 1213773002: Vector ICs: Changes to the IC system to support vector-based stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 5 years, 5 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/ic.h ('k') | src/ic/ic-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
11 #include "src/codegen.h" 11 #include "src/codegen.h"
12 #include "src/conversions.h" 12 #include "src/conversions.h"
13 #include "src/execution.h" 13 #include "src/execution.h"
14 #include "src/ic/call-optimization.h" 14 #include "src/ic/call-optimization.h"
15 #include "src/ic/handler-compiler.h" 15 #include "src/ic/handler-compiler.h"
16 #include "src/ic/ic-inl.h" 16 #include "src/ic/ic-inl.h"
17 #include "src/ic/ic-compiler.h" 17 #include "src/ic/ic-compiler.h"
18 #include "src/ic/stub-cache.h" 18 #include "src/ic/stub-cache.h"
19 #include "src/macro-assembler.h"
19 #include "src/prototype.h" 20 #include "src/prototype.h"
20 #include "src/runtime/runtime.h" 21 #include "src/runtime/runtime.h"
21 22
22 namespace v8 { 23 namespace v8 {
23 namespace internal { 24 namespace internal {
24 25
25 char IC::TransitionMarkFromState(IC::State state) { 26 char IC::TransitionMarkFromState(IC::State state) {
26 switch (state) { 27 switch (state) {
27 case UNINITIALIZED: 28 case UNINITIALIZED:
28 return '0'; 29 return '0';
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 Code* target = GetTargetAtAddress(address, constant_pool); 482 Code* target = GetTargetAtAddress(address, constant_pool);
482 483
483 // Don't clear debug break inline cache as it will remove the break point. 484 // Don't clear debug break inline cache as it will remove the break point.
484 if (target->is_debug_stub()) return; 485 if (target->is_debug_stub()) return;
485 486
486 switch (target->kind()) { 487 switch (target->kind()) {
487 case Code::LOAD_IC: 488 case Code::LOAD_IC:
488 case Code::KEYED_LOAD_IC: 489 case Code::KEYED_LOAD_IC:
489 return; 490 return;
490 case Code::STORE_IC: 491 case Code::STORE_IC:
492 if (FLAG_vector_stores) return;
491 return StoreIC::Clear(isolate, address, target, constant_pool); 493 return StoreIC::Clear(isolate, address, target, constant_pool);
492 case Code::KEYED_STORE_IC: 494 case Code::KEYED_STORE_IC:
495 if (FLAG_vector_stores) return;
493 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); 496 return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
494 case Code::COMPARE_IC: 497 case Code::COMPARE_IC:
495 return CompareIC::Clear(isolate, address, target, constant_pool); 498 return CompareIC::Clear(isolate, address, target, constant_pool);
496 case Code::COMPARE_NIL_IC: 499 case Code::COMPARE_NIL_IC:
497 return CompareNilIC::Clear(address, target, constant_pool); 500 return CompareNilIC::Clear(address, target, constant_pool);
498 case Code::CALL_IC: // CallICs are vector-based and cleared differently. 501 case Code::CALL_IC: // CallICs are vector-based and cleared differently.
499 case Code::BINARY_OP_IC: 502 case Code::BINARY_OP_IC:
500 case Code::TO_BOOLEAN_IC: 503 case Code::TO_BOOLEAN_IC:
501 // Clearing these is tricky and does not 504 // Clearing these is tricky and does not
502 // make any performance difference. 505 // make any performance difference.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 544
542 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, 545 void StoreIC::Clear(Isolate* isolate, Address address, Code* target,
543 Address constant_pool) { 546 Address constant_pool) {
544 if (IsCleared(target)) return; 547 if (IsCleared(target)) return;
545 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC, 548 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC,
546 target->extra_ic_state()); 549 target->extra_ic_state());
547 SetTargetAtAddress(address, code, constant_pool); 550 SetTargetAtAddress(address, code, constant_pool);
548 } 551 }
549 552
550 553
554 void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) {
555 if (IsCleared(nexus)) return;
556 State state = nexus->StateFromFeedback();
557 nexus->ConfigurePremonomorphic();
558 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
559 }
560
561
551 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, 562 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target,
552 Address constant_pool) { 563 Address constant_pool) {
553 if (IsCleared(target)) return; 564 if (IsCleared(target)) return;
554 Handle<Code> code = pre_monomorphic_stub( 565 Handle<Code> code = pre_monomorphic_stub(
555 isolate, StoreICState::GetLanguageMode(target->extra_ic_state())); 566 isolate, StoreICState::GetLanguageMode(target->extra_ic_state()));
556 SetTargetAtAddress(address, *code, constant_pool); 567 SetTargetAtAddress(address, *code, constant_pool);
557 } 568 }
558 569
559 570
571 void KeyedStoreIC::Clear(Isolate* isolate, Code* host,
572 KeyedStoreICNexus* nexus) {
573 if (IsCleared(nexus)) return;
574 State state = nexus->StateFromFeedback();
575 nexus->ConfigurePremonomorphic();
576 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
577 }
578
579
560 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, 580 void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
561 Address constant_pool) { 581 Address constant_pool) {
562 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); 582 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC);
563 CompareICStub stub(target->stub_key(), isolate); 583 CompareICStub stub(target->stub_key(), isolate);
564 // Only clear CompareICs that can retain objects. 584 // Only clear CompareICs that can retain objects.
565 if (stub.state() != CompareICState::KNOWN_OBJECT) return; 585 if (stub.state() != CompareICState::KNOWN_OBJECT) return;
566 SetTargetAtAddress(address, 586 SetTargetAtAddress(address,
567 GetRawUninitialized(isolate, stub.op(), stub.strength()), 587 GetRawUninitialized(isolate, stub.op(), stub.strength()),
568 constant_pool); 588 constant_pool);
569 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 589 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
(...skipping 14 matching lines...) Expand all
584 if (!object->IsJSObject()) return false; 604 if (!object->IsJSObject()) return false;
585 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 605 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
586 if (!receiver->map()->is_deprecated()) return false; 606 if (!receiver->map()->is_deprecated()) return false;
587 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 607 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
588 return true; 608 return true;
589 } 609 }
590 610
591 611
592 void IC::ConfigureVectorState(IC::State new_state) { 612 void IC::ConfigureVectorState(IC::State new_state) {
593 DCHECK(UseVector()); 613 DCHECK(UseVector());
594 if (kind() == Code::LOAD_IC) { 614 if (new_state == PREMONOMORPHIC) {
595 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 615 nexus()->ConfigurePremonomorphic();
596 if (new_state == PREMONOMORPHIC) { 616 } else if (new_state == MEGAMORPHIC) {
597 nexus->ConfigurePremonomorphic(); 617 nexus()->ConfigureMegamorphic();
598 } else if (new_state == MEGAMORPHIC) {
599 nexus->ConfigureMegamorphic();
600 } else {
601 UNREACHABLE();
602 }
603 } else if (kind() == Code::KEYED_LOAD_IC) {
604 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
605 if (new_state == PREMONOMORPHIC) {
606 nexus->ConfigurePremonomorphic();
607 } else if (new_state == MEGAMORPHIC) {
608 nexus->ConfigureMegamorphic();
609 } else {
610 UNREACHABLE();
611 }
612 } else { 618 } else {
613 UNREACHABLE(); 619 UNREACHABLE();
614 } 620 }
615 621
616 vector_set_ = true; 622 vector_set_ = true;
617 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 623 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
618 new_state); 624 new_state);
619 } 625 }
620 626
621 627
622 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, 628 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
623 Handle<Code> handler) { 629 Handle<Code> handler) {
624 DCHECK(UseVector()); 630 DCHECK(UseVector());
625 if (kind() == Code::LOAD_IC) { 631 if (kind() == Code::LOAD_IC) {
626 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 632 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
627 nexus->ConfigureMonomorphic(map, handler); 633 nexus->ConfigureMonomorphic(map, handler);
634 } else if (kind() == Code::KEYED_LOAD_IC) {
635 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
636 nexus->ConfigureMonomorphic(name, map, handler);
637 } else if (kind() == Code::STORE_IC) {
638 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
639 nexus->ConfigureMonomorphic(map, handler);
628 } else { 640 } else {
629 DCHECK(kind() == Code::KEYED_LOAD_IC); 641 DCHECK(kind() == Code::KEYED_STORE_IC);
630 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 642 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
631 nexus->ConfigureMonomorphic(name, map, handler); 643 nexus->ConfigureMonomorphic(name, map, handler);
632 } 644 }
633 645
634 vector_set_ = true; 646 vector_set_ = true;
635 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 647 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
636 MONOMORPHIC); 648 MONOMORPHIC);
637 } 649 }
638 650
639 651
640 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, 652 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
641 CodeHandleList* handlers) { 653 CodeHandleList* handlers) {
642 DCHECK(UseVector()); 654 DCHECK(UseVector());
643 if (kind() == Code::LOAD_IC) { 655 if (kind() == Code::LOAD_IC) {
644 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 656 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
645 nexus->ConfigurePolymorphic(maps, handlers); 657 nexus->ConfigurePolymorphic(maps, handlers);
658 } else if (kind() == Code::KEYED_LOAD_IC) {
659 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
660 nexus->ConfigurePolymorphic(name, maps, handlers);
661 } else if (kind() == Code::STORE_IC) {
662 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
663 nexus->ConfigurePolymorphic(maps, handlers);
646 } else { 664 } else {
647 DCHECK(kind() == Code::KEYED_LOAD_IC); 665 DCHECK(kind() == Code::KEYED_STORE_IC);
648 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 666 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
649 nexus->ConfigurePolymorphic(name, maps, handlers); 667 nexus->ConfigurePolymorphic(name, maps, handlers);
650 } 668 }
651 669
652 vector_set_ = true; 670 vector_set_ = true;
653 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 671 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
654 POLYMORPHIC); 672 POLYMORPHIC);
655 } 673 }
656 674
657 675
658 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { 676 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
659 // If the object is undefined or null it's illegal to try to get any 677 // If the object is undefined or null it's illegal to try to get any
660 // of its properties; throw a TypeError in that case. 678 // of its properties; throw a TypeError in that case.
661 if (object->IsUndefined() || object->IsNull()) { 679 if (object->IsUndefined() || object->IsNull()) {
662 return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name); 680 return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name);
663 } 681 }
664 682
665 // Check if the name is trivially convertible to an index and get 683 // Check if the name is trivially convertible to an index and get
666 // the element or char if so. 684 // the element or char if so.
667 uint32_t index; 685 uint32_t index;
668 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 686 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
669 // Rewrite to the generic keyed load stub. 687 // Rewrite to the generic keyed load stub.
670 if (FLAG_use_ic) { 688 if (FLAG_use_ic) {
671 if (UseVector()) { 689 DCHECK(UseVector());
672 ConfigureVectorState(MEGAMORPHIC); 690 ConfigureVectorState(MEGAMORPHIC);
673 } else {
674 set_target(*megamorphic_stub());
675 }
676 TRACE_IC("LoadIC", name); 691 TRACE_IC("LoadIC", name);
677 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index"); 692 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
678 } 693 }
679 Handle<Object> result; 694 Handle<Object> result;
680 ASSIGN_RETURN_ON_EXCEPTION( 695 ASSIGN_RETURN_ON_EXCEPTION(
681 isolate(), result, 696 isolate(), result,
682 Runtime::GetElementOrCharAt(isolate(), object, index), Object); 697 Runtime::GetElementOrCharAt(isolate(), object, index), Object);
683 return result; 698 return result;
684 } 699 }
685 700
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 ExtraICState state = ComputeExtraICState(language_mode); 1622 ExtraICState state = ComputeExtraICState(language_mode);
1608 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); 1623 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state);
1609 } 1624 }
1610 1625
1611 1626
1612 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, 1627 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
1613 JSReceiver::StoreFromKeyed store_mode) { 1628 JSReceiver::StoreFromKeyed store_mode) {
1614 if (state() == UNINITIALIZED) { 1629 if (state() == UNINITIALIZED) {
1615 // This is the first time we execute this inline cache. Set the target to 1630 // This is the first time we execute this inline cache. Set the target to
1616 // the pre monomorphic stub to delay setting the monomorphic state. 1631 // the pre monomorphic stub to delay setting the monomorphic state.
1617 set_target(*pre_monomorphic_stub()); 1632 if (FLAG_vector_stores) {
1633 ConfigureVectorState(PREMONOMORPHIC);
1634 } else {
1635 set_target(*pre_monomorphic_stub());
1636 }
1618 TRACE_IC("StoreIC", lookup->name()); 1637 TRACE_IC("StoreIC", lookup->name());
1619 return; 1638 return;
1620 } 1639 }
1621 1640
1622 bool use_ic = LookupForWrite(lookup, value, store_mode); 1641 bool use_ic = LookupForWrite(lookup, value, store_mode);
1623 if (!use_ic) { 1642 if (!use_ic) {
1624 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); 1643 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'");
1625 } 1644 }
1626 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); 1645 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub();
1627 1646
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 2065
2047 Handle<Object> store_handle; 2066 Handle<Object> store_handle;
2048 Handle<Code> stub = megamorphic_stub(); 2067 Handle<Code> stub = megamorphic_stub();
2049 2068
2050 if (key->IsInternalizedString() || key->IsSymbol()) { 2069 if (key->IsInternalizedString() || key->IsSymbol()) {
2051 ASSIGN_RETURN_ON_EXCEPTION( 2070 ASSIGN_RETURN_ON_EXCEPTION(
2052 isolate(), store_handle, 2071 isolate(), store_handle,
2053 StoreIC::Store(object, Handle<Name>::cast(key), value, 2072 StoreIC::Store(object, Handle<Name>::cast(key), value,
2054 JSReceiver::MAY_BE_STORE_FROM_KEYED), 2073 JSReceiver::MAY_BE_STORE_FROM_KEYED),
2055 Object); 2074 Object);
2056 if (!is_target_set()) { 2075 if (FLAG_vector_stores) {
2057 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 2076 if (!is_vector_set()) {
2058 "unhandled internalized string key"); 2077 ConfigureVectorState(MEGAMORPHIC);
2059 TRACE_IC("StoreIC", key); 2078 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
2060 set_target(*stub); 2079 "unhandled internalized string key");
2080 TRACE_IC("StoreIC", key);
2081 }
2082 } else {
2083 if (!is_target_set()) {
2084 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
2085 "unhandled internalized string key");
2086 TRACE_IC("StoreIC", key);
2087 set_target(*stub);
2088 }
2061 } 2089 }
2062 return store_handle; 2090 return store_handle;
2063 } 2091 }
2064 2092
2065 bool use_ic = 2093 bool use_ic =
2066 FLAG_use_ic && !object->IsStringWrapper() && 2094 FLAG_use_ic && !object->IsStringWrapper() &&
2067 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() && 2095 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() &&
2068 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed()); 2096 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed());
2069 if (use_ic && !object->IsSmi()) { 2097 if (use_ic && !object->IsSmi()) {
2070 // Don't use ICs for maps of the objects in Array's prototype chain. We 2098 // Don't use ICs for maps of the objects in Array's prototype chain. We
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 } 2135 }
2108 2136
2109 if (store_handle.is_null()) { 2137 if (store_handle.is_null()) {
2110 ASSIGN_RETURN_ON_EXCEPTION( 2138 ASSIGN_RETURN_ON_EXCEPTION(
2111 isolate(), store_handle, 2139 isolate(), store_handle,
2112 Runtime::SetObjectProperty(isolate(), object, key, value, 2140 Runtime::SetObjectProperty(isolate(), object, key, value,
2113 language_mode()), 2141 language_mode()),
2114 Object); 2142 Object);
2115 } 2143 }
2116 2144
2117 DCHECK(!is_target_set()); 2145 if (FLAG_vector_stores) {
2118 Code* megamorphic = *megamorphic_stub(); 2146 if (!is_vector_set() || stub.is_null()) {
2119 if (*stub == megamorphic) { 2147 Code* megamorphic = *megamorphic_stub();
2120 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 2148 if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) {
2121 } 2149 ConfigureVectorState(MEGAMORPHIC);
2122 if (*stub == *slow_stub()) { 2150 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
2123 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 2151 *stub == megamorphic ? "set generic" : "slow stub");
2124 } 2152 }
2125 DCHECK(!stub.is_null()); 2153 }
2126 if (!AddressIsDeoptimizedCode()) { 2154 } else {
2127 set_target(*stub); 2155 DCHECK(!is_target_set());
2156 Code* megamorphic = *megamorphic_stub();
2157 if (*stub == megamorphic) {
2158 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
2159 } else if (*stub == *slow_stub()) {
2160 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
2161 }
2162
2163 DCHECK(!stub.is_null());
2164 if (!AddressIsDeoptimizedCode()) {
2165 set_target(*stub);
2166 }
2128 } 2167 }
2129 TRACE_IC("StoreIC", key); 2168 TRACE_IC("StoreIC", key);
2130 2169
2131 return store_handle; 2170 return store_handle;
2132 } 2171 }
2133 2172
2134 2173
2135 bool CallIC::DoCustomHandler(Handle<Object> function, 2174 bool CallIC::DoCustomHandler(Handle<Object> function,
2136 const CallICState& callic_state) { 2175 const CallICState& callic_state) {
2137 DCHECK(FLAG_use_ic && function->IsJSFunction()); 2176 DCHECK(FLAG_use_ic && function->IsJSFunction());
(...skipping 28 matching lines...) Expand all
2166 } 2205 }
2167 return false; 2206 return false;
2168 } 2207 }
2169 2208
2170 2209
2171 void CallIC::PatchMegamorphic(Handle<Object> function) { 2210 void CallIC::PatchMegamorphic(Handle<Object> function) {
2172 CallICState callic_state(target()->extra_ic_state()); 2211 CallICState callic_state(target()->extra_ic_state());
2173 2212
2174 // We are going generic. 2213 // We are going generic.
2175 CallICNexus* nexus = casted_nexus<CallICNexus>(); 2214 CallICNexus* nexus = casted_nexus<CallICNexus>();
2176 nexus->ConfigureGeneric(); 2215 nexus->ConfigureMegamorphic();
2177 2216
2178 // Vector-based ICs have a different calling convention in optimized code 2217 // Vector-based ICs have a different calling convention in optimized code
2179 // than full code so the correct stub has to be chosen. 2218 // than full code so the correct stub has to be chosen.
2180 if (AddressIsOptimizedCode()) { 2219 if (AddressIsOptimizedCode()) {
2181 CallICStub stub(isolate(), callic_state); 2220 CallICStub stub(isolate(), callic_state);
2182 set_target(*stub.GetCode()); 2221 set_target(*stub.GetCode());
2183 } else { 2222 } else {
2184 CallICTrampolineStub stub(isolate(), callic_state); 2223 CallICTrampolineStub stub(isolate(), callic_state);
2185 set_target(*stub.GetCode()); 2224 set_target(*stub.GetCode());
2186 } 2225 }
(...skipping 14 matching lines...) Expand all
2201 CallICState callic_state(target()->extra_ic_state()); 2240 CallICState callic_state(target()->extra_ic_state());
2202 Handle<Object> name = isolate()->factory()->empty_string(); 2241 Handle<Object> name = isolate()->factory()->empty_string();
2203 CallICNexus* nexus = casted_nexus<CallICNexus>(); 2242 CallICNexus* nexus = casted_nexus<CallICNexus>();
2204 Object* feedback = nexus->GetFeedback(); 2243 Object* feedback = nexus->GetFeedback();
2205 2244
2206 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. 2245 // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
2207 DCHECK(!feedback->IsSmi()); 2246 DCHECK(!feedback->IsSmi());
2208 2247
2209 if (feedback->IsWeakCell() || !function->IsJSFunction()) { 2248 if (feedback->IsWeakCell() || !function->IsJSFunction()) {
2210 // We are going generic. 2249 // We are going generic.
2211 nexus->ConfigureGeneric(); 2250 nexus->ConfigureMegamorphic();
2212 } else { 2251 } else {
2213 // The feedback is either uninitialized or an allocation site. 2252 // The feedback is either uninitialized or an allocation site.
2214 // It might be an allocation site because if we re-compile the full code 2253 // It might be an allocation site because if we re-compile the full code
2215 // to add deoptimization support, we call with the default call-ic, and 2254 // to add deoptimization support, we call with the default call-ic, and
2216 // merely need to patch the target to match the feedback. 2255 // merely need to patch the target to match the feedback.
2217 // TODO(mvstanton): the better approach is to dispense with patching 2256 // TODO(mvstanton): the better approach is to dispense with patching
2218 // altogether, which is in progress. 2257 // altogether, which is in progress.
2219 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || 2258 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) ||
2220 feedback->IsAllocationSite()); 2259 feedback->IsAllocationSite());
2221 2260
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2346 2385
2347 return *result; 2386 return *result;
2348 } 2387 }
2349 2388
2350 2389
2351 // Used from ic-<arch>.cc. 2390 // Used from ic-<arch>.cc.
2352 RUNTIME_FUNCTION(StoreIC_Miss) { 2391 RUNTIME_FUNCTION(StoreIC_Miss) {
2353 TimerEventScope<TimerEventIcMiss> timer(isolate); 2392 TimerEventScope<TimerEventIcMiss> timer(isolate);
2354 HandleScope scope(isolate); 2393 HandleScope scope(isolate);
2355 DCHECK(args.length() == 3);
2356 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2357 Handle<Object> receiver = args.at<Object>(0); 2394 Handle<Object> receiver = args.at<Object>(0);
2358 Handle<Name> key = args.at<Name>(1); 2395 Handle<Name> key = args.at<Name>(1);
2359 ic.UpdateState(receiver, key); 2396 Handle<Object> value = args.at<Object>(2);
2360 Handle<Object> result; 2397 Handle<Object> result;
2361 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2398
2362 isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2399 if (FLAG_vector_stores) {
2400 DCHECK(args.length() == 5);
2401 Handle<Smi> slot = args.at<Smi>(3);
2402 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
2403 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2404 if (vector->GetKind(vector_slot) == Code::STORE_IC) {
2405 StoreICNexus nexus(vector, vector_slot);
2406 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2407 ic.UpdateState(receiver, key);
2408 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2409 ic.Store(receiver, key, value));
2410 } else {
2411 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_STORE_IC);
2412 KeyedStoreICNexus nexus(vector, vector_slot);
2413 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2414 ic.UpdateState(receiver, key);
2415 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2416 ic.Store(receiver, key, value));
2417 }
2418 } else {
2419 DCHECK(args.length() == 3);
2420 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2421 ic.UpdateState(receiver, key);
2422 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2423 ic.Store(receiver, key, value));
2424 }
2363 return *result; 2425 return *result;
2364 } 2426 }
2365 2427
2366 2428
2367 RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) { 2429 RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) {
2368 TimerEventScope<TimerEventIcMiss> timer(isolate); 2430 TimerEventScope<TimerEventIcMiss> timer(isolate);
2369 HandleScope scope(isolate); 2431 HandleScope scope(isolate);
2370 DCHECK(args.length() == 3 || args.length() == 4);
2371 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2372 Handle<Object> receiver = args.at<Object>(0); 2432 Handle<Object> receiver = args.at<Object>(0);
2373 Handle<Name> key = args.at<Name>(1); 2433 Handle<Name> key = args.at<Name>(1);
2374 ic.UpdateState(receiver, key); 2434 Handle<Object> value = args.at<Object>(2);
2375 Handle<Object> result; 2435 Handle<Object> result;
2376 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2436
2377 isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2437 if (FLAG_vector_stores) {
2438 DCHECK(args.length() == 5);
2439 Handle<Smi> slot = args.at<Smi>(3);
2440 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
2441 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2442 if (vector->GetKind(vector_slot) == Code::STORE_IC) {
2443 StoreICNexus nexus(vector, vector_slot);
2444 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2445 ic.UpdateState(receiver, key);
2446 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2447 ic.Store(receiver, key, value));
2448 } else {
2449 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_STORE_IC);
2450 KeyedStoreICNexus nexus(vector, vector_slot);
2451 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2452 ic.UpdateState(receiver, key);
2453 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2454 ic.Store(receiver, key, value));
2455 }
2456 } else {
2457 DCHECK(args.length() == 3 || args.length() == 4);
2458 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2459 ic.UpdateState(receiver, key);
2460 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2461 ic.Store(receiver, key, value));
2462 }
2378 return *result; 2463 return *result;
2379 } 2464 }
2380 2465
2381 2466
2382 // Used from ic-<arch>.cc. 2467 // Used from ic-<arch>.cc.
2383 RUNTIME_FUNCTION(KeyedStoreIC_Miss) { 2468 RUNTIME_FUNCTION(KeyedStoreIC_Miss) {
2384 TimerEventScope<TimerEventIcMiss> timer(isolate); 2469 TimerEventScope<TimerEventIcMiss> timer(isolate);
2385 HandleScope scope(isolate); 2470 HandleScope scope(isolate);
2386 DCHECK(args.length() == 3);
2387 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2388 Handle<Object> receiver = args.at<Object>(0); 2471 Handle<Object> receiver = args.at<Object>(0);
2389 Handle<Object> key = args.at<Object>(1); 2472 Handle<Object> key = args.at<Object>(1);
2390 ic.UpdateState(receiver, key); 2473 Handle<Object> value = args.at<Object>(2);
2391 Handle<Object> result; 2474 Handle<Object> result;
2392 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2475
2393 isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2476 if (FLAG_vector_stores) {
2477 DCHECK(args.length() == 5);
2478 Handle<Smi> slot = args.at<Smi>(3);
2479 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
2480 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2481 KeyedStoreICNexus nexus(vector, vector_slot);
2482 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2483 ic.UpdateState(receiver, key);
2484 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2485 ic.Store(receiver, key, value));
2486 } else {
2487 DCHECK(args.length() == 3);
2488 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2489 ic.UpdateState(receiver, key);
2490 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2491 ic.Store(receiver, key, value));
2492 }
2394 return *result; 2493 return *result;
2395 } 2494 }
2396 2495
2397 2496
2398 RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure) { 2497 RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure) {
2399 TimerEventScope<TimerEventIcMiss> timer(isolate); 2498 TimerEventScope<TimerEventIcMiss> timer(isolate);
2400 HandleScope scope(isolate); 2499 HandleScope scope(isolate);
2401 DCHECK(args.length() == 3);
2402 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2403 Handle<Object> receiver = args.at<Object>(0); 2500 Handle<Object> receiver = args.at<Object>(0);
2404 Handle<Object> key = args.at<Object>(1); 2501 Handle<Object> key = args.at<Object>(1);
2405 ic.UpdateState(receiver, key); 2502 Handle<Object> value = args.at<Object>(2);
2406 Handle<Object> result; 2503 Handle<Object> result;
2407 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2504
2408 isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2505 if (FLAG_vector_stores) {
2506 DCHECK(args.length() == 5);
2507 Handle<Smi> slot = args.at<Smi>(3);
2508 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
2509 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2510 KeyedStoreICNexus nexus(vector, vector_slot);
2511 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2512 ic.UpdateState(receiver, key);
2513 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2514 ic.Store(receiver, key, value));
2515 } else {
2516 DCHECK(args.length() == 3);
2517 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2518 ic.UpdateState(receiver, key);
2519 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2520 isolate, result, ic.Store(receiver, key, args.at<Object>(2)));
2521 }
2409 return *result; 2522 return *result;
2410 } 2523 }
2411 2524
2412 2525
2413 RUNTIME_FUNCTION(StoreIC_Slow) { 2526 RUNTIME_FUNCTION(StoreIC_Slow) {
2414 HandleScope scope(isolate); 2527 HandleScope scope(isolate);
2415 DCHECK(args.length() == 3); 2528 DCHECK(args.length() == 3);
2416 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2529 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2417 Handle<Object> object = args.at<Object>(0); 2530 Handle<Object> object = args.at<Object>(0);
2418 Handle<Object> key = args.at<Object>(1); 2531 Handle<Object> key = args.at<Object>(1);
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 static const Address IC_utilities[] = { 3051 static const Address IC_utilities[] = {
2939 #define ADDR(name) FUNCTION_ADDR(name), 3052 #define ADDR(name) FUNCTION_ADDR(name),
2940 IC_UTIL_LIST(ADDR) NULL 3053 IC_UTIL_LIST(ADDR) NULL
2941 #undef ADDR 3054 #undef ADDR
2942 }; 3055 };
2943 3056
2944 3057
2945 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 3058 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
2946 } // namespace internal 3059 } // namespace internal
2947 } // namespace v8 3060 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698