| 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 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 DCHECK(RecomputeHandlerForName(name)); | 40 DCHECK(RecomputeHandlerForName(name)); |
| 41 old_state_ = state_; | 41 old_state_ = state_; |
| 42 state_ = RECOMPUTE_HANDLER; | 42 state_ = RECOMPUTE_HANDLER; |
| 43 } | 43 } |
| 44 | 44 |
| 45 // Clear the inline cache to initial state. | 45 // Clear the inline cache to initial state. |
| 46 static void Clear(Isolate* isolate, Address address, Address constant_pool); | 46 static void Clear(Isolate* isolate, Address address, Address constant_pool); |
| 47 | 47 |
| 48 #ifdef DEBUG | 48 #ifdef DEBUG |
| 49 bool IsLoadStub() const { | 49 bool IsLoadStub() const { |
| 50 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 50 return kind_ == Code::LOAD_IC || kind_ == Code::KEYED_LOAD_IC; |
| 51 } | 51 } |
| 52 | |
| 53 bool IsStoreStub() const { | 52 bool IsStoreStub() const { |
| 54 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 53 return kind_ == Code::STORE_IC || kind_ == Code::KEYED_STORE_IC; |
| 55 } | 54 } |
| 56 | 55 bool IsCallStub() const { return kind_ == Code::CALL_IC; } |
| 57 bool IsCallStub() const { return target()->is_call_stub(); } | |
| 58 #endif | 56 #endif |
| 59 | 57 |
| 60 static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map, | 58 static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map, |
| 61 bool receiver_is_holder, | 59 bool receiver_is_holder, |
| 62 Isolate* isolate, | 60 Isolate* isolate, |
| 63 CacheHolderFlag* flag); | 61 CacheHolderFlag* flag); |
| 64 static inline Handle<Map> GetICCacheHolder(Handle<Map> receiver_map, | 62 static inline Handle<Map> GetICCacheHolder(Handle<Map> receiver_map, |
| 65 Isolate* isolate, | 63 Isolate* isolate, |
| 66 CacheHolderFlag* flag); | 64 CacheHolderFlag* flag); |
| 67 | 65 |
| 68 static bool IsCleared(Code* code) { | 66 static bool IsCleared(Code* code) { |
| 69 InlineCacheState state = code->ic_state(); | 67 InlineCacheState state = code->ic_state(); |
| 70 return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC; | 68 return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC; |
| 71 } | 69 } |
| 72 | 70 |
| 73 static bool IsCleared(FeedbackNexus* nexus) { | 71 static bool IsCleared(FeedbackNexus* nexus) { |
| 74 InlineCacheState state = nexus->StateFromFeedback(); | 72 InlineCacheState state = nexus->StateFromFeedback(); |
| 75 return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC; | 73 return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC; |
| 76 } | 74 } |
| 77 | 75 |
| 78 static bool ICUseVector(Code::Kind kind) { | 76 static bool ICUseVector(Code::Kind kind) { |
| 79 return kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || | 77 return kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || |
| 80 kind == Code::CALL_IC || kind == Code::STORE_IC || | 78 kind == Code::CALL_IC || kind == Code::STORE_IC || |
| 81 kind == Code::KEYED_STORE_IC; | 79 kind == Code::KEYED_STORE_IC; |
| 82 } | 80 } |
| 83 | 81 |
| 84 protected: | 82 protected: |
| 85 // Get the call-site target; used for determining the state. | |
| 86 Handle<Code> target() const { return target_; } | |
| 87 | |
| 88 Address fp() const { return fp_; } | 83 Address fp() const { return fp_; } |
| 89 Address pc() const { return *pc_address_; } | 84 Address pc() const { return *pc_address_; } |
| 90 Isolate* isolate() const { return isolate_; } | 85 Isolate* isolate() const { return isolate_; } |
| 91 | 86 |
| 92 // Get the shared function info of the caller. | 87 // Get the shared function info of the caller. |
| 93 SharedFunctionInfo* GetSharedFunctionInfo() const; | 88 SharedFunctionInfo* GetSharedFunctionInfo() const; |
| 94 // Get the code object of the caller. | 89 // Get the code object of the caller. |
| 95 Code* GetCode() const; | 90 Code* GetCode() const; |
| 96 | 91 |
| 97 bool AddressIsOptimizedCode() const; | 92 bool AddressIsOptimizedCode() const; |
| 98 inline bool AddressIsDeoptimizedCode() const; | 93 inline bool AddressIsDeoptimizedCode() const; |
| 99 inline static bool AddressIsDeoptimizedCode(Isolate* isolate, | 94 inline static bool AddressIsDeoptimizedCode(Isolate* isolate, |
| 100 Address address); | 95 Address address); |
| 101 | 96 |
| 102 // Set the call-site target. | 97 // Set the call-site target. |
| 103 inline void set_target(Code* code); | 98 inline void set_target(Code* code); |
| 104 bool is_target_set() { return target_set_; } | |
| 105 bool is_vector_set() { return vector_set_; } | 99 bool is_vector_set() { return vector_set_; } |
| 106 | 100 |
| 107 bool UseVector() const { | 101 bool UseVector() const { |
| 108 bool use = ICUseVector(kind()); | 102 bool use = ICUseVector(kind()); |
| 109 // If we are supposed to use the nexus, verify the nexus is non-null. | 103 // If we are supposed to use the nexus, verify the nexus is non-null. |
| 110 DCHECK(!use || nexus_ != NULL); | 104 DCHECK(!use || nexus_ != nullptr); |
| 111 return use; | 105 return use; |
| 112 } | 106 } |
| 113 | 107 |
| 114 // Configure for most states. | 108 // Configure for most states. |
| 115 void ConfigureVectorState(IC::State new_state); | 109 void ConfigureVectorState(IC::State new_state); |
| 116 // Configure the vector for MONOMORPHIC. | 110 // Configure the vector for MONOMORPHIC. |
| 117 void ConfigureVectorState(Handle<Name> name, Handle<Map> map, | 111 void ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
| 118 Handle<Code> handler); | 112 Handle<Code> handler); |
| 119 // Configure the vector for POLYMORPHIC. | 113 // Configure the vector for POLYMORPHIC. |
| 120 void ConfigureVectorState(Handle<Name> name, MapHandleList* maps, | 114 void ConfigureVectorState(Handle<Name> name, MapHandleList* maps, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 132 | 126 |
| 133 MaybeHandle<Object> TypeError(MessageTemplate::Template, | 127 MaybeHandle<Object> TypeError(MessageTemplate::Template, |
| 134 Handle<Object> object, Handle<Object> key); | 128 Handle<Object> object, Handle<Object> key); |
| 135 MaybeHandle<Object> ReferenceError(Handle<Name> name); | 129 MaybeHandle<Object> ReferenceError(Handle<Name> name); |
| 136 | 130 |
| 137 // Access the target code for the given IC address. | 131 // Access the target code for the given IC address. |
| 138 static inline Code* GetTargetAtAddress(Address address, | 132 static inline Code* GetTargetAtAddress(Address address, |
| 139 Address constant_pool); | 133 Address constant_pool); |
| 140 static inline void SetTargetAtAddress(Address address, Code* target, | 134 static inline void SetTargetAtAddress(Address address, Code* target, |
| 141 Address constant_pool); | 135 Address constant_pool); |
| 142 static void OnTypeFeedbackChanged(Isolate* isolate, Address address, | |
| 143 State old_state, State new_state, | |
| 144 bool target_remains_ic_stub); | |
| 145 // As a vector-based IC, type feedback must be updated differently. | 136 // As a vector-based IC, type feedback must be updated differently. |
| 146 static void OnTypeFeedbackChanged(Isolate* isolate, Code* host); | 137 static void OnTypeFeedbackChanged(Isolate* isolate, Code* host); |
| 147 static void PostPatching(Address address, Code* target, Code* old_target); | 138 static void PostPatching(Address address, Code* target, Code* old_target); |
| 148 | 139 |
| 149 // Compute the handler either by compiling or by retrieving a cached version. | 140 // Compute the handler either by compiling or by retrieving a cached version. |
| 150 Handle<Code> ComputeHandler(LookupIterator* lookup, | 141 Handle<Code> ComputeHandler(LookupIterator* lookup, |
| 151 Handle<Object> value = Handle<Code>::null()); | 142 Handle<Object> value = Handle<Code>::null()); |
| 152 virtual Handle<Code> CompileHandler(LookupIterator* lookup, | 143 virtual Handle<Code> CompileHandler(LookupIterator* lookup, |
| 153 Handle<Object> value, | 144 Handle<Object> value, |
| 154 CacheHolderFlag cache_holder) { | 145 CacheHolderFlag cache_holder) { |
| 155 UNREACHABLE(); | 146 UNREACHABLE(); |
| 156 return Handle<Code>::null(); | 147 return Handle<Code>::null(); |
| 157 } | 148 } |
| 158 | 149 |
| 159 void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name); | 150 void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name); |
| 160 bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code); | 151 bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code); |
| 161 void UpdateMegamorphicCache(Map* map, Name* name, Code* code); | 152 void UpdateMegamorphicCache(Map* map, Name* name, Code* code); |
| 162 | 153 |
| 163 void CopyICToMegamorphicCache(Handle<Name> name); | 154 void CopyICToMegamorphicCache(Handle<Name> name); |
| 164 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); | 155 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); |
| 165 void PatchCache(Handle<Name> name, Handle<Code> code); | 156 void PatchCache(Handle<Name> name, Handle<Code> code); |
| 166 Code::Kind kind() const { return kind_; } | 157 Code::Kind kind() const { return kind_; } |
| 158 bool is_keyed() const { |
| 159 return kind_ == Code::KEYED_LOAD_IC || kind_ == Code::KEYED_STORE_IC; |
| 160 } |
| 167 Code::Kind handler_kind() const { | 161 Code::Kind handler_kind() const { |
| 168 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; | 162 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; |
| 169 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || | 163 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || |
| 170 kind_ == Code::KEYED_STORE_IC); | 164 kind_ == Code::KEYED_STORE_IC); |
| 171 return kind_; | 165 return kind_; |
| 172 } | 166 } |
| 173 virtual Handle<Code> megamorphic_stub() { | |
| 174 UNREACHABLE(); | |
| 175 return Handle<Code>::null(); | |
| 176 } | |
| 177 | |
| 178 bool ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name); | 167 bool ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name); |
| 179 | 168 |
| 180 ExtraICState extra_ic_state() const { return extra_ic_state_; } | 169 ExtraICState extra_ic_state() const { return extra_ic_state_; } |
| 181 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; } | |
| 182 | 170 |
| 183 Handle<Map> receiver_map() { return receiver_map_; } | 171 Handle<Map> receiver_map() { return receiver_map_; } |
| 184 void update_receiver_map(Handle<Object> receiver) { | 172 void update_receiver_map(Handle<Object> receiver) { |
| 185 if (receiver->IsSmi()) { | 173 if (receiver->IsSmi()) { |
| 186 receiver_map_ = isolate_->factory()->heap_number_map(); | 174 receiver_map_ = isolate_->factory()->heap_number_map(); |
| 187 } else { | 175 } else { |
| 188 receiver_map_ = handle(HeapObject::cast(*receiver)->map()); | 176 receiver_map_ = handle(HeapObject::cast(*receiver)->map()); |
| 189 } | 177 } |
| 190 } | 178 } |
| 191 | 179 |
| 192 void TargetMaps(MapHandleList* list) { | 180 void TargetMaps(MapHandleList* list) { |
| 193 FindTargetMaps(); | 181 FindTargetMaps(); |
| 194 for (int i = 0; i < target_maps_.length(); i++) { | 182 for (int i = 0; i < target_maps_.length(); i++) { |
| 195 list->Add(target_maps_.at(i)); | 183 list->Add(target_maps_.at(i)); |
| 196 } | 184 } |
| 197 } | 185 } |
| 198 | 186 |
| 199 Map* FirstTargetMap() { | 187 Map* FirstTargetMap() { |
| 200 FindTargetMaps(); | 188 FindTargetMaps(); |
| 201 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; | 189 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; |
| 202 } | 190 } |
| 203 | 191 |
| 204 inline void UpdateTarget(); | |
| 205 | |
| 206 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } | 192 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } |
| 207 FeedbackVectorSlot slot() const { return nexus()->slot(); } | 193 FeedbackVectorSlot slot() const { return nexus()->slot(); } |
| 208 State saved_state() const { | 194 State saved_state() const { |
| 209 return state() == RECOMPUTE_HANDLER ? old_state_ : state(); | 195 return state() == RECOMPUTE_HANDLER ? old_state_ : state(); |
| 210 } | 196 } |
| 211 | 197 |
| 212 template <class NexusClass> | 198 template <class NexusClass> |
| 213 NexusClass* casted_nexus() { | 199 NexusClass* casted_nexus() { |
| 214 return static_cast<NexusClass*>(nexus_); | 200 return static_cast<NexusClass*>(nexus_); |
| 215 } | 201 } |
| 216 FeedbackNexus* nexus() const { return nexus_; } | 202 FeedbackNexus* nexus() const { return nexus_; } |
| 217 | 203 |
| 218 inline Code* get_host(); | 204 inline Code* get_host(); |
| 205 inline Code* target() const; |
| 219 | 206 |
| 220 private: | 207 private: |
| 221 inline Code* raw_target() const; | |
| 222 inline Address constant_pool() const; | 208 inline Address constant_pool() const; |
| 223 inline Address raw_constant_pool() const; | 209 inline Address raw_constant_pool() const; |
| 224 | 210 |
| 225 void FindTargetMaps() { | 211 void FindTargetMaps() { |
| 226 if (target_maps_set_) return; | 212 if (target_maps_set_) return; |
| 227 target_maps_set_ = true; | 213 target_maps_set_ = true; |
| 228 if (UseVector()) { | 214 DCHECK(UseVector()); |
| 229 nexus()->ExtractMaps(&target_maps_); | 215 nexus()->ExtractMaps(&target_maps_); |
| 230 } else { | |
| 231 if (state_ == MONOMORPHIC) { | |
| 232 Map* map = target_->FindFirstMap(); | |
| 233 if (map != NULL) target_maps_.Add(handle(map)); | |
| 234 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { | |
| 235 target_->FindAllMaps(&target_maps_); | |
| 236 } | |
| 237 } | |
| 238 } | 216 } |
| 239 | 217 |
| 240 // Frame pointer for the frame that uses (calls) the IC. | 218 // Frame pointer for the frame that uses (calls) the IC. |
| 241 Address fp_; | 219 Address fp_; |
| 242 | 220 |
| 243 // All access to the program counter and constant pool of an IC structure is | 221 // All access to the program counter and constant pool of an IC structure is |
| 244 // indirect to make the code GC safe. This feature is crucial since | 222 // indirect to make the code GC safe. This feature is crucial since |
| 245 // GetProperty and SetProperty are called and they in turn might | 223 // GetProperty and SetProperty are called and they in turn might |
| 246 // invoke the garbage collector. | 224 // invoke the garbage collector. |
| 247 Address* pc_address_; | 225 Address* pc_address_; |
| 248 | 226 |
| 249 // The constant pool of the code which originally called the IC (which might | 227 // The constant pool of the code which originally called the IC (which might |
| 250 // be for the breakpointed copy of the original code). | 228 // be for the breakpointed copy of the original code). |
| 251 Address* constant_pool_address_; | 229 Address* constant_pool_address_; |
| 252 | 230 |
| 253 Isolate* isolate_; | 231 Isolate* isolate_; |
| 254 | 232 |
| 255 // The original code target that missed. | |
| 256 Handle<Code> target_; | |
| 257 bool target_set_; | |
| 258 bool vector_set_; | 233 bool vector_set_; |
| 259 State old_state_; // For saving if we marked as prototype failure. | 234 State old_state_; // For saving if we marked as prototype failure. |
| 260 State state_; | 235 State state_; |
| 261 Code::Kind kind_; | 236 Code::Kind kind_; |
| 262 Handle<Map> receiver_map_; | 237 Handle<Map> receiver_map_; |
| 263 MaybeHandle<Code> maybe_handler_; | 238 MaybeHandle<Code> maybe_handler_; |
| 264 | 239 |
| 265 ExtraICState extra_ic_state_; | 240 ExtraICState extra_ic_state_; |
| 266 MapHandleList target_maps_; | 241 MapHandleList target_maps_; |
| 267 bool target_maps_set_; | 242 bool target_maps_set_; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 ExtraICState extra_state); | 298 ExtraICState extra_state); |
| 324 static Handle<Code> initialize_stub_in_optimized_code( | 299 static Handle<Code> initialize_stub_in_optimized_code( |
| 325 Isolate* isolate, ExtraICState extra_state, State initialization_state); | 300 Isolate* isolate, ExtraICState extra_state, State initialization_state); |
| 326 | 301 |
| 327 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 302 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
| 328 Handle<Name> name); | 303 Handle<Name> name); |
| 329 | 304 |
| 330 static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus); | 305 static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus); |
| 331 | 306 |
| 332 protected: | 307 protected: |
| 333 inline void set_target(Code* code); | |
| 334 | |
| 335 Handle<Code> slow_stub() const { | 308 Handle<Code> slow_stub() const { |
| 336 if (kind() == Code::LOAD_IC) { | 309 if (kind() == Code::LOAD_IC) { |
| 337 return isolate()->builtins()->LoadIC_Slow(); | 310 return isolate()->builtins()->LoadIC_Slow(); |
| 338 } else { | 311 } else { |
| 339 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); | 312 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); |
| 340 return isolate()->builtins()->KeyedLoadIC_Slow(); | 313 return isolate()->builtins()->KeyedLoadIC_Slow(); |
| 341 } | 314 } |
| 342 } | 315 } |
| 343 | 316 |
| 344 Handle<Code> megamorphic_stub() override; | |
| 345 | |
| 346 // Update the inline cache and the global stub cache based on the | 317 // Update the inline cache and the global stub cache based on the |
| 347 // lookup result. | 318 // lookup result. |
| 348 void UpdateCaches(LookupIterator* lookup); | 319 void UpdateCaches(LookupIterator* lookup); |
| 349 | 320 |
| 350 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused, | 321 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused, |
| 351 CacheHolderFlag cache_holder) override; | 322 CacheHolderFlag cache_holder) override; |
| 352 | 323 |
| 353 private: | 324 private: |
| 354 Handle<Code> SimpleFieldLoad(FieldIndex index); | 325 Handle<Code> SimpleFieldLoad(FieldIndex index); |
| 355 | 326 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 370 } | 341 } |
| 371 | 342 |
| 372 static IcCheckType GetKeyType(ExtraICState extra_state) { | 343 static IcCheckType GetKeyType(ExtraICState extra_state) { |
| 373 return IcCheckTypeField::decode(extra_state); | 344 return IcCheckTypeField::decode(extra_state); |
| 374 } | 345 } |
| 375 | 346 |
| 376 KeyedLoadIC(FrameDepth depth, Isolate* isolate, | 347 KeyedLoadIC(FrameDepth depth, Isolate* isolate, |
| 377 KeyedLoadICNexus* nexus = NULL) | 348 KeyedLoadICNexus* nexus = NULL) |
| 378 : LoadIC(depth, isolate, nexus) { | 349 : LoadIC(depth, isolate, nexus) { |
| 379 DCHECK(nexus != NULL); | 350 DCHECK(nexus != NULL); |
| 380 DCHECK(target()->is_keyed_load_stub()); | |
| 381 } | 351 } |
| 382 | 352 |
| 383 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 353 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
| 384 Handle<Object> key); | 354 Handle<Object> key); |
| 385 | 355 |
| 386 // Code generator routines. | 356 // Code generator routines. |
| 387 static void GenerateMiss(MacroAssembler* masm); | 357 static void GenerateMiss(MacroAssembler* masm); |
| 388 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 358 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
| 389 static void GenerateMegamorphic(MacroAssembler* masm); | 359 static void GenerateMegamorphic(MacroAssembler* masm); |
| 390 | 360 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 JSReceiver::StoreFromKeyed store_mode = | 417 JSReceiver::StoreFromKeyed store_mode = |
| 448 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); | 418 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); |
| 449 | 419 |
| 450 bool LookupForWrite(LookupIterator* it, Handle<Object> value, | 420 bool LookupForWrite(LookupIterator* it, Handle<Object> value, |
| 451 JSReceiver::StoreFromKeyed store_mode); | 421 JSReceiver::StoreFromKeyed store_mode); |
| 452 | 422 |
| 453 static void Clear(Isolate* isolate, Code* host, StoreICNexus* nexus); | 423 static void Clear(Isolate* isolate, Code* host, StoreICNexus* nexus); |
| 454 | 424 |
| 455 protected: | 425 protected: |
| 456 // Stub accessors. | 426 // Stub accessors. |
| 457 Handle<Code> megamorphic_stub() override; | |
| 458 Handle<Code> slow_stub() const; | 427 Handle<Code> slow_stub() const; |
| 459 | 428 |
| 460 // Update the inline cache and the global stub cache based on the | 429 // Update the inline cache and the global stub cache based on the |
| 461 // lookup result. | 430 // lookup result. |
| 462 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, | 431 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, |
| 463 JSReceiver::StoreFromKeyed store_mode); | 432 JSReceiver::StoreFromKeyed store_mode); |
| 464 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value, | 433 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value, |
| 465 CacheHolderFlag cache_holder) override; | 434 CacheHolderFlag cache_holder) override; |
| 466 | 435 |
| 467 private: | 436 private: |
| 468 inline void set_target(Code* code); | |
| 469 | |
| 470 friend class IC; | 437 friend class IC; |
| 471 }; | 438 }; |
| 472 | 439 |
| 473 | 440 |
| 474 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; | 441 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; |
| 475 | 442 |
| 476 | 443 |
| 477 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; | 444 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; |
| 478 | 445 |
| 479 | 446 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 494 ExtraICStateKeyedAccessStoreMode::encode(mode) | | 461 ExtraICStateKeyedAccessStoreMode::encode(mode) | |
| 495 IcCheckTypeField::encode(ELEMENT); | 462 IcCheckTypeField::encode(ELEMENT); |
| 496 } | 463 } |
| 497 | 464 |
| 498 KeyedAccessStoreMode GetKeyedAccessStoreMode() { | 465 KeyedAccessStoreMode GetKeyedAccessStoreMode() { |
| 499 return casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); | 466 return casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); |
| 500 } | 467 } |
| 501 | 468 |
| 502 KeyedStoreIC(FrameDepth depth, Isolate* isolate, | 469 KeyedStoreIC(FrameDepth depth, Isolate* isolate, |
| 503 KeyedStoreICNexus* nexus = NULL) | 470 KeyedStoreICNexus* nexus = NULL) |
| 504 : StoreIC(depth, isolate, nexus) { | 471 : StoreIC(depth, isolate, nexus) {} |
| 505 DCHECK(target()->is_keyed_store_stub()); | |
| 506 } | |
| 507 | 472 |
| 508 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, | 473 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, |
| 509 Handle<Object> name, | 474 Handle<Object> name, |
| 510 Handle<Object> value); | 475 Handle<Object> value); |
| 511 | 476 |
| 512 // Code generators for stub routines. Only called once at startup. | 477 // Code generators for stub routines. Only called once at startup. |
| 513 static void GenerateMiss(MacroAssembler* masm); | 478 static void GenerateMiss(MacroAssembler* masm); |
| 514 static void GenerateSlow(MacroAssembler* masm); | 479 static void GenerateSlow(MacroAssembler* masm); |
| 515 static void GenerateMegamorphic(MacroAssembler* masm, | 480 static void GenerateMegamorphic(MacroAssembler* masm, |
| 516 LanguageMode language_mode); | 481 LanguageMode language_mode); |
| 517 | 482 |
| 518 static Handle<Code> initialize_stub(Isolate* isolate, | 483 static Handle<Code> initialize_stub(Isolate* isolate, |
| 519 LanguageMode language_mode, | 484 LanguageMode language_mode, |
| 520 State initialization_state); | 485 State initialization_state); |
| 521 | 486 |
| 522 static Handle<Code> initialize_stub_in_optimized_code( | 487 static Handle<Code> initialize_stub_in_optimized_code( |
| 523 Isolate* isolate, LanguageMode language_mode, State initialization_state); | 488 Isolate* isolate, LanguageMode language_mode, State initialization_state); |
| 524 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate, | 489 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate, |
| 525 ExtraICState extra_state); | 490 ExtraICState extra_state); |
| 526 | 491 |
| 527 static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus); | 492 static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus); |
| 528 | 493 |
| 529 protected: | 494 protected: |
| 530 Handle<Code> StoreElementStub(Handle<Map> receiver_map, | 495 Handle<Code> StoreElementStub(Handle<Map> receiver_map, |
| 531 KeyedAccessStoreMode store_mode); | 496 KeyedAccessStoreMode store_mode); |
| 532 | 497 |
| 533 private: | 498 private: |
| 534 inline void set_target(Code* code); | |
| 535 | |
| 536 Handle<Map> ComputeTransitionedMap(Handle<Map> map, | 499 Handle<Map> ComputeTransitionedMap(Handle<Map> map, |
| 537 KeyedAccessStoreMode store_mode); | 500 KeyedAccessStoreMode store_mode); |
| 538 | 501 |
| 539 friend class IC; | 502 friend class IC; |
| 540 }; | 503 }; |
| 541 | 504 |
| 542 | 505 |
| 543 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. | 506 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. |
| 544 class BinaryOpIC : public IC { | 507 class BinaryOpIC : public IC { |
| 545 public: | 508 public: |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 555 |
| 593 // Helper for BinaryOpIC and CompareIC. | 556 // Helper for BinaryOpIC and CompareIC. |
| 594 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; | 557 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; |
| 595 void PatchInlinedSmiCode(Isolate* isolate, Address address, | 558 void PatchInlinedSmiCode(Isolate* isolate, Address address, |
| 596 InlinedSmiCheck check); | 559 InlinedSmiCheck check); |
| 597 | 560 |
| 598 } // namespace internal | 561 } // namespace internal |
| 599 } // namespace v8 | 562 } // namespace v8 |
| 600 | 563 |
| 601 #endif // V8_IC_H_ | 564 #endif // V8_IC_H_ |
| OLD | NEW |