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

Side by Side Diff: src/ic.cc

Issue 226233002: Revert "Reland of https://codereview.chromium.org/172523002/" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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/log.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 // 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 Code* apply_builtin = isolate()->builtins()->builtin( 84 Code* apply_builtin = isolate()->builtins()->builtin(
85 Builtins::kFunctionApply); 85 Builtins::kFunctionApply);
86 if (raw_frame->unchecked_code() == apply_builtin) { 86 if (raw_frame->unchecked_code() == apply_builtin) {
87 PrintF("apply from "); 87 PrintF("apply from ");
88 it.Advance(); 88 it.Advance();
89 raw_frame = it.frame(); 89 raw_frame = it.frame();
90 } 90 }
91 } 91 }
92 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 92 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
93 ExtraICState extra_state = new_target->extra_ic_state(); 93 ExtraICState extra_state = new_target->extra_ic_state();
94 const char* modifier = ""; 94 const char* modifier =
95 if (new_target->kind() == Code::KEYED_STORE_IC) { 95 GetTransitionMarkModifier(
96 modifier = GetTransitionMarkModifier( 96 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
97 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
98 }
99 PrintF(" (%c->%c%s)", 97 PrintF(" (%c->%c%s)",
100 TransitionMarkFromState(state()), 98 TransitionMarkFromState(state()),
101 TransitionMarkFromState(new_state), 99 TransitionMarkFromState(new_state),
102 modifier); 100 modifier);
103 name->Print(); 101 name->Print();
104 PrintF("]\n"); 102 PrintF("]\n");
105 } 103 }
106 } 104 }
107 105
108 #define TRACE_GENERIC_IC(isolate, type, reason) \ 106 #define TRACE_GENERIC_IC(isolate, type, reason) \
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 Isolate* isolate = target->GetHeap()->isolate(); 408 Isolate* isolate = target->GetHeap()->isolate();
411 Code* host = isolate-> 409 Code* host = isolate->
412 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; 410 inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
413 if (host->kind() != Code::FUNCTION) return; 411 if (host->kind() != Code::FUNCTION) return;
414 412
415 if (FLAG_type_info_threshold > 0 && 413 if (FLAG_type_info_threshold > 0 &&
416 old_target->is_inline_cache_stub() && 414 old_target->is_inline_cache_stub() &&
417 target->is_inline_cache_stub()) { 415 target->is_inline_cache_stub()) {
418 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(), 416 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
419 target->ic_state()); 417 target->ic_state());
420 // Call ICs don't have interesting state changes from this point
421 // of view.
422 ASSERT(target->kind() != Code::CALL_IC || delta == 0);
423
424 // Not all Code objects have TypeFeedbackInfo. 418 // Not all Code objects have TypeFeedbackInfo.
425 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) { 419 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
426 TypeFeedbackInfo* info = 420 TypeFeedbackInfo* info =
427 TypeFeedbackInfo::cast(host->type_feedback_info()); 421 TypeFeedbackInfo::cast(host->type_feedback_info());
428 info->change_ic_with_type_info_count(delta); 422 info->change_ic_with_type_info_count(delta);
429 } 423 }
430 } 424 }
431 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { 425 if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
432 TypeFeedbackInfo* info = 426 TypeFeedbackInfo* info =
433 TypeFeedbackInfo::cast(host->type_feedback_info()); 427 TypeFeedbackInfo::cast(host->type_feedback_info());
(...skipping 16 matching lines...) Expand all
450 444
451 switch (target->kind()) { 445 switch (target->kind()) {
452 case Code::LOAD_IC: 446 case Code::LOAD_IC:
453 return LoadIC::Clear(isolate, address, target, constant_pool); 447 return LoadIC::Clear(isolate, address, target, constant_pool);
454 case Code::KEYED_LOAD_IC: 448 case Code::KEYED_LOAD_IC:
455 return KeyedLoadIC::Clear(isolate, address, target, constant_pool); 449 return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
456 case Code::STORE_IC: 450 case Code::STORE_IC:
457 return StoreIC::Clear(isolate, address, target, constant_pool); 451 return StoreIC::Clear(isolate, address, target, constant_pool);
458 case Code::KEYED_STORE_IC: 452 case Code::KEYED_STORE_IC:
459 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); 453 return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
460 case Code::CALL_IC:
461 return CallIC::Clear(isolate, address, target, constant_pool);
462 case Code::COMPARE_IC: 454 case Code::COMPARE_IC:
463 return CompareIC::Clear(isolate, address, target, constant_pool); 455 return CompareIC::Clear(isolate, address, target, constant_pool);
464 case Code::COMPARE_NIL_IC: 456 case Code::COMPARE_NIL_IC:
465 return CompareNilIC::Clear(address, target, constant_pool); 457 return CompareNilIC::Clear(address, target, constant_pool);
466 case Code::BINARY_OP_IC: 458 case Code::BINARY_OP_IC:
467 case Code::TO_BOOLEAN_IC: 459 case Code::TO_BOOLEAN_IC:
468 // Clearing these is tricky and does not 460 // Clearing these is tricky and does not
469 // make any performance difference. 461 // make any performance difference.
470 return; 462 return;
471 default: UNREACHABLE(); 463 default: UNREACHABLE();
472 } 464 }
473 } 465 }
474 466
475 467
476 void KeyedLoadIC::Clear(Isolate* isolate, 468 void KeyedLoadIC::Clear(Isolate* isolate,
477 Address address, 469 Address address,
478 Code* target, 470 Code* target,
479 ConstantPoolArray* constant_pool) { 471 ConstantPoolArray* constant_pool) {
480 if (IsCleared(target)) return; 472 if (IsCleared(target)) return;
481 // Make sure to also clear the map used in inline fast cases. If we 473 // Make sure to also clear the map used in inline fast cases. If we
482 // do not clear these maps, cached code can keep objects alive 474 // do not clear these maps, cached code can keep objects alive
483 // through the embedded maps. 475 // through the embedded maps.
484 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); 476 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool);
485 } 477 }
486 478
487 479
488 void CallIC::Clear(Isolate* isolate,
489 Address address,
490 Code* target,
491 ConstantPoolArray* constant_pool) {
492 // CallIC just has a generic stub and a monomorphic stub. Only clear if we
493 // are monomorphic
494 if (target->ic_state() != ::v8::internal::MONOMORPHIC) return;
495
496 CallIC::State existing_state(target->extra_ic_state());
497
498 // Install default stub with the immutable parts of existing state.
499 HandleScope scope(isolate);
500 CallICStub stub(State::DefaultCallState(existing_state.arg_count(),
501 existing_state.call_type()));
502 Code* code = *stub.GetCode(isolate);
503 SetTargetAtAddress(address, code, constant_pool);
504 }
505
506
507 void LoadIC::Clear(Isolate* isolate, 480 void LoadIC::Clear(Isolate* isolate,
508 Address address, 481 Address address,
509 Code* target, 482 Code* target,
510 ConstantPoolArray* constant_pool) { 483 ConstantPoolArray* constant_pool) {
511 if (IsCleared(target)) return; 484 if (IsCleared(target)) return;
512 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( 485 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC(
513 Code::LOAD_IC, target->extra_ic_state()); 486 Code::LOAD_IC, target->extra_ic_state());
514 SetTargetAtAddress(address, code, constant_pool); 487 SetTargetAtAddress(address, code, constant_pool);
515 } 488 }
516 489
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 // Set the property. 1269 // Set the property.
1297 Handle<Object> result; 1270 Handle<Object> result;
1298 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1271 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1299 isolate(), result, 1272 isolate(), result,
1300 JSReceiver::SetProperty( 1273 JSReceiver::SetProperty(
1301 receiver, name, value, NONE, strict_mode(), store_mode)); 1274 receiver, name, value, NONE, strict_mode(), store_mode));
1302 return *result; 1275 return *result;
1303 } 1276 }
1304 1277
1305 1278
1306 void CallIC::State::Print(StringStream* stream) const {
1307 stream->Add("(args(%d), ",
1308 argc_);
1309 stream->Add("%s, ",
1310 call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION");
1311 stream->Add("%s, ",
1312 stub_type_ == CallIC::MONOMORPHIC ?
1313 "MONOMORPHIC" : "NOT_MONOMORPHIC");
1314 stream->Add("%s, ",
1315 argument_check_ == CallIC::ARGUMENTS_MUST_MATCH ?
1316 "args_must_match" : "args_might_match");
1317 stream->Add("%s)",
1318 strict_mode_ == STRICT ?
1319 "strict" : "sloppy");
1320 }
1321
1322
1323 Handle<Code> CallIC::initialize_stub(Isolate* isolate,
1324 int argc,
1325 CallType call_type) {
1326 CallICStub stub(State::DefaultCallState(argc, call_type));
1327 Handle<Code> code = stub.GetCode(isolate);
1328 return code;
1329 }
1330
1331
1332 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, 1279 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
1333 StrictMode strict_mode) { 1280 StrictMode strict_mode) {
1334 ExtraICState extra_state = ComputeExtraICState(strict_mode); 1281 ExtraICState extra_state = ComputeExtraICState(strict_mode);
1335 Handle<Code> ic = isolate->stub_cache()->ComputeStore( 1282 Handle<Code> ic = isolate->stub_cache()->ComputeStore(
1336 UNINITIALIZED, extra_state); 1283 UNINITIALIZED, extra_state);
1337 return ic; 1284 return ic;
1338 } 1285 }
1339 1286
1340 1287
1341 Handle<Code> StoreIC::megamorphic_stub() { 1288 Handle<Code> StoreIC::megamorphic_stub() {
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 if (maybe_object) return maybe_object; 1741 if (maybe_object) return maybe_object;
1795 Handle<Object> result; 1742 Handle<Object> result;
1796 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1743 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1797 isolate(), result, 1744 isolate(), result,
1798 Runtime::SetObjectProperty( 1745 Runtime::SetObjectProperty(
1799 isolate(), object, key, value, NONE, strict_mode())); 1746 isolate(), object, key, value, NONE, strict_mode()));
1800 return *result; 1747 return *result;
1801 } 1748 }
1802 1749
1803 1750
1804 CallIC::State::State(ExtraICState extra_ic_state)
1805 : argc_(ArgcBits::decode(extra_ic_state)),
1806 call_type_(CallTypeBits::decode(extra_ic_state)),
1807 stub_type_(StubTypeBits::decode(extra_ic_state)),
1808 argument_check_(ArgumentCheckBits::decode(extra_ic_state)),
1809 strict_mode_(StrictModeBits::decode(extra_ic_state)) {
1810 }
1811
1812
1813 ExtraICState CallIC::State::GetExtraICState() const {
1814 ExtraICState extra_ic_state =
1815 ArgcBits::encode(argc_) |
1816 CallTypeBits::encode(call_type_) |
1817 StubTypeBits::encode(stub_type_) |
1818 ArgumentCheckBits::encode(argument_check_) |
1819 StrictModeBits::encode(strict_mode_);
1820 return extra_ic_state;
1821 }
1822
1823
1824 CallIC::State CallIC::State::ToGenericState() {
1825 if (stub_type() == CallIC::MONOMORPHIC) {
1826 return DefaultCallState(arg_count(), call_type());
1827 }
1828 return *this;
1829 }
1830
1831
1832 CallIC::State CallIC::State::ToMonomorphicState(
1833 Handle<JSFunction> function) {
1834 // Choose the right monomorphic handler
1835 SharedFunctionInfo* shared = function->shared();
1836 ArgumentCheck new_argument_check =
1837 shared->formal_parameter_count() == arg_count()
1838 ? CallIC::ARGUMENTS_MUST_MATCH
1839 : CallIC::ARGUMENTS_COUNT_UNKNOWN;
1840 StrictMode new_strict_mode = shared->strict_mode();
1841 if (new_argument_check != argument_check() ||
1842 new_strict_mode != strict_mode()) {
1843 return MonomorphicCallState(arg_count(), call_type(), new_argument_check,
1844 new_strict_mode);
1845 }
1846
1847 return *this;
1848 }
1849
1850
1851 void CallIC::HandleMiss(Handle<Object> receiver,
1852 Handle<Object> function,
1853 Handle<FixedArray> vector,
1854 Handle<Smi> slot) {
1855 State state(target()->extra_ic_state());
1856 Object* feedback = vector->get(slot->value());
1857
1858 if (feedback->IsJSFunction() || !function->IsJSFunction()) {
1859 // We are going generic.
1860 ASSERT(!function->IsJSFunction() || *function != feedback);
1861
1862 vector->set(slot->value(),
1863 *TypeFeedbackInfo::MegamorphicSentinel(isolate()));
1864
1865 // We only need to patch if we currently don't have the default stub in
1866 // place.
1867 State new_state = state.ToGenericState();
1868 if (new_state != state) {
1869 CallICStub stub(new_state);
1870 set_target(*stub.GetCode(isolate()));
1871 TRACE_GENERIC_IC(isolate(), "CallIC", "generic");
1872 }
1873 } else {
1874 // If we came here feedback must be the uninitialized sentinel,
1875 // and we are going monomorphic.
1876 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()));
1877 ASSERT(state.stub_type() != CallIC::MONOMORPHIC);
1878
1879 vector->set(slot->value(), *function);
1880
1881 // Choose the right monomorphic handler
1882 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
1883 State new_state = state.ToMonomorphicState(js_function);
1884 if (new_state != state) {
1885 CallICStub stub(new_state);
1886 Handle<Code> code = stub.GetCode(isolate());
1887 // Creating the code above could result in a gc, which clears the type
1888 // vector. If that happens, our plan to go monomorphic has been
1889 // pre-empted.
1890 feedback = vector->get(slot->value());
1891 if (feedback == *function) {
1892 set_target(*code);
1893 TRACE_IC("CallIC", handle(js_function->shared()->name(), isolate()));
1894 }
1895 }
1896 }
1897 }
1898
1899
1900 #undef TRACE_IC 1751 #undef TRACE_IC
1901 1752
1902 1753
1903 // ---------------------------------------------------------------------------- 1754 // ----------------------------------------------------------------------------
1904 // Static IC stub generators. 1755 // Static IC stub generators.
1905 // 1756 //
1906 1757
1907 // Used from ic-<arch>.cc. 1758 // Used from ic-<arch>.cc.
1908 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
1909 HandleScope scope(isolate);
1910 ASSERT(args.length() == 4);
1911 CallIC ic(isolate);
1912 Handle<Object> receiver = args.at<Object>(0);
1913 Handle<Object> function = args.at<Object>(1);
1914 Handle<FixedArray> vector = args.at<FixedArray>(2);
1915 Handle<Smi> slot = args.at<Smi>(3);
1916 ic.HandleMiss(receiver, function, vector, slot);
1917 return *function;
1918 }
1919
1920
1921 // Used from ic-<arch>.cc. 1759 // Used from ic-<arch>.cc.
1922 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { 1760 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
1923 HandleScope scope(isolate); 1761 HandleScope scope(isolate);
1924 ASSERT(args.length() == 2); 1762 ASSERT(args.length() == 2);
1925 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 1763 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
1926 Handle<Object> receiver = args.at<Object>(0); 1764 Handle<Object> receiver = args.at<Object>(0);
1927 Handle<String> key = args.at<String>(1); 1765 Handle<String> key = args.at<String>(1);
1928 ic.UpdateState(receiver, key); 1766 ic.UpdateState(receiver, key);
1929 return ic.Load(receiver, key); 1767 return ic.Load(receiver, key);
1930 } 1768 }
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 #undef ADDR 2837 #undef ADDR
3000 }; 2838 };
3001 2839
3002 2840
3003 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2841 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3004 return IC_utilities[id]; 2842 return IC_utilities[id];
3005 } 2843 }
3006 2844
3007 2845
3008 } } // namespace v8::internal 2846 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/log.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698