OLD | NEW |
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 Loading... |
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 GetTransitionMarkModifier( | 95 if (new_target->kind() == Code::KEYED_STORE_IC) { |
96 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); | 96 modifier = GetTransitionMarkModifier( |
| 97 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); |
| 98 } |
97 PrintF(" (%c->%c%s)", | 99 PrintF(" (%c->%c%s)", |
98 TransitionMarkFromState(state()), | 100 TransitionMarkFromState(state()), |
99 TransitionMarkFromState(new_state), | 101 TransitionMarkFromState(new_state), |
100 modifier); | 102 modifier); |
101 name->Print(); | 103 name->Print(); |
102 PrintF("]\n"); | 104 PrintF("]\n"); |
103 } | 105 } |
104 } | 106 } |
105 | 107 |
106 #define TRACE_GENERIC_IC(isolate, type, reason) \ | 108 #define TRACE_GENERIC_IC(isolate, type, reason) \ |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 Isolate* isolate = target->GetHeap()->isolate(); | 410 Isolate* isolate = target->GetHeap()->isolate(); |
409 Code* host = isolate-> | 411 Code* host = isolate-> |
410 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; | 412 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; |
411 if (host->kind() != Code::FUNCTION) return; | 413 if (host->kind() != Code::FUNCTION) return; |
412 | 414 |
413 if (FLAG_type_info_threshold > 0 && | 415 if (FLAG_type_info_threshold > 0 && |
414 old_target->is_inline_cache_stub() && | 416 old_target->is_inline_cache_stub() && |
415 target->is_inline_cache_stub()) { | 417 target->is_inline_cache_stub()) { |
416 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(), | 418 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(), |
417 target->ic_state()); | 419 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 |
418 // Not all Code objects have TypeFeedbackInfo. | 424 // Not all Code objects have TypeFeedbackInfo. |
419 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) { | 425 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) { |
420 TypeFeedbackInfo* info = | 426 TypeFeedbackInfo* info = |
421 TypeFeedbackInfo::cast(host->type_feedback_info()); | 427 TypeFeedbackInfo::cast(host->type_feedback_info()); |
422 info->change_ic_with_type_info_count(delta); | 428 info->change_ic_with_type_info_count(delta); |
423 } | 429 } |
424 } | 430 } |
425 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { | 431 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { |
426 TypeFeedbackInfo* info = | 432 TypeFeedbackInfo* info = |
427 TypeFeedbackInfo::cast(host->type_feedback_info()); | 433 TypeFeedbackInfo::cast(host->type_feedback_info()); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 | 486 |
481 switch (target->kind()) { | 487 switch (target->kind()) { |
482 case Code::LOAD_IC: | 488 case Code::LOAD_IC: |
483 return LoadIC::Clear(isolate, address, target, constant_pool); | 489 return LoadIC::Clear(isolate, address, target, constant_pool); |
484 case Code::KEYED_LOAD_IC: | 490 case Code::KEYED_LOAD_IC: |
485 return KeyedLoadIC::Clear(isolate, address, target, constant_pool); | 491 return KeyedLoadIC::Clear(isolate, address, target, constant_pool); |
486 case Code::STORE_IC: | 492 case Code::STORE_IC: |
487 return StoreIC::Clear(isolate, address, target, constant_pool); | 493 return StoreIC::Clear(isolate, address, target, constant_pool); |
488 case Code::KEYED_STORE_IC: | 494 case Code::KEYED_STORE_IC: |
489 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); | 495 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); |
| 496 case Code::CALL_IC: |
| 497 return CallIC::Clear(isolate, address, target, constant_pool); |
490 case Code::COMPARE_IC: | 498 case Code::COMPARE_IC: |
491 return CompareIC::Clear(isolate, address, target, constant_pool); | 499 return CompareIC::Clear(isolate, address, target, constant_pool); |
492 case Code::COMPARE_NIL_IC: | 500 case Code::COMPARE_NIL_IC: |
493 return CompareNilIC::Clear(address, target, constant_pool); | 501 return CompareNilIC::Clear(address, target, constant_pool); |
494 case Code::BINARY_OP_IC: | 502 case Code::BINARY_OP_IC: |
495 case Code::TO_BOOLEAN_IC: | 503 case Code::TO_BOOLEAN_IC: |
496 // Clearing these is tricky and does not | 504 // Clearing these is tricky and does not |
497 // make any performance difference. | 505 // make any performance difference. |
498 return; | 506 return; |
499 default: UNREACHABLE(); | 507 default: UNREACHABLE(); |
500 } | 508 } |
501 } | 509 } |
502 | 510 |
503 | 511 |
504 void KeyedLoadIC::Clear(Isolate* isolate, | 512 void KeyedLoadIC::Clear(Isolate* isolate, |
505 Address address, | 513 Address address, |
506 Code* target, | 514 Code* target, |
507 ConstantPoolArray* constant_pool) { | 515 ConstantPoolArray* constant_pool) { |
508 if (IsCleared(target)) return; | 516 if (IsCleared(target)) return; |
509 // Make sure to also clear the map used in inline fast cases. If we | 517 // Make sure to also clear the map used in inline fast cases. If we |
510 // do not clear these maps, cached code can keep objects alive | 518 // do not clear these maps, cached code can keep objects alive |
511 // through the embedded maps. | 519 // through the embedded maps. |
512 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); | 520 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); |
513 } | 521 } |
514 | 522 |
515 | 523 |
| 524 void CallIC::Clear(Isolate* isolate, |
| 525 Address address, |
| 526 Code* target, |
| 527 ConstantPoolArray* constant_pool) { |
| 528 // Currently, CallIC doesn't have state changes. |
| 529 ASSERT(target->ic_state() == v8::internal::GENERIC); |
| 530 } |
| 531 |
| 532 |
516 void LoadIC::Clear(Isolate* isolate, | 533 void LoadIC::Clear(Isolate* isolate, |
517 Address address, | 534 Address address, |
518 Code* target, | 535 Code* target, |
519 ConstantPoolArray* constant_pool) { | 536 ConstantPoolArray* constant_pool) { |
520 if (IsCleared(target)) return; | 537 if (IsCleared(target)) return; |
521 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( | 538 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
522 Code::LOAD_IC, target->extra_ic_state()); | 539 Code::LOAD_IC, target->extra_ic_state()); |
523 SetTargetAtAddress(address, code, constant_pool); | 540 SetTargetAtAddress(address, code, constant_pool); |
524 } | 541 } |
525 | 542 |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 ASSIGN_RETURN_ON_EXCEPTION( | 1353 ASSIGN_RETURN_ON_EXCEPTION( |
1337 isolate(), | 1354 isolate(), |
1338 result, | 1355 result, |
1339 JSReceiver::SetProperty( | 1356 JSReceiver::SetProperty( |
1340 receiver, name, value, NONE, strict_mode(), store_mode), | 1357 receiver, name, value, NONE, strict_mode(), store_mode), |
1341 Object); | 1358 Object); |
1342 return result; | 1359 return result; |
1343 } | 1360 } |
1344 | 1361 |
1345 | 1362 |
| 1363 void CallIC::State::Print(StringStream* stream) const { |
| 1364 stream->Add("(args(%d), ", |
| 1365 argc_); |
| 1366 stream->Add("%s, ", |
| 1367 call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION"); |
| 1368 } |
| 1369 |
| 1370 |
| 1371 Handle<Code> CallIC::initialize_stub(Isolate* isolate, |
| 1372 int argc, |
| 1373 CallType call_type) { |
| 1374 CallICStub stub(State::DefaultCallState(argc, call_type)); |
| 1375 Handle<Code> code = stub.GetCode(isolate); |
| 1376 return code; |
| 1377 } |
| 1378 |
| 1379 |
1346 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | 1380 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
1347 StrictMode strict_mode) { | 1381 StrictMode strict_mode) { |
1348 ExtraICState extra_state = ComputeExtraICState(strict_mode); | 1382 ExtraICState extra_state = ComputeExtraICState(strict_mode); |
1349 Handle<Code> ic = isolate->stub_cache()->ComputeStore( | 1383 Handle<Code> ic = isolate->stub_cache()->ComputeStore( |
1350 UNINITIALIZED, extra_state); | 1384 UNINITIALIZED, extra_state); |
1351 return ic; | 1385 return ic; |
1352 } | 1386 } |
1353 | 1387 |
1354 | 1388 |
1355 Handle<Code> StoreIC::megamorphic_stub() { | 1389 Handle<Code> StoreIC::megamorphic_stub() { |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 ASSIGN_RETURN_ON_EXCEPTION( | 1849 ASSIGN_RETURN_ON_EXCEPTION( |
1816 isolate(), | 1850 isolate(), |
1817 result, | 1851 result, |
1818 Runtime::SetObjectProperty( | 1852 Runtime::SetObjectProperty( |
1819 isolate(), object, key, value, NONE, strict_mode()), | 1853 isolate(), object, key, value, NONE, strict_mode()), |
1820 Object); | 1854 Object); |
1821 return result; | 1855 return result; |
1822 } | 1856 } |
1823 | 1857 |
1824 | 1858 |
| 1859 CallIC::State::State(ExtraICState extra_ic_state) |
| 1860 : argc_(ArgcBits::decode(extra_ic_state)), |
| 1861 call_type_(CallTypeBits::decode(extra_ic_state)) { |
| 1862 } |
| 1863 |
| 1864 |
| 1865 ExtraICState CallIC::State::GetExtraICState() const { |
| 1866 ExtraICState extra_ic_state = |
| 1867 ArgcBits::encode(argc_) | |
| 1868 CallTypeBits::encode(call_type_); |
| 1869 return extra_ic_state; |
| 1870 } |
| 1871 |
| 1872 |
| 1873 void CallIC::HandleMiss(Handle<Object> receiver, |
| 1874 Handle<Object> function, |
| 1875 Handle<FixedArray> vector, |
| 1876 Handle<Smi> slot) { |
| 1877 State state(target()->extra_ic_state()); |
| 1878 Object* feedback = vector->get(slot->value()); |
| 1879 |
| 1880 if (feedback->IsJSFunction() || !function->IsJSFunction()) { |
| 1881 // We are going generic. |
| 1882 ASSERT(!function->IsJSFunction() || *function != feedback); |
| 1883 |
| 1884 vector->set(slot->value(), |
| 1885 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), |
| 1886 SKIP_WRITE_BARRIER); |
| 1887 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); |
| 1888 } else { |
| 1889 // If we came here feedback must be the uninitialized sentinel, |
| 1890 // and we are going monomorphic. |
| 1891 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); |
| 1892 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
| 1893 Handle<Object> name(js_function->shared()->name(), isolate()); |
| 1894 TRACE_IC("CallIC", name); |
| 1895 vector->set(slot->value(), *function); |
| 1896 } |
| 1897 } |
| 1898 |
| 1899 |
1825 #undef TRACE_IC | 1900 #undef TRACE_IC |
1826 | 1901 |
1827 | 1902 |
1828 // ---------------------------------------------------------------------------- | 1903 // ---------------------------------------------------------------------------- |
1829 // Static IC stub generators. | 1904 // Static IC stub generators. |
1830 // | 1905 // |
1831 | 1906 |
1832 // Used from ic-<arch>.cc. | 1907 // Used from ic-<arch>.cc. |
| 1908 RUNTIME_FUNCTION(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 |
1833 // Used from ic-<arch>.cc. | 1921 // Used from ic-<arch>.cc. |
1834 RUNTIME_FUNCTION(LoadIC_Miss) { | 1922 RUNTIME_FUNCTION(LoadIC_Miss) { |
1835 HandleScope scope(isolate); | 1923 HandleScope scope(isolate); |
1836 ASSERT(args.length() == 2); | 1924 ASSERT(args.length() == 2); |
1837 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 1925 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
1838 Handle<Object> receiver = args.at<Object>(0); | 1926 Handle<Object> receiver = args.at<Object>(0); |
1839 Handle<String> key = args.at<String>(1); | 1927 Handle<String> key = args.at<String>(1); |
1840 ic.UpdateState(receiver, key); | 1928 ic.UpdateState(receiver, key); |
1841 Handle<Object> result; | 1929 Handle<Object> result; |
1842 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 1930 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2947 #undef ADDR | 3035 #undef ADDR |
2948 }; | 3036 }; |
2949 | 3037 |
2950 | 3038 |
2951 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3039 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2952 return IC_utilities[id]; | 3040 return IC_utilities[id]; |
2953 } | 3041 } |
2954 | 3042 |
2955 | 3043 |
2956 } } // namespace v8::internal | 3044 } } // namespace v8::internal |
OLD | NEW |