| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 | 36 |
| 37 const int kMaxKeyedPolymorphism = 4; | 37 const int kMaxKeyedPolymorphism = 4; |
| 38 | 38 |
| 39 | 39 |
| 40 // IC_UTIL_LIST defines all utility functions called from generated | 40 // IC_UTIL_LIST defines all utility functions called from generated |
| 41 // inline caching code. The argument for the macro, ICU, is the function name. | 41 // inline caching code. The argument for the macro, ICU, is the function name. |
| 42 #define IC_UTIL_LIST(ICU) \ | 42 #define IC_UTIL_LIST(ICU) \ |
| 43 ICU(LoadIC_Miss) \ | 43 ICU(LoadIC_Miss) \ |
| 44 ICU(KeyedLoadIC_Miss) \ | 44 ICU(KeyedLoadIC_Miss) \ |
| 45 ICU(CallIC_Miss) \ | |
| 46 ICU(KeyedCallIC_Miss) \ | |
| 47 ICU(StoreIC_Miss) \ | 45 ICU(StoreIC_Miss) \ |
| 48 ICU(StoreIC_ArrayLength) \ | 46 ICU(StoreIC_ArrayLength) \ |
| 49 ICU(StoreIC_Slow) \ | 47 ICU(StoreIC_Slow) \ |
| 50 ICU(SharedStoreIC_ExtendStorage) \ | 48 ICU(SharedStoreIC_ExtendStorage) \ |
| 51 ICU(KeyedStoreIC_Miss) \ | 49 ICU(KeyedStoreIC_Miss) \ |
| 52 ICU(KeyedStoreIC_Slow) \ | 50 ICU(KeyedStoreIC_Slow) \ |
| 53 /* Utilities for IC stubs. */ \ | 51 /* Utilities for IC stubs. */ \ |
| 54 ICU(StoreCallbackProperty) \ | 52 ICU(StoreCallbackProperty) \ |
| 55 ICU(LoadPropertyWithInterceptorOnly) \ | 53 ICU(LoadPropertyWithInterceptorOnly) \ |
| 56 ICU(LoadPropertyWithInterceptorForLoad) \ | 54 ICU(LoadPropertyWithInterceptorForLoad) \ |
| 57 ICU(LoadPropertyWithInterceptorForCall) \ | 55 ICU(LoadPropertyWithInterceptorForCall) \ |
| 58 ICU(KeyedLoadPropertyWithInterceptor) \ | 56 ICU(KeyedLoadPropertyWithInterceptor) \ |
| 59 ICU(StoreInterceptorProperty) \ | 57 ICU(StoreInterceptorProperty) \ |
| 60 ICU(CompareIC_Miss) \ | 58 ICU(CompareIC_Miss) \ |
| 61 ICU(BinaryOpIC_Miss) \ | 59 ICU(BinaryOpIC_Miss) \ |
| 62 ICU(CompareNilIC_Miss) \ | 60 ICU(CompareNilIC_Miss) \ |
| 63 ICU(Unreachable) \ | 61 ICU(Unreachable) \ |
| 64 ICU(ToBooleanIC_Miss) | 62 ICU(ToBooleanIC_Miss) |
| 65 // | 63 // |
| 66 // IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC, | 64 // IC is the base class for LoadIC, StoreIC, KeyedLoadIC, and KeyedStoreIC. |
| 67 // and KeyedStoreIC. | |
| 68 // | 65 // |
| 69 class IC { | 66 class IC { |
| 70 public: | 67 public: |
| 71 // The ids for utility called from the generated code. | 68 // The ids for utility called from the generated code. |
| 72 enum UtilityId { | 69 enum UtilityId { |
| 73 #define CONST_NAME(name) k##name, | 70 #define CONST_NAME(name) k##name, |
| 74 IC_UTIL_LIST(CONST_NAME) | 71 IC_UTIL_LIST(CONST_NAME) |
| 75 #undef CONST_NAME | 72 #undef CONST_NAME |
| 76 kUtilityCount | 73 kUtilityCount |
| 77 }; | 74 }; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 107 static void Clear(Isolate* isolate, Address address); | 104 static void Clear(Isolate* isolate, Address address); |
| 108 | 105 |
| 109 #ifdef DEBUG | 106 #ifdef DEBUG |
| 110 bool IsLoadStub() const { | 107 bool IsLoadStub() const { |
| 111 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 108 return target()->is_load_stub() || target()->is_keyed_load_stub(); |
| 112 } | 109 } |
| 113 | 110 |
| 114 bool IsStoreStub() const { | 111 bool IsStoreStub() const { |
| 115 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 112 return target()->is_store_stub() || target()->is_keyed_store_stub(); |
| 116 } | 113 } |
| 117 | |
| 118 bool IsCallStub() const { | |
| 119 return target()->is_call_stub() || target()->is_keyed_call_stub(); | |
| 120 } | |
| 121 #endif | 114 #endif |
| 122 | 115 |
| 123 // Determines which map must be used for keeping the code stub. | 116 // Determines which map must be used for keeping the code stub. |
| 124 // These methods should not be called with undefined or null. | 117 // These methods should not be called with undefined or null. |
| 125 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object); | 118 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object); |
| 126 // TODO(verwaest): This currently returns a HeapObject rather than JSObject* | 119 // TODO(verwaest): This currently returns a HeapObject rather than JSObject* |
| 127 // since loading the IC for loading the length from strings are stored on | 120 // since loading the IC for loading the length from strings are stored on |
| 128 // the string map directly, rather than on the JSObject-typed prototype. | 121 // the string map directly, rather than on the JSObject-typed prototype. |
| 129 static inline HeapObject* GetCodeCacheHolder(Isolate* isolate, | 122 static inline HeapObject* GetCodeCacheHolder(Isolate* isolate, |
| 130 Object* object, | 123 Object* object, |
| 131 InlineCacheHolderFlag holder); | 124 InlineCacheHolderFlag holder); |
| 132 | 125 |
| 133 static inline InlineCacheHolderFlag GetCodeCacheFlag(Type* type); | 126 static inline InlineCacheHolderFlag GetCodeCacheFlag(HeapType* type); |
| 134 static inline Handle<Map> GetCodeCacheHolder(InlineCacheHolderFlag flag, | 127 static inline Handle<Map> GetCodeCacheHolder(InlineCacheHolderFlag flag, |
| 135 Type* type, | 128 HeapType* type, |
| 136 Isolate* isolate); | 129 Isolate* isolate); |
| 137 | 130 |
| 138 static bool IsCleared(Code* code) { | 131 static bool IsCleared(Code* code) { |
| 139 InlineCacheState state = code->ic_state(); | 132 InlineCacheState state = code->ic_state(); |
| 140 return state == UNINITIALIZED || state == PREMONOMORPHIC; | 133 return state == UNINITIALIZED || state == PREMONOMORPHIC; |
| 141 } | 134 } |
| 142 | 135 |
| 143 // Utility functions to convert maps to types and back. There are two special | 136 // Utility functions to convert maps to types and back. There are two special |
| 144 // cases: | 137 // cases: |
| 145 // - The heap_number_map is used as a marker which includes heap numbers as | 138 // - The heap_number_map is used as a marker which includes heap numbers as |
| 146 // well as smis. | 139 // well as smis. |
| 147 // - The oddball map is only used for booleans. | 140 // - The oddball map is only used for booleans. |
| 148 static Handle<Map> TypeToMap(Type* type, Isolate* isolate); | 141 static Handle<Map> TypeToMap(HeapType* type, Isolate* isolate); |
| 149 static Handle<Type> MapToType(Handle<Map> type); | 142 template <class T> |
| 150 static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate); | 143 static typename T::TypeHandle MapToType(Handle<Map> map, |
| 144 typename T::Region* region); |
| 145 |
| 146 static Handle<HeapType> CurrentTypeOf(Handle<Object> object, |
| 147 Isolate* isolate); |
| 151 | 148 |
| 152 protected: | 149 protected: |
| 153 // Get the call-site target; used for determining the state. | 150 // Get the call-site target; used for determining the state. |
| 154 Handle<Code> target() const { return target_; } | 151 Handle<Code> target() const { return target_; } |
| 155 | 152 |
| 156 Address fp() const { return fp_; } | 153 Address fp() const { return fp_; } |
| 157 Address pc() const { return *pc_address_; } | 154 Address pc() const { return *pc_address_; } |
| 158 Isolate* isolate() const { return isolate_; } | 155 Isolate* isolate() const { return isolate_; } |
| 159 | 156 |
| 160 #ifdef ENABLE_DEBUGGER_SUPPORT | 157 #ifdef ENABLE_DEBUGGER_SUPPORT |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 Handle<Object> value = Handle<Code>::null()); | 191 Handle<Object> value = Handle<Code>::null()); |
| 195 virtual Handle<Code> CompileHandler(LookupResult* lookup, | 192 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
| 196 Handle<Object> object, | 193 Handle<Object> object, |
| 197 Handle<String> name, | 194 Handle<String> name, |
| 198 Handle<Object> value, | 195 Handle<Object> value, |
| 199 InlineCacheHolderFlag cache_holder) { | 196 InlineCacheHolderFlag cache_holder) { |
| 200 UNREACHABLE(); | 197 UNREACHABLE(); |
| 201 return Handle<Code>::null(); | 198 return Handle<Code>::null(); |
| 202 } | 199 } |
| 203 | 200 |
| 204 void UpdateMonomorphicIC(Handle<Type> type, | 201 void UpdateMonomorphicIC(Handle<HeapType> type, |
| 205 Handle<Code> handler, | 202 Handle<Code> handler, |
| 206 Handle<String> name); | 203 Handle<String> name); |
| 207 | 204 |
| 208 bool UpdatePolymorphicIC(Handle<Type> type, | 205 bool UpdatePolymorphicIC(Handle<HeapType> type, |
| 209 Handle<String> name, | 206 Handle<String> name, |
| 210 Handle<Code> code); | 207 Handle<Code> code); |
| 211 | 208 |
| 212 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code); | 209 virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); |
| 213 | 210 |
| 214 void CopyICToMegamorphicCache(Handle<String> name); | 211 void CopyICToMegamorphicCache(Handle<String> name); |
| 215 bool IsTransitionOfMonomorphicTarget(Handle<Type> type); | 212 bool IsTransitionOfMonomorphicTarget(Handle<HeapType> type); |
| 216 void PatchCache(Handle<Type> type, | 213 void PatchCache(Handle<HeapType> type, |
| 217 Handle<String> name, | 214 Handle<String> name, |
| 218 Handle<Code> code); | 215 Handle<Code> code); |
| 219 virtual Code::Kind kind() const { | 216 virtual Code::Kind kind() const { |
| 220 UNREACHABLE(); | 217 UNREACHABLE(); |
| 221 return Code::STUB; | 218 return Code::STUB; |
| 222 } | 219 } |
| 223 virtual Handle<Code> slow_stub() const { | 220 virtual Handle<Code> slow_stub() const { |
| 224 UNREACHABLE(); | 221 UNREACHABLE(); |
| 225 return Handle<Code>::null(); | 222 return Handle<Code>::null(); |
| 226 } | 223 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 | 273 |
| 277 Address address() const { return address_; } | 274 Address address() const { return address_; } |
| 278 | 275 |
| 279 IC::UtilityId id() const { return id_; } | 276 IC::UtilityId id() const { return id_; } |
| 280 private: | 277 private: |
| 281 Address address_; | 278 Address address_; |
| 282 IC::UtilityId id_; | 279 IC::UtilityId id_; |
| 283 }; | 280 }; |
| 284 | 281 |
| 285 | 282 |
| 286 class CallICBase: public IC { | |
| 287 public: | |
| 288 // Returns a JSFunction or a Failure. | |
| 289 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, | |
| 290 Handle<String> name); | |
| 291 | |
| 292 protected: | |
| 293 CallICBase(Code::Kind kind, Isolate* isolate) | |
| 294 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} | |
| 295 | |
| 296 // Compute a monomorphic stub if possible, otherwise return a null handle. | |
| 297 Handle<Code> ComputeMonomorphicStub(LookupResult* lookup, | |
| 298 Handle<Object> object, | |
| 299 Handle<String> name); | |
| 300 | |
| 301 // Update the inline cache and the global stub cache based on the lookup | |
| 302 // result. | |
| 303 void UpdateCaches(LookupResult* lookup, | |
| 304 Handle<Object> object, | |
| 305 Handle<String> name); | |
| 306 | |
| 307 // Returns a JSFunction if the object can be called as a function, and | |
| 308 // patches the stack to be ready for the call. Otherwise, it returns the | |
| 309 // undefined value. | |
| 310 Handle<Object> TryCallAsFunction(Handle<Object> object); | |
| 311 | |
| 312 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); | |
| 313 | |
| 314 static void Clear(Address address, Code* target); | |
| 315 | |
| 316 // Platform-specific code generation functions used by both call and | |
| 317 // keyed call. | |
| 318 static void GenerateMiss(MacroAssembler* masm, | |
| 319 int argc, | |
| 320 IC::UtilityId id, | |
| 321 ExtraICState extra_state); | |
| 322 | |
| 323 static void GenerateNormal(MacroAssembler* masm, int argc); | |
| 324 | |
| 325 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, | |
| 326 int argc, | |
| 327 Code::Kind kind, | |
| 328 ExtraICState extra_state); | |
| 329 | |
| 330 virtual Handle<Code> megamorphic_stub(); | |
| 331 virtual Handle<Code> pre_monomorphic_stub(); | |
| 332 | |
| 333 Code::Kind kind_; | |
| 334 | |
| 335 friend class IC; | |
| 336 }; | |
| 337 | |
| 338 | |
| 339 class CallIC: public CallICBase { | |
| 340 public: | |
| 341 explicit CallIC(Isolate* isolate) | |
| 342 : CallICBase(Code::CALL_IC, isolate) { | |
| 343 ASSERT(target()->is_call_stub()); | |
| 344 } | |
| 345 | |
| 346 // Code generator routines. | |
| 347 static void GenerateInitialize(MacroAssembler* masm, | |
| 348 int argc, | |
| 349 ExtraICState extra_state) { | |
| 350 GenerateMiss(masm, argc, extra_state); | |
| 351 } | |
| 352 | |
| 353 static void GenerateMiss(MacroAssembler* masm, | |
| 354 int argc, | |
| 355 ExtraICState extra_state) { | |
| 356 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state); | |
| 357 } | |
| 358 | |
| 359 static void GenerateMegamorphic(MacroAssembler* masm, | |
| 360 int argc, | |
| 361 ExtraICState extra_ic_state); | |
| 362 | |
| 363 static void GenerateNormal(MacroAssembler* masm, int argc) { | |
| 364 CallICBase::GenerateNormal(masm, argc); | |
| 365 GenerateMiss(masm, argc, kNoExtraICState); | |
| 366 } | |
| 367 bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object); | |
| 368 }; | |
| 369 | |
| 370 | |
| 371 class KeyedCallIC: public CallICBase { | |
| 372 public: | |
| 373 explicit KeyedCallIC(Isolate* isolate) | |
| 374 : CallICBase(Code::KEYED_CALL_IC, isolate) { | |
| 375 ASSERT(target()->is_keyed_call_stub()); | |
| 376 } | |
| 377 | |
| 378 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, | |
| 379 Handle<Object> key); | |
| 380 | |
| 381 // Code generator routines. | |
| 382 static void GenerateInitialize(MacroAssembler* masm, int argc) { | |
| 383 GenerateMiss(masm, argc); | |
| 384 } | |
| 385 | |
| 386 static void GenerateMiss(MacroAssembler* masm, int argc) { | |
| 387 CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss, | |
| 388 kNoExtraICState); | |
| 389 } | |
| 390 | |
| 391 static void GenerateMegamorphic(MacroAssembler* masm, int argc); | |
| 392 static void GenerateNormal(MacroAssembler* masm, int argc); | |
| 393 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); | |
| 394 }; | |
| 395 | |
| 396 | |
| 397 class LoadIC: public IC { | 283 class LoadIC: public IC { |
| 398 public: | 284 public: |
| 399 // ExtraICState bits | 285 // ExtraICState bits |
| 400 class Contextual: public BitField<ContextualMode, 0, 1> {}; | 286 class ContextualModeBits: public BitField<ContextualMode, 0, 1> {}; |
| 401 STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0); | 287 STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0); |
| 402 | 288 |
| 403 static ExtraICState ComputeExtraICState(ContextualMode mode) { | 289 static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) { |
| 404 return Contextual::encode(mode); | 290 return ContextualModeBits::encode(contextual_mode); |
| 405 } | 291 } |
| 406 | 292 |
| 407 static ContextualMode GetContextualMode(ExtraICState state) { | 293 static ContextualMode GetContextualMode(ExtraICState state) { |
| 408 return Contextual::decode(state); | 294 return ContextualModeBits::decode(state); |
| 409 } | 295 } |
| 410 | 296 |
| 411 ContextualMode contextual_mode() const { | 297 ContextualMode contextual_mode() const { |
| 412 return Contextual::decode(extra_ic_state()); | 298 return ContextualModeBits::decode(extra_ic_state()); |
| 413 } | 299 } |
| 414 | 300 |
| 415 explicit LoadIC(FrameDepth depth, Isolate* isolate) | 301 explicit LoadIC(FrameDepth depth, Isolate* isolate) |
| 416 : IC(depth, isolate) { | 302 : IC(depth, isolate) { |
| 417 ASSERT(IsLoadStub()); | 303 ASSERT(IsLoadStub()); |
| 418 } | 304 } |
| 419 | 305 |
| 420 // Returns if this IC is for contextual (no explicit receiver) | 306 // Returns if this IC is for contextual (no explicit receiver) |
| 421 // access to properties. | 307 // access to properties. |
| 422 bool IsUndeclaredGlobal(Handle<Object> receiver) { | 308 bool IsUndeclaredGlobal(Handle<Object> receiver) { |
| 423 if (receiver->IsGlobalObject()) { | 309 if (receiver->IsGlobalObject()) { |
| 424 return contextual_mode() == CONTEXTUAL; | 310 return contextual_mode() == CONTEXTUAL; |
| 425 } else { | 311 } else { |
| 426 ASSERT(contextual_mode() != CONTEXTUAL); | 312 ASSERT(contextual_mode() != CONTEXTUAL); |
| 427 return false; | 313 return false; |
| 428 } | 314 } |
| 429 } | 315 } |
| 430 | 316 |
| 431 // Code generator routines. | 317 // Code generator routines. |
| 432 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 318 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 433 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 319 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
| 434 GenerateMiss(masm); | 320 GenerateMiss(masm); |
| 435 } | 321 } |
| 436 static void GenerateMiss(MacroAssembler* masm); | 322 static void GenerateMiss(MacroAssembler* masm); |
| 437 static void GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode); | 323 static void GenerateMegamorphic(MacroAssembler* masm); |
| 438 static void GenerateNormal(MacroAssembler* masm); | 324 static void GenerateNormal(MacroAssembler* masm); |
| 439 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 325 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
| 440 | 326 |
| 441 static Handle<Code> initialize_stub(Isolate* isolate, ContextualMode mode); | 327 static Handle<Code> initialize_stub(Isolate* isolate, |
| 328 ExtraICState extra_state); |
| 442 | 329 |
| 443 MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, | 330 MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, |
| 444 Handle<String> name); | 331 Handle<String> name); |
| 445 | 332 |
| 446 protected: | 333 protected: |
| 447 virtual Code::Kind kind() const { return Code::LOAD_IC; } | 334 virtual Code::Kind kind() const { return Code::LOAD_IC; } |
| 448 | 335 |
| 449 void set_target(Code* code) { | 336 void set_target(Code* code) { |
| 450 // The contextual mode must be preserved across IC patching. | 337 // The contextual mode must be preserved across IC patching. |
| 451 ASSERT(GetContextualMode(code->extra_ic_state()) == | 338 ASSERT(GetContextualMode(code->extra_ic_state()) == |
| (...skipping 16 matching lines...) Expand all Loading... |
| 468 | 355 |
| 469 virtual Handle<Code> CompileHandler(LookupResult* lookup, | 356 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
| 470 Handle<Object> object, | 357 Handle<Object> object, |
| 471 Handle<String> name, | 358 Handle<String> name, |
| 472 Handle<Object> unused, | 359 Handle<Object> unused, |
| 473 InlineCacheHolderFlag cache_holder); | 360 InlineCacheHolderFlag cache_holder); |
| 474 | 361 |
| 475 private: | 362 private: |
| 476 // Stub accessors. | 363 // Stub accessors. |
| 477 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, | 364 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, |
| 478 ContextualMode mode); | 365 ExtraICState exstra_state); |
| 479 | 366 |
| 480 virtual Handle<Code> pre_monomorphic_stub() { | 367 virtual Handle<Code> pre_monomorphic_stub() { |
| 481 return pre_monomorphic_stub(isolate(), contextual_mode()); | 368 return pre_monomorphic_stub(isolate(), extra_ic_state()); |
| 482 } | 369 } |
| 483 | 370 |
| 484 Handle<Code> SimpleFieldLoad(int offset, | 371 Handle<Code> SimpleFieldLoad(int offset, |
| 485 bool inobject = true, | 372 bool inobject = true, |
| 486 Representation representation = | 373 Representation representation = |
| 487 Representation::Tagged()); | 374 Representation::Tagged()); |
| 488 | 375 |
| 489 static void Clear(Isolate* isolate, Address address, Code* target); | 376 static void Clear(Isolate* isolate, Address address, Code* target); |
| 490 | 377 |
| 491 friend class IC; | 378 friend class IC; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 virtual Handle<Code> megamorphic_stub() { | 416 virtual Handle<Code> megamorphic_stub() { |
| 530 return isolate()->builtins()->KeyedLoadIC_Generic(); | 417 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 531 } | 418 } |
| 532 virtual Handle<Code> generic_stub() const { | 419 virtual Handle<Code> generic_stub() const { |
| 533 return isolate()->builtins()->KeyedLoadIC_Generic(); | 420 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 534 } | 421 } |
| 535 virtual Handle<Code> slow_stub() const { | 422 virtual Handle<Code> slow_stub() const { |
| 536 return isolate()->builtins()->KeyedLoadIC_Slow(); | 423 return isolate()->builtins()->KeyedLoadIC_Slow(); |
| 537 } | 424 } |
| 538 | 425 |
| 539 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } | 426 virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {} |
| 540 | 427 |
| 541 private: | 428 private: |
| 542 // Stub accessors. | 429 // Stub accessors. |
| 543 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { | 430 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { |
| 544 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); | 431 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); |
| 545 } | 432 } |
| 546 virtual Handle<Code> pre_monomorphic_stub() { | 433 virtual Handle<Code> pre_monomorphic_stub() { |
| 547 return pre_monomorphic_stub(isolate()); | 434 return pre_monomorphic_stub(isolate()); |
| 548 } | 435 } |
| 549 Handle<Code> indexed_interceptor_stub() { | 436 Handle<Code> indexed_interceptor_stub() { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 return StrictModeState::decode(extra_ic_state()); | 474 return StrictModeState::decode(extra_ic_state()); |
| 588 } | 475 } |
| 589 | 476 |
| 590 // Code generators for stub routines. Only called once at startup. | 477 // Code generators for stub routines. Only called once at startup. |
| 591 static void GenerateSlow(MacroAssembler* masm); | 478 static void GenerateSlow(MacroAssembler* masm); |
| 592 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 479 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 593 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 480 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
| 594 GenerateMiss(masm); | 481 GenerateMiss(masm); |
| 595 } | 482 } |
| 596 static void GenerateMiss(MacroAssembler* masm); | 483 static void GenerateMiss(MacroAssembler* masm); |
| 597 static void GenerateMegamorphic(MacroAssembler* masm, | 484 static void GenerateMegamorphic(MacroAssembler* masm); |
| 598 ExtraICState extra_ic_state); | |
| 599 static void GenerateNormal(MacroAssembler* masm); | 485 static void GenerateNormal(MacroAssembler* masm); |
| 600 static void GenerateRuntimeSetProperty(MacroAssembler* masm, | 486 static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 601 StrictModeFlag strict_mode); | 487 StrictModeFlag strict_mode); |
| 602 | 488 |
| 603 static Handle<Code> initialize_stub(Isolate* isolate, | 489 static Handle<Code> initialize_stub(Isolate* isolate, |
| 604 StrictModeFlag strict_mode); | 490 StrictModeFlag strict_mode); |
| 605 | 491 |
| 606 MUST_USE_RESULT MaybeObject* Store( | 492 MUST_USE_RESULT MaybeObject* Store( |
| 607 Handle<Object> object, | 493 Handle<Object> object, |
| 608 Handle<String> name, | 494 Handle<String> name, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 static void GenerateMiss(MacroAssembler* masm); | 587 static void GenerateMiss(MacroAssembler* masm); |
| 702 static void GenerateSlow(MacroAssembler* masm); | 588 static void GenerateSlow(MacroAssembler* masm); |
| 703 static void GenerateRuntimeSetProperty(MacroAssembler* masm, | 589 static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 704 StrictModeFlag strict_mode); | 590 StrictModeFlag strict_mode); |
| 705 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); | 591 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); |
| 706 static void GenerateNonStrictArguments(MacroAssembler* masm); | 592 static void GenerateNonStrictArguments(MacroAssembler* masm); |
| 707 | 593 |
| 708 protected: | 594 protected: |
| 709 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } | 595 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } |
| 710 | 596 |
| 711 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } | 597 virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {} |
| 712 | 598 |
| 713 virtual Handle<Code> pre_monomorphic_stub() { | 599 virtual Handle<Code> pre_monomorphic_stub() { |
| 714 return pre_monomorphic_stub(isolate(), strict_mode()); | 600 return pre_monomorphic_stub(isolate(), strict_mode()); |
| 715 } | 601 } |
| 716 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, | 602 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, |
| 717 StrictModeFlag strict_mode) { | 603 StrictModeFlag strict_mode) { |
| 718 if (strict_mode == kStrictMode) { | 604 if (strict_mode == kStrictMode) { |
| 719 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); | 605 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); |
| 720 } else { | 606 } else { |
| 721 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); | 607 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_); | 722 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_); |
| 837 } | 723 } |
| 838 | 724 |
| 839 static const int FIRST_TOKEN = Token::BIT_OR; | 725 static const int FIRST_TOKEN = Token::BIT_OR; |
| 840 static const int LAST_TOKEN = Token::MOD; | 726 static const int LAST_TOKEN = Token::MOD; |
| 841 | 727 |
| 842 Token::Value op() const { return op_; } | 728 Token::Value op() const { return op_; } |
| 843 OverwriteMode mode() const { return mode_; } | 729 OverwriteMode mode() const { return mode_; } |
| 844 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } | 730 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } |
| 845 | 731 |
| 846 Handle<Type> GetLeftType(Isolate* isolate) const { | 732 Type* GetLeftType(Zone* zone) const { |
| 847 return KindToType(left_kind_, isolate); | 733 return KindToType(left_kind_, zone); |
| 848 } | 734 } |
| 849 Handle<Type> GetRightType(Isolate* isolate) const { | 735 Type* GetRightType(Zone* zone) const { |
| 850 return KindToType(right_kind_, isolate); | 736 return KindToType(right_kind_, zone); |
| 851 } | 737 } |
| 852 Handle<Type> GetResultType(Isolate* isolate) const; | 738 Type* GetResultType(Zone* zone) const; |
| 853 | 739 |
| 854 void Print(StringStream* stream) const; | 740 void Print(StringStream* stream) const; |
| 855 | 741 |
| 856 void Update(Handle<Object> left, | 742 void Update(Handle<Object> left, |
| 857 Handle<Object> right, | 743 Handle<Object> right, |
| 858 Handle<Object> result); | 744 Handle<Object> result); |
| 859 | 745 |
| 860 private: | 746 private: |
| 861 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; | 747 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; |
| 862 | 748 |
| 863 Kind UpdateKind(Handle<Object> object, Kind kind) const; | 749 Kind UpdateKind(Handle<Object> object, Kind kind) const; |
| 864 | 750 |
| 865 static const char* KindToString(Kind kind); | 751 static const char* KindToString(Kind kind); |
| 866 static Handle<Type> KindToType(Kind kind, Isolate* isolate); | 752 static Type* KindToType(Kind kind, Zone* zone); |
| 867 static bool KindMaybeSmi(Kind kind) { | 753 static bool KindMaybeSmi(Kind kind) { |
| 868 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC; | 754 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC; |
| 869 } | 755 } |
| 870 | 756 |
| 871 // We truncate the last bit of the token. | 757 // We truncate the last bit of the token. |
| 872 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4)); | 758 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4)); |
| 873 class OpField: public BitField<int, 0, 4> {}; | 759 class OpField: public BitField<int, 0, 4> {}; |
| 874 class OverwriteModeField: public BitField<OverwriteMode, 4, 2> {}; | 760 class OverwriteModeField: public BitField<OverwriteMode, 4, 2> {}; |
| 875 class SSE2Field: public BitField<bool, 6, 1> {}; | 761 class SSE2Field: public BitField<bool, 6, 1> {}; |
| 876 class ResultKindField: public BitField<Kind, 7, 3> {}; | 762 class ResultKindField: public BitField<Kind, 7, 3> {}; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 STRING, | 800 STRING, |
| 915 INTERNALIZED_STRING, | 801 INTERNALIZED_STRING, |
| 916 UNIQUE_NAME, // Symbol or InternalizedString | 802 UNIQUE_NAME, // Symbol or InternalizedString |
| 917 OBJECT, // JSObject | 803 OBJECT, // JSObject |
| 918 KNOWN_OBJECT, // JSObject with specific map (faster check) | 804 KNOWN_OBJECT, // JSObject with specific map (faster check) |
| 919 GENERIC | 805 GENERIC |
| 920 }; | 806 }; |
| 921 | 807 |
| 922 static State NewInputState(State old_state, Handle<Object> value); | 808 static State NewInputState(State old_state, Handle<Object> value); |
| 923 | 809 |
| 924 static Handle<Type> StateToType(Isolate* isolate, | 810 static Type* StateToType(Zone* zone, |
| 925 State state, | 811 State state, |
| 926 Handle<Map> map = Handle<Map>()); | 812 Handle<Map> map = Handle<Map>()); |
| 927 | 813 |
| 928 static void StubInfoToType(int stub_minor_key, | 814 static void StubInfoToType(int stub_minor_key, |
| 929 Handle<Type>* left_type, | 815 Type** left_type, |
| 930 Handle<Type>* right_type, | 816 Type** right_type, |
| 931 Handle<Type>* overall_type, | 817 Type** overall_type, |
| 932 Handle<Map> map, | 818 Handle<Map> map, |
| 933 Isolate* isolate); | 819 Zone* zone); |
| 934 | 820 |
| 935 CompareIC(Isolate* isolate, Token::Value op) | 821 CompareIC(Isolate* isolate, Token::Value op) |
| 936 : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } | 822 : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } |
| 937 | 823 |
| 938 // Update the inline cache for the given operands. | 824 // Update the inline cache for the given operands. |
| 939 Code* UpdateCaches(Handle<Object> x, Handle<Object> y); | 825 Code* UpdateCaches(Handle<Object> x, Handle<Object> y); |
| 940 | 826 |
| 941 | 827 |
| 942 // Factory method for getting an uninitialized compare stub. | 828 // Factory method for getting an uninitialized compare stub. |
| 943 static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op); | 829 static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 | 880 |
| 995 | 881 |
| 996 // Helper for BinaryOpIC and CompareIC. | 882 // Helper for BinaryOpIC and CompareIC. |
| 997 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; | 883 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; |
| 998 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); | 884 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); |
| 999 | 885 |
| 1000 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure); | 886 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure); |
| 1001 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure); | 887 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure); |
| 1002 DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss); | 888 DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss); |
| 1003 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure); | 889 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure); |
| 1004 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure); | |
| 1005 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); | 890 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); |
| 1006 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); | 891 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); |
| 1007 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite); | 892 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite); |
| 1008 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); | 893 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); |
| 1009 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); | 894 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); |
| 1010 | 895 |
| 1011 | 896 |
| 1012 } } // namespace v8::internal | 897 } } // namespace v8::internal |
| 1013 | 898 |
| 1014 #endif // V8_IC_H_ | 899 #endif // V8_IC_H_ |
| OLD | NEW |