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_embedded_constant_pool) { | 154 if (FLAG_enable_ool_constant_pool) { |
155 constant_pool = reinterpret_cast<Address*>( | 155 constant_pool = |
156 entry + ExitFrameConstants::kConstantPoolOffset); | 156 Memory::Address_at(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_embedded_constant_pool) { | 165 if (FLAG_enable_ool_constant_pool) { |
166 constant_pool = reinterpret_cast<Address*>( | 166 constant_pool = |
167 fp + StandardFrameConstants::kConstantPoolOffset); | 167 Memory::Address_at(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_embedded_constant_pool) { | 180 if (FLAG_enable_ool_constant_pool) { |
181 constant_pool_address_ = constant_pool; | 181 raw_constant_pool_ = handle( |
| 182 ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)), |
| 183 isolate); |
182 } | 184 } |
183 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); | 185 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
184 target_ = handle(raw_target(), isolate); | 186 target_ = handle(raw_target(), isolate); |
185 kind_ = target_->kind(); | 187 kind_ = target_->kind(); |
186 state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback() | 188 state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback() |
187 : target_->ic_state(); | 189 : target_->ic_state(); |
188 old_state_ = state_; | 190 old_state_ = state_; |
189 extra_ic_state_ = target_->extra_ic_state(); | 191 extra_ic_state_ = target_->extra_ic_state(); |
190 } | 192 } |
191 | 193 |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 old_state = old_target->ic_state(); | 472 old_state = old_target->ic_state(); |
471 new_state = target->ic_state(); | 473 new_state = target->ic_state(); |
472 target_remains_ic_stub = true; | 474 target_remains_ic_stub = true; |
473 } | 475 } |
474 | 476 |
475 OnTypeFeedbackChanged(isolate, address, old_state, new_state, | 477 OnTypeFeedbackChanged(isolate, address, old_state, new_state, |
476 target_remains_ic_stub); | 478 target_remains_ic_stub); |
477 } | 479 } |
478 | 480 |
479 | 481 |
480 void IC::Clear(Isolate* isolate, Address address, Address constant_pool) { | 482 void IC::Clear(Isolate* isolate, Address address, |
| 483 ConstantPoolArray* constant_pool) { |
481 Code* target = GetTargetAtAddress(address, constant_pool); | 484 Code* target = GetTargetAtAddress(address, constant_pool); |
482 | 485 |
483 // Don't clear debug break inline cache as it will remove the break point. | 486 // Don't clear debug break inline cache as it will remove the break point. |
484 if (target->is_debug_stub()) return; | 487 if (target->is_debug_stub()) return; |
485 | 488 |
486 switch (target->kind()) { | 489 switch (target->kind()) { |
487 case Code::LOAD_IC: | 490 case Code::LOAD_IC: |
488 case Code::KEYED_LOAD_IC: | 491 case Code::KEYED_LOAD_IC: |
489 return; | 492 return; |
490 case Code::STORE_IC: | 493 case Code::STORE_IC: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 | 536 |
534 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { | 537 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { |
535 if (IsCleared(nexus)) return; | 538 if (IsCleared(nexus)) return; |
536 State state = nexus->StateFromFeedback(); | 539 State state = nexus->StateFromFeedback(); |
537 nexus->ConfigurePremonomorphic(); | 540 nexus->ConfigurePremonomorphic(); |
538 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); | 541 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); |
539 } | 542 } |
540 | 543 |
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 ConstantPoolArray* 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 |
551 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, | 554 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, |
552 Address constant_pool) { | 555 ConstantPoolArray* constant_pool) { |
553 if (IsCleared(target)) return; | 556 if (IsCleared(target)) return; |
554 Handle<Code> code = pre_monomorphic_stub( | 557 Handle<Code> code = pre_monomorphic_stub( |
555 isolate, StoreICState::GetLanguageMode(target->extra_ic_state())); | 558 isolate, StoreICState::GetLanguageMode(target->extra_ic_state())); |
556 SetTargetAtAddress(address, *code, constant_pool); | 559 SetTargetAtAddress(address, *code, constant_pool); |
557 } | 560 } |
558 | 561 |
559 | 562 |
560 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, | 563 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, |
561 Address constant_pool) { | 564 ConstantPoolArray* constant_pool) { |
562 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); | 565 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); |
563 CompareICStub stub(target->stub_key(), isolate); | 566 CompareICStub stub(target->stub_key(), isolate); |
564 // Only clear CompareICs that can retain objects. | 567 // Only clear CompareICs that can retain objects. |
565 if (stub.state() != CompareICState::KNOWN_OBJECT) return; | 568 if (stub.state() != CompareICState::KNOWN_OBJECT) return; |
566 SetTargetAtAddress(address, | 569 SetTargetAtAddress(address, |
567 GetRawUninitialized(isolate, stub.op(), stub.strong()), | 570 GetRawUninitialized(isolate, stub.op(), stub.strong()), |
568 constant_pool); | 571 constant_pool); |
569 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); | 572 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); |
570 } | 573 } |
571 | 574 |
(...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2595 // Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc. | 2598 // Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc. |
2596 RUNTIME_FUNCTION(CompareIC_Miss) { | 2599 RUNTIME_FUNCTION(CompareIC_Miss) { |
2597 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2600 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2598 HandleScope scope(isolate); | 2601 HandleScope scope(isolate); |
2599 DCHECK(args.length() == 3); | 2602 DCHECK(args.length() == 3); |
2600 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2603 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2601 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2604 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2602 } | 2605 } |
2603 | 2606 |
2604 | 2607 |
2605 void CompareNilIC::Clear(Address address, Code* target, Address constant_pool) { | 2608 void CompareNilIC::Clear(Address address, Code* target, |
| 2609 ConstantPoolArray* constant_pool) { |
2606 if (IsCleared(target)) return; | 2610 if (IsCleared(target)) return; |
2607 ExtraICState state = target->extra_ic_state(); | 2611 ExtraICState state = target->extra_ic_state(); |
2608 | 2612 |
2609 CompareNilICStub stub(target->GetIsolate(), state, | 2613 CompareNilICStub stub(target->GetIsolate(), state, |
2610 HydrogenCodeStub::UNINITIALIZED); | 2614 HydrogenCodeStub::UNINITIALIZED); |
2611 stub.ClearState(); | 2615 stub.ClearState(); |
2612 | 2616 |
2613 Code* code = NULL; | 2617 Code* code = NULL; |
2614 CHECK(stub.FindCodeInCache(&code)); | 2618 CHECK(stub.FindCodeInCache(&code)); |
2615 | 2619 |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2897 static const Address IC_utilities[] = { | 2901 static const Address IC_utilities[] = { |
2898 #define ADDR(name) FUNCTION_ADDR(name), | 2902 #define ADDR(name) FUNCTION_ADDR(name), |
2899 IC_UTIL_LIST(ADDR) NULL | 2903 IC_UTIL_LIST(ADDR) NULL |
2900 #undef ADDR | 2904 #undef ADDR |
2901 }; | 2905 }; |
2902 | 2906 |
2903 | 2907 |
2904 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 2908 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
2905 } // namespace internal | 2909 } // namespace internal |
2906 } // namespace v8 | 2910 } // namespace v8 |
OLD | NEW |