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 #ifndef V8_IC_INL_H_ | 5 #ifndef V8_IC_INL_H_ |
6 #define V8_IC_INL_H_ | 6 #define V8_IC_INL_H_ |
7 | 7 |
8 #include "src/ic.h" | 8 #include "src/ic/ic.h" |
9 | 9 |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
11 #include "src/debug.h" | 11 #include "src/debug.h" |
12 #include "src/macro-assembler.h" | 12 #include "src/macro-assembler.h" |
13 #include "src/prototype.h" | 13 #include "src/prototype.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 | 18 |
19 Address IC::address() const { | 19 Address IC::address() const { |
20 // Get the address of the call. | 20 // Get the address of the call. |
21 Address result = Assembler::target_address_from_return_address(pc()); | 21 Address result = Assembler::target_address_from_return_address(pc()); |
22 | 22 |
23 Debug* debug = isolate()->debug(); | 23 Debug* debug = isolate()->debug(); |
24 // First check if any break points are active if not just return the address | 24 // First check if any break points are active if not just return the address |
25 // of the call. | 25 // of the call. |
26 if (!debug->has_break_points()) return result; | 26 if (!debug->has_break_points()) return result; |
27 | 27 |
28 // At least one break point is active perform additional test to ensure that | 28 // At least one break point is active perform additional test to ensure that |
29 // break point locations are updated correctly. | 29 // break point locations are updated correctly. |
30 if (debug->IsDebugBreak(Assembler::target_address_at(result, | 30 if (debug->IsDebugBreak( |
31 raw_constant_pool()))) { | 31 Assembler::target_address_at(result, raw_constant_pool()))) { |
32 // If the call site is a call to debug break then return the address in | 32 // If the call site is a call to debug break then return the address in |
33 // the original code instead of the address in the running code. This will | 33 // the original code instead of the address in the running code. This will |
34 // cause the original code to be updated and keeps the breakpoint active in | 34 // cause the original code to be updated and keeps the breakpoint active in |
35 // the running code. | 35 // the running code. |
36 Code* code = GetCode(); | 36 Code* code = GetCode(); |
37 Code* original_code = GetOriginalCode(); | 37 Code* original_code = GetOriginalCode(); |
38 intptr_t delta = | 38 intptr_t delta = |
39 original_code->instruction_start() - code->instruction_start(); | 39 original_code->instruction_start() - code->instruction_start(); |
40 // Return the address in the original code. This is the place where | 40 // Return the address in the original code. This is the place where |
41 // the call which has been overwritten by the DebugBreakXXX resides | 41 // the call which has been overwritten by the DebugBreakXXX resides |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 // Get the target address of the IC. | 86 // Get the target address of the IC. |
87 Address target = Assembler::target_address_at(address, constant_pool); | 87 Address target = Assembler::target_address_at(address, constant_pool); |
88 // Convert target address to the code object. Code::GetCodeFromTargetAddress | 88 // Convert target address to the code object. Code::GetCodeFromTargetAddress |
89 // is safe for use during GC where the map might be marked. | 89 // is safe for use during GC where the map might be marked. |
90 Code* result = Code::GetCodeFromTargetAddress(target); | 90 Code* result = Code::GetCodeFromTargetAddress(target); |
91 DCHECK(result->is_inline_cache_stub()); | 91 DCHECK(result->is_inline_cache_stub()); |
92 return result; | 92 return result; |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 void IC::SetTargetAtAddress(Address address, | 96 void IC::SetTargetAtAddress(Address address, Code* target, |
97 Code* target, | |
98 ConstantPoolArray* constant_pool) { | 97 ConstantPoolArray* constant_pool) { |
99 DCHECK(target->is_inline_cache_stub() || target->is_compare_ic_stub()); | 98 DCHECK(target->is_inline_cache_stub() || target->is_compare_ic_stub()); |
100 Heap* heap = target->GetHeap(); | 99 Heap* heap = target->GetHeap(); |
101 Code* old_target = GetTargetAtAddress(address, constant_pool); | 100 Code* old_target = GetTargetAtAddress(address, constant_pool); |
102 #ifdef DEBUG | 101 #ifdef DEBUG |
103 // STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark | 102 // STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark |
104 // ICs as strict mode. The strict-ness of the IC must be preserved. | 103 // ICs as strict mode. The strict-ness of the IC must be preserved. |
105 if (old_target->kind() == Code::STORE_IC || | 104 if (old_target->kind() == Code::STORE_IC || |
106 old_target->kind() == Code::KEYED_STORE_IC) { | 105 old_target->kind() == Code::KEYED_STORE_IC) { |
107 DCHECK(StoreIC::GetStrictMode(old_target->extra_ic_state()) == | 106 DCHECK(StoreIC::GetStrictMode(old_target->extra_ic_state()) == |
108 StoreIC::GetStrictMode(target->extra_ic_state())); | 107 StoreIC::GetStrictMode(target->extra_ic_state())); |
109 } | 108 } |
110 #endif | 109 #endif |
111 Assembler::set_target_address_at( | 110 Assembler::set_target_address_at(address, constant_pool, |
112 address, constant_pool, target->instruction_start()); | 111 target->instruction_start()); |
113 if (heap->gc_state() == Heap::MARK_COMPACT) { | 112 if (heap->gc_state() == Heap::MARK_COMPACT) { |
114 heap->mark_compact_collector()->RecordCodeTargetPatch(address, target); | 113 heap->mark_compact_collector()->RecordCodeTargetPatch(address, target); |
115 } else { | 114 } else { |
116 heap->incremental_marking()->RecordCodeTargetPatch(address, target); | 115 heap->incremental_marking()->RecordCodeTargetPatch(address, target); |
117 } | 116 } |
118 PostPatching(address, target, old_target); | 117 PostPatching(address, target, old_target); |
119 } | 118 } |
120 | 119 |
121 | 120 |
| 121 void IC::set_target(Code* code) { |
| 122 #ifdef VERIFY_HEAP |
| 123 code->VerifyEmbeddedObjectsDependency(); |
| 124 #endif |
| 125 SetTargetAtAddress(address(), code, constant_pool()); |
| 126 target_set_ = true; |
| 127 } |
| 128 |
| 129 |
| 130 void LoadIC::set_target(Code* code) { |
| 131 // The contextual mode must be preserved across IC patching. |
| 132 DCHECK(GetContextualMode(code->extra_ic_state()) == |
| 133 GetContextualMode(target()->extra_ic_state())); |
| 134 |
| 135 IC::set_target(code); |
| 136 } |
| 137 |
| 138 |
| 139 void StoreIC::set_target(Code* code) { |
| 140 // Strict mode must be preserved across IC patching. |
| 141 DCHECK(GetStrictMode(code->extra_ic_state()) == |
| 142 GetStrictMode(target()->extra_ic_state())); |
| 143 IC::set_target(code); |
| 144 } |
| 145 |
| 146 |
| 147 void KeyedStoreIC::set_target(Code* code) { |
| 148 // Strict mode must be preserved across IC patching. |
| 149 DCHECK(GetStrictMode(code->extra_ic_state()) == strict_mode()); |
| 150 IC::set_target(code); |
| 151 } |
| 152 |
| 153 |
| 154 Code* IC::raw_target() const { |
| 155 return GetTargetAtAddress(address(), constant_pool()); |
| 156 } |
| 157 |
| 158 void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); } |
| 159 |
| 160 |
122 template <class TypeClass> | 161 template <class TypeClass> |
123 JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) { | 162 JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) { |
124 if (type->Is(TypeClass::Boolean())) { | 163 if (type->Is(TypeClass::Boolean())) { |
125 return native_context->boolean_function(); | 164 return native_context->boolean_function(); |
126 } else if (type->Is(TypeClass::Number())) { | 165 } else if (type->Is(TypeClass::Number())) { |
127 return native_context->number_function(); | 166 return native_context->number_function(); |
128 } else if (type->Is(TypeClass::String())) { | 167 } else if (type->Is(TypeClass::String())) { |
129 return native_context->string_function(); | 168 return native_context->string_function(); |
130 } else if (type->Is(TypeClass::Symbol())) { | 169 } else if (type->Is(TypeClass::Symbol())) { |
131 return native_context->symbol_function(); | 170 return native_context->symbol_function(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 if (feedback == *TypeFeedbackInfo::MegamorphicSentinel(isolate())) { | 216 if (feedback == *TypeFeedbackInfo::MegamorphicSentinel(isolate())) { |
178 state = GENERIC; | 217 state = GENERIC; |
179 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | 218 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { |
180 state = MONOMORPHIC; | 219 state = MONOMORPHIC; |
181 } else { | 220 } else { |
182 CHECK(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); | 221 CHECK(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); |
183 } | 222 } |
184 | 223 |
185 return state; | 224 return state; |
186 } | 225 } |
187 } } // namespace v8::internal | 226 } |
| 227 } // namespace v8::internal |
188 | 228 |
189 #endif // V8_IC_INL_H_ | 229 #endif // V8_IC_INL_H_ |
OLD | NEW |