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