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