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 |