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_H_ | 5 #ifndef V8_IC_H_ |
6 #define V8_IC_H_ | 6 #define V8_IC_H_ |
7 | 7 |
8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 | 10 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 85 return target()->is_load_stub() || target()->is_keyed_load_stub(); |
86 } | 86 } |
87 | 87 |
88 bool IsStoreStub() const { | 88 bool IsStoreStub() const { |
89 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 89 return target()->is_store_stub() || target()->is_keyed_store_stub(); |
90 } | 90 } |
91 | 91 |
92 bool IsCallStub() const { return target()->is_call_stub(); } | 92 bool IsCallStub() const { return target()->is_call_stub(); } |
93 #endif | 93 #endif |
94 | 94 |
95 template <class TypeClass> | 95 static inline JSFunction* GetRootConstructor(Map* receiver_map, |
96 static JSFunction* GetRootConstructor(TypeClass* type, | 96 Context* native_context); |
97 Context* native_context); | 97 static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map, |
98 static inline Handle<Map> GetHandlerCacheHolder(HeapType* type, | |
99 bool receiver_is_holder, | 98 bool receiver_is_holder, |
100 Isolate* isolate, | 99 Isolate* isolate, |
101 CacheHolderFlag* flag); | 100 CacheHolderFlag* flag); |
102 static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate, | 101 static inline Handle<Map> GetICCacheHolder(Handle<Map> receiver_map, |
| 102 Isolate* isolate, |
103 CacheHolderFlag* flag); | 103 CacheHolderFlag* flag); |
104 | 104 |
105 static bool IsCleared(Code* code) { | 105 static bool IsCleared(Code* code) { |
106 InlineCacheState state = code->ic_state(); | 106 InlineCacheState state = code->ic_state(); |
107 return state == UNINITIALIZED || state == PREMONOMORPHIC; | 107 return state == UNINITIALIZED || state == PREMONOMORPHIC; |
108 } | 108 } |
109 | 109 |
110 static bool IsCleared(FeedbackNexus* nexus) { | 110 static bool IsCleared(FeedbackNexus* nexus) { |
111 InlineCacheState state = nexus->StateFromFeedback(); | 111 InlineCacheState state = nexus->StateFromFeedback(); |
112 return state == UNINITIALIZED || state == PREMONOMORPHIC; | 112 return state == UNINITIALIZED || state == PREMONOMORPHIC; |
113 } | 113 } |
114 | 114 |
115 // Utility functions to convert maps to types and back. There are two special | |
116 // cases: | |
117 // - The heap_number_map is used as a marker which includes heap numbers as | |
118 // well as smis. | |
119 // - The oddball map is only used for booleans. | |
120 static Handle<Map> TypeToMap(HeapType* type, Isolate* isolate); | |
121 template <class T> | |
122 static typename T::TypeHandle MapToType(Handle<Map> map, | |
123 typename T::Region* region); | |
124 | |
125 static Handle<HeapType> CurrentTypeOf(Handle<Object> object, | |
126 Isolate* isolate); | |
127 | |
128 static bool ICUseVector(Code::Kind kind) { | 115 static bool ICUseVector(Code::Kind kind) { |
129 return (FLAG_vector_ics && | 116 return (FLAG_vector_ics && |
130 (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) || | 117 (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) || |
131 kind == Code::CALL_IC; | 118 kind == Code::CALL_IC; |
132 } | 119 } |
133 | 120 |
134 protected: | 121 protected: |
135 // Get the call-site target; used for determining the state. | 122 // Get the call-site target; used for determining the state. |
136 Handle<Code> target() const { return target_; } | 123 Handle<Code> target() const { return target_; } |
137 | 124 |
(...skipping 18 matching lines...) Expand all Loading... |
156 bool UseVector() const { | 143 bool UseVector() const { |
157 bool use = ICUseVector(kind()); | 144 bool use = ICUseVector(kind()); |
158 // If we are supposed to use the nexus, verify the nexus is non-null. | 145 // If we are supposed to use the nexus, verify the nexus is non-null. |
159 DCHECK(!use || nexus_ != NULL); | 146 DCHECK(!use || nexus_ != NULL); |
160 return use; | 147 return use; |
161 } | 148 } |
162 | 149 |
163 // Configure for most states. | 150 // Configure for most states. |
164 void ConfigureVectorState(IC::State new_state); | 151 void ConfigureVectorState(IC::State new_state); |
165 // Configure the vector for MONOMORPHIC. | 152 // Configure the vector for MONOMORPHIC. |
166 void ConfigureVectorState(Handle<Name> name, Handle<HeapType> type, | 153 void ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
167 Handle<Code> handler); | 154 Handle<Code> handler); |
168 // Configure the vector for POLYMORPHIC. | 155 // Configure the vector for POLYMORPHIC. |
169 void ConfigureVectorState(Handle<Name> name, TypeHandleList* types, | 156 void ConfigureVectorState(Handle<Name> name, MapHandleList* maps, |
170 CodeHandleList* handlers); | 157 CodeHandleList* handlers); |
171 | 158 |
172 char TransitionMarkFromState(IC::State state); | 159 char TransitionMarkFromState(IC::State state); |
173 void TraceIC(const char* type, Handle<Object> name); | 160 void TraceIC(const char* type, Handle<Object> name); |
174 void TraceIC(const char* type, Handle<Object> name, State old_state, | 161 void TraceIC(const char* type, Handle<Object> name, State old_state, |
175 State new_state); | 162 State new_state); |
176 | 163 |
177 MaybeHandle<Object> TypeError(const char* type, Handle<Object> object, | 164 MaybeHandle<Object> TypeError(const char* type, Handle<Object> object, |
178 Handle<Object> key); | 165 Handle<Object> key); |
179 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name); | 166 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name); |
(...skipping 17 matching lines...) Expand all Loading... |
197 Handle<Object> value = Handle<Code>::null()); | 184 Handle<Object> value = Handle<Code>::null()); |
198 virtual Handle<Code> CompileHandler(LookupIterator* lookup, | 185 virtual Handle<Code> CompileHandler(LookupIterator* lookup, |
199 Handle<Object> value, | 186 Handle<Object> value, |
200 CacheHolderFlag cache_holder) { | 187 CacheHolderFlag cache_holder) { |
201 UNREACHABLE(); | 188 UNREACHABLE(); |
202 return Handle<Code>::null(); | 189 return Handle<Code>::null(); |
203 } | 190 } |
204 | 191 |
205 void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name); | 192 void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name); |
206 bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code); | 193 bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code); |
207 void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); | 194 void UpdateMegamorphicCache(Map* map, Name* name, Code* code); |
208 | 195 |
209 void CopyICToMegamorphicCache(Handle<Name> name); | 196 void CopyICToMegamorphicCache(Handle<Name> name); |
210 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); | 197 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); |
211 void PatchCache(Handle<Name> name, Handle<Code> code); | 198 void PatchCache(Handle<Name> name, Handle<Code> code); |
212 Code::Kind kind() const { return kind_; } | 199 Code::Kind kind() const { return kind_; } |
213 Code::Kind handler_kind() const { | 200 Code::Kind handler_kind() const { |
214 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; | 201 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; |
215 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || | 202 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || |
216 kind_ == Code::KEYED_STORE_IC); | 203 kind_ == Code::KEYED_STORE_IC); |
217 return kind_; | 204 return kind_; |
218 } | 205 } |
219 virtual Handle<Code> megamorphic_stub() { | 206 virtual Handle<Code> megamorphic_stub() { |
220 UNREACHABLE(); | 207 UNREACHABLE(); |
221 return Handle<Code>::null(); | 208 return Handle<Code>::null(); |
222 } | 209 } |
223 | 210 |
224 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, | 211 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
225 Handle<String> name); | 212 Handle<String> name); |
226 | 213 |
227 ExtraICState extra_ic_state() const { return extra_ic_state_; } | 214 ExtraICState extra_ic_state() const { return extra_ic_state_; } |
228 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; } | 215 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; } |
229 | 216 |
230 Handle<HeapType> receiver_type() { return receiver_type_; } | 217 Handle<Map> receiver_map() { return receiver_map_; } |
231 void update_receiver_type(Handle<Object> receiver) { | 218 void update_receiver_map(Handle<Object> receiver) { |
232 receiver_type_ = CurrentTypeOf(receiver, isolate_); | 219 if (receiver->IsSmi()) { |
| 220 receiver_map_ = isolate_->factory()->heap_number_map(); |
| 221 } else { |
| 222 receiver_map_ = handle(HeapObject::cast(*receiver)->map()); |
| 223 } |
233 } | 224 } |
234 | 225 |
235 void TargetMaps(MapHandleList* list) { | 226 void TargetMaps(MapHandleList* list) { |
236 FindTargetMaps(); | 227 FindTargetMaps(); |
237 for (int i = 0; i < target_maps_.length(); i++) { | 228 for (int i = 0; i < target_maps_.length(); i++) { |
238 list->Add(target_maps_.at(i)); | 229 list->Add(target_maps_.at(i)); |
239 } | 230 } |
240 } | 231 } |
241 | 232 |
242 void TargetTypes(TypeHandleList* list) { | |
243 FindTargetMaps(); | |
244 for (int i = 0; i < target_maps_.length(); i++) { | |
245 list->Add(MapToType<HeapType>(target_maps_.at(i), isolate_)); | |
246 } | |
247 } | |
248 | |
249 Map* FirstTargetMap() { | 233 Map* FirstTargetMap() { |
250 FindTargetMaps(); | 234 FindTargetMaps(); |
251 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; | 235 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; |
252 } | 236 } |
253 | 237 |
254 inline void UpdateTarget(); | 238 inline void UpdateTarget(); |
255 | 239 |
256 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } | 240 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } |
257 FeedbackVectorICSlot slot() const { return nexus()->slot(); } | 241 FeedbackVectorICSlot slot() const { return nexus()->slot(); } |
258 State saved_state() const { | 242 State saved_state() const { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 // be for the breakpointed copy of the original code). | 286 // be for the breakpointed copy of the original code). |
303 Handle<ConstantPoolArray> raw_constant_pool_; | 287 Handle<ConstantPoolArray> raw_constant_pool_; |
304 | 288 |
305 // The original code target that missed. | 289 // The original code target that missed. |
306 Handle<Code> target_; | 290 Handle<Code> target_; |
307 bool target_set_; | 291 bool target_set_; |
308 bool vector_set_; | 292 bool vector_set_; |
309 State old_state_; // For saving if we marked as prototype failure. | 293 State old_state_; // For saving if we marked as prototype failure. |
310 State state_; | 294 State state_; |
311 Code::Kind kind_; | 295 Code::Kind kind_; |
312 Handle<HeapType> receiver_type_; | 296 Handle<Map> receiver_map_; |
313 MaybeHandle<Code> maybe_handler_; | 297 MaybeHandle<Code> maybe_handler_; |
314 | 298 |
315 ExtraICState extra_ic_state_; | 299 ExtraICState extra_ic_state_; |
316 MapHandleList target_maps_; | 300 MapHandleList target_maps_; |
317 bool target_maps_set_; | 301 bool target_maps_set_; |
318 | 302 |
319 FeedbackNexus* nexus_; | 303 FeedbackNexus* nexus_; |
320 | 304 |
321 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); | 305 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
322 }; | 306 }; |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 | 756 |
773 // Support functions for interceptor handlers. | 757 // Support functions for interceptor handlers. |
774 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); | 758 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); |
775 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); | 759 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); |
776 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); | 760 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); |
777 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); | 761 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); |
778 } | 762 } |
779 } // namespace v8::internal | 763 } // namespace v8::internal |
780 | 764 |
781 #endif // V8_IC_H_ | 765 #endif // V8_IC_H_ |
OLD | NEW |