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/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 // JavaScript frames on the stack. | 68 // JavaScript frames on the stack. |
69 IC(FrameDepth depth, Isolate* isolate); | 69 IC(FrameDepth depth, Isolate* isolate); |
70 virtual ~IC() {} | 70 virtual ~IC() {} |
71 | 71 |
72 State state() const { return state_; } | 72 State state() const { return state_; } |
73 inline Address address() const; | 73 inline Address address() const; |
74 | 74 |
75 // Compute the current IC state based on the target stub, receiver and name. | 75 // Compute the current IC state based on the target stub, receiver and name. |
76 void UpdateState(Handle<Object> receiver, Handle<Object> name); | 76 void UpdateState(Handle<Object> receiver, Handle<Object> name); |
77 | 77 |
78 bool IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name); | 78 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); |
79 bool TryMarkMonomorphicPrototypeFailure(Handle<Object> name) { | 79 void MarkPrototypeFailure(Handle<Object> name) { |
80 if (IsNameCompatibleWithMonomorphicPrototypeFailure(name)) { | 80 ASSERT(IsNameCompatibleWithPrototypeFailure(name)); |
81 state_ = MONOMORPHIC_PROTOTYPE_FAILURE; | 81 state_ = PROTOTYPE_FAILURE; |
82 return true; | |
83 } | |
84 return false; | |
85 } | 82 } |
86 | 83 |
87 // If the stub contains weak maps then this function adds the stub to | 84 // If the stub contains weak maps then this function adds the stub to |
88 // the dependent code array of each weak map. | 85 // the dependent code array of each weak map. |
89 static void RegisterWeakMapDependency(Handle<Code> stub); | 86 static void RegisterWeakMapDependency(Handle<Code> stub); |
90 | 87 |
91 // This function is called when a weak map in the stub is dying, | 88 // This function is called when a weak map in the stub is dying, |
92 // invalidates the stub by setting maps in it to undefined. | 89 // invalidates the stub by setting maps in it to undefined. |
93 static void InvalidateMaps(Code* stub); | 90 static void InvalidateMaps(Code* stub); |
94 | 91 |
95 // Clear the inline cache to initial state. | 92 // Clear the inline cache to initial state. |
96 static void Clear(Isolate* isolate, | 93 static void Clear(Isolate* isolate, |
97 Address address, | 94 Address address, |
98 ConstantPoolArray* constant_pool); | 95 ConstantPoolArray* constant_pool); |
99 | 96 |
100 #ifdef DEBUG | 97 #ifdef DEBUG |
101 bool IsLoadStub() const { | 98 bool IsLoadStub() const { |
102 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 99 return target()->is_load_stub() || target()->is_keyed_load_stub(); |
103 } | 100 } |
104 | 101 |
105 bool IsStoreStub() const { | 102 bool IsStoreStub() const { |
106 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 103 return target()->is_store_stub() || target()->is_keyed_store_stub(); |
107 } | 104 } |
108 | 105 |
109 bool IsCallStub() const { | 106 bool IsCallStub() const { |
110 return target()->is_call_stub(); | 107 return target()->is_call_stub(); |
111 } | 108 } |
112 #endif | 109 #endif |
113 | 110 |
114 // Determines which map must be used for keeping the code stub. | 111 template <class TypeClass> |
115 // These methods should not be called with undefined or null. | 112 static JSFunction* GetRootConstructor(TypeClass* type, |
116 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object); | 113 Context* native_context); |
117 // TODO(verwaest): This currently returns a HeapObject rather than JSObject* | 114 static inline Handle<Map> GetHandlerCacheHolder(HeapType* type, |
118 // since loading the IC for loading the length from strings are stored on | 115 bool receiver_is_holder, |
119 // the string map directly, rather than on the JSObject-typed prototype. | 116 Isolate* isolate, |
120 static inline HeapObject* GetCodeCacheHolder(Isolate* isolate, | 117 CacheHolderFlag* flag); |
121 Object* object, | 118 static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate, |
122 InlineCacheHolderFlag holder); | 119 CacheHolderFlag* flag); |
123 | |
124 static inline InlineCacheHolderFlag GetCodeCacheFlag(HeapType* type); | |
125 static inline Handle<Map> GetCodeCacheHolder(InlineCacheHolderFlag flag, | |
126 HeapType* type, | |
127 Isolate* isolate); | |
128 | 120 |
129 static bool IsCleared(Code* code) { | 121 static bool IsCleared(Code* code) { |
130 InlineCacheState state = code->ic_state(); | 122 InlineCacheState state = code->ic_state(); |
131 return state == UNINITIALIZED || state == PREMONOMORPHIC; | 123 return state == UNINITIALIZED || state == PREMONOMORPHIC; |
132 } | 124 } |
133 | 125 |
134 // Utility functions to convert maps to types and back. There are two special | 126 // Utility functions to convert maps to types and back. There are two special |
135 // cases: | 127 // cases: |
136 // - The heap_number_map is used as a marker which includes heap numbers as | 128 // - The heap_number_map is used as a marker which includes heap numbers as |
137 // well as smis. | 129 // well as smis. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 ConstantPoolArray* constant_pool); | 178 ConstantPoolArray* constant_pool); |
187 static void PostPatching(Address address, Code* target, Code* old_target); | 179 static void PostPatching(Address address, Code* target, Code* old_target); |
188 | 180 |
189 // Compute the handler either by compiling or by retrieving a cached version. | 181 // Compute the handler either by compiling or by retrieving a cached version. |
190 Handle<Code> ComputeHandler(LookupResult* lookup, | 182 Handle<Code> ComputeHandler(LookupResult* lookup, |
191 Handle<Object> object, | 183 Handle<Object> object, |
192 Handle<String> name, | 184 Handle<String> name, |
193 Handle<Object> value = Handle<Code>::null()); | 185 Handle<Object> value = Handle<Code>::null()); |
194 virtual Handle<Code> CompileHandler(LookupResult* lookup, | 186 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
195 Handle<Object> object, | 187 Handle<Object> object, |
196 Handle<String> name, | 188 Handle<String> name, Handle<Object> value, |
197 Handle<Object> value, | 189 CacheHolderFlag cache_holder) { |
198 InlineCacheHolderFlag cache_holder) { | |
199 UNREACHABLE(); | 190 UNREACHABLE(); |
200 return Handle<Code>::null(); | 191 return Handle<Code>::null(); |
201 } | 192 } |
202 | 193 |
203 void UpdateMonomorphicIC(Handle<HeapType> type, | 194 void UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name); |
204 Handle<Code> handler, | |
205 Handle<String> name); | |
206 | 195 |
207 bool UpdatePolymorphicIC(Handle<HeapType> type, | 196 bool UpdatePolymorphicIC(Handle<String> name, Handle<Code> code); |
208 Handle<String> name, | |
209 Handle<Code> code); | |
210 | 197 |
211 virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); | 198 virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); |
212 | 199 |
213 void CopyICToMegamorphicCache(Handle<String> name); | 200 void CopyICToMegamorphicCache(Handle<String> name); |
214 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); | 201 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); |
215 void PatchCache(Handle<HeapType> type, | 202 void PatchCache(Handle<String> name, Handle<Code> code); |
216 Handle<String> name, | |
217 Handle<Code> code); | |
218 virtual Code::Kind kind() const { | 203 virtual Code::Kind kind() const { |
219 UNREACHABLE(); | 204 UNREACHABLE(); |
220 return Code::STUB; | 205 return Code::STUB; |
221 } | 206 } |
222 virtual Handle<Code> slow_stub() const { | 207 virtual Handle<Code> slow_stub() const { |
223 UNREACHABLE(); | 208 UNREACHABLE(); |
224 return Handle<Code>::null(); | 209 return Handle<Code>::null(); |
225 } | 210 } |
226 virtual Handle<Code> megamorphic_stub() { | 211 virtual Handle<Code> megamorphic_stub() { |
227 UNREACHABLE(); | 212 UNREACHABLE(); |
228 return Handle<Code>::null(); | 213 return Handle<Code>::null(); |
229 } | 214 } |
230 virtual Handle<Code> generic_stub() const { | 215 virtual Handle<Code> generic_stub() const { |
231 UNREACHABLE(); | 216 UNREACHABLE(); |
232 return Handle<Code>::null(); | 217 return Handle<Code>::null(); |
233 } | 218 } |
234 | 219 |
235 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, | 220 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
236 Handle<String> name); | 221 Handle<String> name); |
237 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name); | |
238 | 222 |
239 ExtraICState extra_ic_state() const { return extra_ic_state_; } | 223 ExtraICState extra_ic_state() const { return extra_ic_state_; } |
240 void set_extra_ic_state(ExtraICState state) { | 224 void set_extra_ic_state(ExtraICState state) { |
241 extra_ic_state_ = state; | 225 extra_ic_state_ = state; |
242 } | 226 } |
243 | 227 |
| 228 Handle<HeapType> receiver_type() { return receiver_type_; } |
| 229 |
244 void TargetMaps(MapHandleList* list) { | 230 void TargetMaps(MapHandleList* list) { |
245 FindTargetMaps(); | 231 FindTargetMaps(); |
246 for (int i = 0; i < target_maps_.length(); i++) { | 232 for (int i = 0; i < target_maps_.length(); i++) { |
247 list->Add(target_maps_.at(i)); | 233 list->Add(target_maps_.at(i)); |
248 } | 234 } |
249 } | 235 } |
250 | 236 |
251 void TargetTypes(TypeHandleList* list) { | 237 void TargetTypes(TypeHandleList* list) { |
252 FindTargetMaps(); | 238 FindTargetMaps(); |
253 for (int i = 0; i < target_maps_.length(); i++) { | 239 for (int i = 0; i < target_maps_.length(); i++) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 Address* pc_address_; | 279 Address* pc_address_; |
294 | 280 |
295 Isolate* isolate_; | 281 Isolate* isolate_; |
296 | 282 |
297 // The constant pool of the code which originally called the IC (which might | 283 // The constant pool of the code which originally called the IC (which might |
298 // be for the breakpointed copy of the original code). | 284 // be for the breakpointed copy of the original code). |
299 Handle<ConstantPoolArray> raw_constant_pool_; | 285 Handle<ConstantPoolArray> raw_constant_pool_; |
300 | 286 |
301 // The original code target that missed. | 287 // The original code target that missed. |
302 Handle<Code> target_; | 288 Handle<Code> target_; |
| 289 bool target_set_; |
303 State state_; | 290 State state_; |
304 bool target_set_; | 291 Handle<HeapType> receiver_type_; |
| 292 MaybeHandle<Code> maybe_handler_; |
305 | 293 |
306 ExtraICState extra_ic_state_; | 294 ExtraICState extra_ic_state_; |
307 MapHandleList target_maps_; | 295 MapHandleList target_maps_; |
308 bool target_maps_set_; | 296 bool target_maps_set_; |
309 | 297 |
310 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); | 298 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
311 }; | 299 }; |
312 | 300 |
313 | 301 |
314 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you | 302 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // Update the inline cache and the global stub cache based on the | 457 // Update the inline cache and the global stub cache based on the |
470 // lookup result. | 458 // lookup result. |
471 void UpdateCaches(LookupResult* lookup, | 459 void UpdateCaches(LookupResult* lookup, |
472 Handle<Object> object, | 460 Handle<Object> object, |
473 Handle<String> name); | 461 Handle<String> name); |
474 | 462 |
475 virtual Handle<Code> CompileHandler(LookupResult* lookup, | 463 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
476 Handle<Object> object, | 464 Handle<Object> object, |
477 Handle<String> name, | 465 Handle<String> name, |
478 Handle<Object> unused, | 466 Handle<Object> unused, |
479 InlineCacheHolderFlag cache_holder); | 467 CacheHolderFlag cache_holder); |
480 | 468 |
481 private: | 469 private: |
482 // Stub accessors. | 470 // Stub accessors. |
483 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, | 471 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, |
484 ExtraICState exstra_state); | 472 ExtraICState exstra_state); |
485 | 473 |
486 virtual Handle<Code> pre_monomorphic_stub() { | 474 virtual Handle<Code> pre_monomorphic_stub() { |
487 return pre_monomorphic_stub(isolate(), extra_ic_state()); | 475 return pre_monomorphic_stub(isolate(), extra_ic_state()); |
488 } | 476 } |
489 | 477 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 StrictMode strict_mode); | 631 StrictMode strict_mode); |
644 | 632 |
645 // Update the inline cache and the global stub cache based on the | 633 // Update the inline cache and the global stub cache based on the |
646 // lookup result. | 634 // lookup result. |
647 void UpdateCaches(LookupResult* lookup, | 635 void UpdateCaches(LookupResult* lookup, |
648 Handle<JSObject> receiver, | 636 Handle<JSObject> receiver, |
649 Handle<String> name, | 637 Handle<String> name, |
650 Handle<Object> value); | 638 Handle<Object> value); |
651 virtual Handle<Code> CompileHandler(LookupResult* lookup, | 639 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
652 Handle<Object> object, | 640 Handle<Object> object, |
653 Handle<String> name, | 641 Handle<String> name, Handle<Object> value, |
654 Handle<Object> value, | 642 CacheHolderFlag cache_holder); |
655 InlineCacheHolderFlag cache_holder); | |
656 | 643 |
657 private: | 644 private: |
658 void set_target(Code* code) { | 645 void set_target(Code* code) { |
659 // Strict mode must be preserved across IC patching. | 646 // Strict mode must be preserved across IC patching. |
660 ASSERT(GetStrictMode(code->extra_ic_state()) == | 647 ASSERT(GetStrictMode(code->extra_ic_state()) == |
661 GetStrictMode(target()->extra_ic_state())); | 648 GetStrictMode(target()->extra_ic_state())); |
662 IC::set_target(code); | 649 IC::set_target(code); |
663 } | 650 } |
664 | 651 |
665 static void Clear(Isolate* isolate, | 652 static void Clear(Isolate* isolate, |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); | 1030 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); |
1044 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); | 1031 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); |
1045 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); | 1032 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); |
1046 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); | 1033 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); |
1047 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); | 1034 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); |
1048 | 1035 |
1049 | 1036 |
1050 } } // namespace v8::internal | 1037 } } // namespace v8::internal |
1051 | 1038 |
1052 #endif // V8_IC_H_ | 1039 #endif // V8_IC_H_ |
OLD | NEW |