OLD | NEW |
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" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 bool for_queries_only) | 143 bool for_queries_only) |
144 : isolate_(isolate), | 144 : isolate_(isolate), |
145 target_set_(false), | 145 target_set_(false), |
146 vector_set_(false), | 146 vector_set_(false), |
147 target_maps_set_(false), | 147 target_maps_set_(false), |
148 nexus_(nexus) { | 148 nexus_(nexus) { |
149 // To improve the performance of the (much used) IC code, we unfold a few | 149 // To improve the performance of the (much used) IC code, we unfold a few |
150 // levels of the stack frame iteration code. This yields a ~35% speedup when | 150 // levels of the stack frame iteration code. This yields a ~35% speedup when |
151 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. | 151 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. |
152 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); | 152 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); |
153 Address constant_pool = NULL; | 153 Address* constant_pool = NULL; |
154 if (FLAG_enable_ool_constant_pool) { | 154 if (FLAG_enable_embedded_constant_pool) { |
155 constant_pool = | 155 constant_pool = reinterpret_cast<Address*>( |
156 Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset); | 156 entry + ExitFrameConstants::kConstantPoolOffset); |
157 } | 157 } |
158 Address* pc_address = | 158 Address* pc_address = |
159 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); | 159 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); |
160 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); | 160 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); |
161 // If there's another JavaScript frame on the stack or a | 161 // If there's another JavaScript frame on the stack or a |
162 // StubFailureTrampoline, we need to look one frame further down the stack to | 162 // StubFailureTrampoline, we need to look one frame further down the stack to |
163 // find the frame pointer and the return address stack slot. | 163 // find the frame pointer and the return address stack slot. |
164 if (depth == EXTRA_CALL_FRAME) { | 164 if (depth == EXTRA_CALL_FRAME) { |
165 if (FLAG_enable_ool_constant_pool) { | 165 if (FLAG_enable_embedded_constant_pool) { |
166 constant_pool = | 166 constant_pool = reinterpret_cast<Address*>( |
167 Memory::Address_at(fp + StandardFrameConstants::kConstantPoolOffset); | 167 fp + StandardFrameConstants::kConstantPoolOffset); |
168 } | 168 } |
169 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; | 169 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; |
170 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); | 170 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); |
171 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 171 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
172 } | 172 } |
173 #ifdef DEBUG | 173 #ifdef DEBUG |
174 StackFrameIterator it(isolate); | 174 StackFrameIterator it(isolate); |
175 for (int i = 0; i < depth + 1; i++) it.Advance(); | 175 for (int i = 0; i < depth + 1; i++) it.Advance(); |
176 StackFrame* frame = it.frame(); | 176 StackFrame* frame = it.frame(); |
177 DCHECK(fp == frame->fp() && pc_address == frame->pc_address()); | 177 DCHECK(fp == frame->fp() && pc_address == frame->pc_address()); |
178 #endif | 178 #endif |
179 fp_ = fp; | 179 fp_ = fp; |
180 if (FLAG_enable_ool_constant_pool) { | 180 if (FLAG_enable_embedded_constant_pool) { |
181 raw_constant_pool_ = handle( | 181 constant_pool_address_ = constant_pool; |
182 ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)), | |
183 isolate); | |
184 } | 182 } |
185 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); | 183 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
186 target_ = handle(raw_target(), isolate); | 184 target_ = handle(raw_target(), isolate); |
187 kind_ = target_->kind(); | 185 kind_ = target_->kind(); |
188 state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback() | 186 state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback() |
189 : target_->ic_state(); | 187 : target_->ic_state(); |
190 old_state_ = state_; | 188 old_state_ = state_; |
191 extra_ic_state_ = target_->extra_ic_state(); | 189 extra_ic_state_ = target_->extra_ic_state(); |
192 } | 190 } |
193 | 191 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 old_state = old_target->ic_state(); | 479 old_state = old_target->ic_state(); |
482 new_state = target->ic_state(); | 480 new_state = target->ic_state(); |
483 target_remains_ic_stub = true; | 481 target_remains_ic_stub = true; |
484 } | 482 } |
485 | 483 |
486 OnTypeFeedbackChanged(isolate, address, old_state, new_state, | 484 OnTypeFeedbackChanged(isolate, address, old_state, new_state, |
487 target_remains_ic_stub); | 485 target_remains_ic_stub); |
488 } | 486 } |
489 | 487 |
490 | 488 |
491 void IC::Clear(Isolate* isolate, Address address, | 489 void IC::Clear(Isolate* isolate, Address address, Address constant_pool) { |
492 ConstantPoolArray* constant_pool) { | |
493 Code* target = GetTargetAtAddress(address, constant_pool); | 490 Code* target = GetTargetAtAddress(address, constant_pool); |
494 | 491 |
495 // Don't clear debug break inline cache as it will remove the break point. | 492 // Don't clear debug break inline cache as it will remove the break point. |
496 if (target->is_debug_stub()) return; | 493 if (target->is_debug_stub()) return; |
497 | 494 |
498 switch (target->kind()) { | 495 switch (target->kind()) { |
499 case Code::LOAD_IC: | 496 case Code::LOAD_IC: |
500 if (FLAG_vector_ics) return; | 497 if (FLAG_vector_ics) return; |
501 return LoadIC::Clear(isolate, address, target, constant_pool); | 498 return LoadIC::Clear(isolate, address, target, constant_pool); |
502 case Code::KEYED_LOAD_IC: | 499 case Code::KEYED_LOAD_IC: |
(...skipping 13 matching lines...) Expand all Loading... |
516 // Clearing these is tricky and does not | 513 // Clearing these is tricky and does not |
517 // make any performance difference. | 514 // make any performance difference. |
518 return; | 515 return; |
519 default: | 516 default: |
520 UNREACHABLE(); | 517 UNREACHABLE(); |
521 } | 518 } |
522 } | 519 } |
523 | 520 |
524 | 521 |
525 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, | 522 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, |
526 ConstantPoolArray* constant_pool) { | 523 Address constant_pool) { |
527 DCHECK(!FLAG_vector_ics); | 524 DCHECK(!FLAG_vector_ics); |
528 if (IsCleared(target)) return; | 525 if (IsCleared(target)) return; |
529 | 526 |
530 // Make sure to also clear the map used in inline fast cases. If we | 527 // Make sure to also clear the map used in inline fast cases. If we |
531 // do not clear these maps, cached code can keep objects alive | 528 // do not clear these maps, cached code can keep objects alive |
532 // through the embedded maps. | 529 // through the embedded maps. |
533 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); | 530 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); |
534 } | 531 } |
535 | 532 |
536 | 533 |
(...skipping 15 matching lines...) Expand all Loading... |
552 | 549 |
553 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) { | 550 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) { |
554 nexus->ConfigureUninitialized(); | 551 nexus->ConfigureUninitialized(); |
555 // The change in state must be processed. | 552 // The change in state must be processed. |
556 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED); | 553 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED); |
557 } | 554 } |
558 } | 555 } |
559 | 556 |
560 | 557 |
561 void LoadIC::Clear(Isolate* isolate, Address address, Code* target, | 558 void LoadIC::Clear(Isolate* isolate, Address address, Code* target, |
562 ConstantPoolArray* constant_pool) { | 559 Address constant_pool) { |
563 DCHECK(!FLAG_vector_ics); | 560 DCHECK(!FLAG_vector_ics); |
564 if (IsCleared(target)) return; | 561 if (IsCleared(target)) return; |
565 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, | 562 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, |
566 target->extra_ic_state()); | 563 target->extra_ic_state()); |
567 SetTargetAtAddress(address, code, constant_pool); | 564 SetTargetAtAddress(address, code, constant_pool); |
568 } | 565 } |
569 | 566 |
570 | 567 |
571 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { | 568 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { |
572 if (IsCleared(nexus)) return; | 569 if (IsCleared(nexus)) return; |
573 State state = nexus->StateFromFeedback(); | 570 State state = nexus->StateFromFeedback(); |
574 nexus->ConfigurePremonomorphic(); | 571 nexus->ConfigurePremonomorphic(); |
575 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); | 572 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); |
576 } | 573 } |
577 | 574 |
578 | 575 |
579 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, | 576 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, |
580 ConstantPoolArray* constant_pool) { | 577 Address constant_pool) { |
581 if (IsCleared(target)) return; | 578 if (IsCleared(target)) return; |
582 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC, | 579 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC, |
583 target->extra_ic_state()); | 580 target->extra_ic_state()); |
584 SetTargetAtAddress(address, code, constant_pool); | 581 SetTargetAtAddress(address, code, constant_pool); |
585 } | 582 } |
586 | 583 |
587 | 584 |
588 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, | 585 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, |
589 ConstantPoolArray* constant_pool) { | 586 Address constant_pool) { |
590 if (IsCleared(target)) return; | 587 if (IsCleared(target)) return; |
591 SetTargetAtAddress( | 588 SetTargetAtAddress( |
592 address, *pre_monomorphic_stub( | 589 address, *pre_monomorphic_stub( |
593 isolate, StoreIC::GetLanguageMode(target->extra_ic_state())), | 590 isolate, StoreIC::GetLanguageMode(target->extra_ic_state())), |
594 constant_pool); | 591 constant_pool); |
595 } | 592 } |
596 | 593 |
597 | 594 |
598 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, | 595 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, |
599 ConstantPoolArray* constant_pool) { | 596 Address constant_pool) { |
600 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); | 597 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); |
601 CompareICStub stub(target->stub_key(), isolate); | 598 CompareICStub stub(target->stub_key(), isolate); |
602 // Only clear CompareICs that can retain objects. | 599 // Only clear CompareICs that can retain objects. |
603 if (stub.state() != CompareICState::KNOWN_OBJECT) return; | 600 if (stub.state() != CompareICState::KNOWN_OBJECT) return; |
604 SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()), | 601 SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()), |
605 constant_pool); | 602 constant_pool); |
606 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); | 603 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); |
607 } | 604 } |
608 | 605 |
609 | 606 |
(...skipping 2131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2741 // Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc. | 2738 // Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc. |
2742 RUNTIME_FUNCTION(CompareIC_Miss) { | 2739 RUNTIME_FUNCTION(CompareIC_Miss) { |
2743 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2740 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2744 HandleScope scope(isolate); | 2741 HandleScope scope(isolate); |
2745 DCHECK(args.length() == 3); | 2742 DCHECK(args.length() == 3); |
2746 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2743 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2747 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2744 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2748 } | 2745 } |
2749 | 2746 |
2750 | 2747 |
2751 void CompareNilIC::Clear(Address address, Code* target, | 2748 void CompareNilIC::Clear(Address address, Code* target, Address constant_pool) { |
2752 ConstantPoolArray* constant_pool) { | |
2753 if (IsCleared(target)) return; | 2749 if (IsCleared(target)) return; |
2754 ExtraICState state = target->extra_ic_state(); | 2750 ExtraICState state = target->extra_ic_state(); |
2755 | 2751 |
2756 CompareNilICStub stub(target->GetIsolate(), state, | 2752 CompareNilICStub stub(target->GetIsolate(), state, |
2757 HydrogenCodeStub::UNINITIALIZED); | 2753 HydrogenCodeStub::UNINITIALIZED); |
2758 stub.ClearState(); | 2754 stub.ClearState(); |
2759 | 2755 |
2760 Code* code = NULL; | 2756 Code* code = NULL; |
2761 CHECK(stub.FindCodeInCache(&code)); | 2757 CHECK(stub.FindCodeInCache(&code)); |
2762 | 2758 |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3052 static const Address IC_utilities[] = { | 3048 static const Address IC_utilities[] = { |
3053 #define ADDR(name) FUNCTION_ADDR(name), | 3049 #define ADDR(name) FUNCTION_ADDR(name), |
3054 IC_UTIL_LIST(ADDR) NULL | 3050 IC_UTIL_LIST(ADDR) NULL |
3055 #undef ADDR | 3051 #undef ADDR |
3056 }; | 3052 }; |
3057 | 3053 |
3058 | 3054 |
3059 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3055 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
3060 } | 3056 } |
3061 } // namespace v8::internal | 3057 } // namespace v8::internal |
OLD | NEW |