| 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 |