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