| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 Address pc() const { return *pc_address_; } | 148 Address pc() const { return *pc_address_; } |
| 149 Isolate* isolate() const { return isolate_; } | 149 Isolate* isolate() const { return isolate_; } |
| 150 | 150 |
| 151 #ifdef ENABLE_DEBUGGER_SUPPORT | 151 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 152 // Computes the address in the original code when the code running is | 152 // Computes the address in the original code when the code running is |
| 153 // containing break points (calls to DebugBreakXXX builtins). | 153 // containing break points (calls to DebugBreakXXX builtins). |
| 154 Address OriginalCodeAddress() const; | 154 Address OriginalCodeAddress() const; |
| 155 #endif | 155 #endif |
| 156 | 156 |
| 157 // Set the call-site target. | 157 // Set the call-site target. |
| 158 void set_target(Code* code) { SetTargetAtAddress(address(), code); } | 158 void set_target(Code* code) { |
| 159 SetTargetAtAddress(address(), code); |
| 160 target_set_ = true; |
| 161 } |
| 162 |
| 163 bool is_target_set() { return target_set_; } |
| 159 | 164 |
| 160 #ifdef DEBUG | 165 #ifdef DEBUG |
| 161 char TransitionMarkFromState(IC::State state); | 166 char TransitionMarkFromState(IC::State state); |
| 162 | 167 |
| 163 void TraceIC(const char* type, Handle<Object> name); | 168 void TraceIC(const char* type, Handle<Object> name); |
| 164 #endif | 169 #endif |
| 165 | 170 |
| 166 Failure* TypeError(const char* type, | 171 Failure* TypeError(const char* type, |
| 167 Handle<Object> object, | 172 Handle<Object> object, |
| 168 Handle<Object> key); | 173 Handle<Object> key); |
| 169 Failure* ReferenceError(const char* type, Handle<String> name); | 174 Failure* ReferenceError(const char* type, Handle<String> name); |
| 170 | 175 |
| 171 // Access the target code for the given IC address. | 176 // Access the target code for the given IC address. |
| 172 static inline Code* GetTargetAtAddress(Address address); | 177 static inline Code* GetTargetAtAddress(Address address); |
| 173 static inline void SetTargetAtAddress(Address address, Code* target); | 178 static inline void SetTargetAtAddress(Address address, Code* target); |
| 174 static void PostPatching(Address address, Code* target, Code* old_target); | 179 static void PostPatching(Address address, Code* target, Code* old_target); |
| 175 | 180 |
| 181 // Compute the handler either by compiling or by retrieving a cached version. |
| 182 Handle<Code> ComputeHandler(LookupResult* lookup, |
| 183 Handle<JSObject> receiver, |
| 184 Handle<String> name, |
| 185 Handle<Object> value = Handle<Code>::null()); |
| 186 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
| 187 Handle<JSObject> receiver, |
| 188 Handle<String> name, |
| 189 Handle<Object> value) { |
| 190 UNREACHABLE(); |
| 191 return Handle<Code>::null(); |
| 192 } |
| 176 void UpdateMonomorphicIC(Handle<HeapObject> receiver, | 193 void UpdateMonomorphicIC(Handle<HeapObject> receiver, |
| 177 Handle<Code> handler, | 194 Handle<Code> handler, |
| 178 Handle<String> name); | 195 Handle<String> name); |
| 179 | 196 |
| 180 bool UpdatePolymorphicIC(Handle<HeapObject> receiver, | 197 bool UpdatePolymorphicIC(Handle<HeapObject> receiver, |
| 181 Handle<String> name, | 198 Handle<String> name, |
| 182 Handle<Code> code); | 199 Handle<Code> code); |
| 183 | 200 |
| 184 void CopyICToMegamorphicCache(Handle<String> name); | 201 void CopyICToMegamorphicCache(Handle<String> name); |
| 185 bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map); | 202 bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map); |
| 186 void PatchCache(Handle<HeapObject> receiver, | 203 void PatchCache(Handle<HeapObject> receiver, |
| 187 Handle<String> name, | 204 Handle<String> name, |
| 188 Handle<Code> code); | 205 Handle<Code> code); |
| 189 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code); | 206 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code); |
| 207 virtual Code::Kind kind() const { |
| 208 UNREACHABLE(); |
| 209 return Code::STUB; |
| 210 } |
| 211 virtual Handle<Code> slow_stub() const { |
| 212 UNREACHABLE(); |
| 213 return Handle<Code>::null(); |
| 214 } |
| 190 virtual Handle<Code> megamorphic_stub() { | 215 virtual Handle<Code> megamorphic_stub() { |
| 191 UNREACHABLE(); | 216 UNREACHABLE(); |
| 192 return Handle<Code>::null(); | 217 return Handle<Code>::null(); |
| 193 } | 218 } |
| 194 virtual Handle<Code> generic_stub() const { | 219 virtual Handle<Code> generic_stub() const { |
| 195 UNREACHABLE(); | 220 UNREACHABLE(); |
| 196 return Handle<Code>::null(); | 221 return Handle<Code>::null(); |
| 197 } | 222 } |
| 198 virtual StrictModeFlag strict_mode() const { return kNonStrictMode; } | 223 virtual StrictModeFlag strict_mode() const { return kNonStrictMode; } |
| 199 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, | 224 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
| 200 Handle<String> name); | 225 Handle<String> name); |
| 226 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name); |
| 201 | 227 |
| 202 private: | 228 private: |
| 203 // Frame pointer for the frame that uses (calls) the IC. | 229 // Frame pointer for the frame that uses (calls) the IC. |
| 204 Address fp_; | 230 Address fp_; |
| 205 | 231 |
| 206 // All access to the program counter of an IC structure is indirect | 232 // All access to the program counter of an IC structure is indirect |
| 207 // to make the code GC safe. This feature is crucial since | 233 // to make the code GC safe. This feature is crucial since |
| 208 // GetProperty and SetProperty are called and they in turn might | 234 // GetProperty and SetProperty are called and they in turn might |
| 209 // invoke the garbage collector. | 235 // invoke the garbage collector. |
| 210 Address* pc_address_; | 236 Address* pc_address_; |
| 211 | 237 |
| 212 Isolate* isolate_; | 238 Isolate* isolate_; |
| 213 | 239 |
| 214 // The original code target that missed. | 240 // The original code target that missed. |
| 215 Handle<Code> target_; | 241 Handle<Code> target_; |
| 216 State state_; | 242 State state_; |
| 243 bool target_set_; |
| 217 | 244 |
| 218 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); | 245 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
| 219 }; | 246 }; |
| 220 | 247 |
| 221 | 248 |
| 222 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you | 249 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you |
| 223 // cannot make forward declarations to an enum. | 250 // cannot make forward declarations to an enum. |
| 224 class IC_Utility { | 251 class IC_Utility { |
| 225 public: | 252 public: |
| 226 explicit IC_Utility(IC::UtilityId id) | 253 explicit IC_Utility(IC::UtilityId id) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 virtual Handle<Code> megamorphic_stub() { | 414 virtual Handle<Code> megamorphic_stub() { |
| 388 return isolate()->builtins()->LoadIC_Megamorphic(); | 415 return isolate()->builtins()->LoadIC_Megamorphic(); |
| 389 } | 416 } |
| 390 | 417 |
| 391 // Update the inline cache and the global stub cache based on the | 418 // Update the inline cache and the global stub cache based on the |
| 392 // lookup result. | 419 // lookup result. |
| 393 void UpdateCaches(LookupResult* lookup, | 420 void UpdateCaches(LookupResult* lookup, |
| 394 Handle<Object> object, | 421 Handle<Object> object, |
| 395 Handle<String> name); | 422 Handle<String> name); |
| 396 | 423 |
| 397 virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup, | 424 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
| 398 Handle<JSObject> receiver, | 425 Handle<JSObject> receiver, |
| 399 Handle<String> name); | 426 Handle<String> name, |
| 427 Handle<Object> unused); |
| 400 | 428 |
| 401 private: | 429 private: |
| 402 // Stub accessors. | 430 // Stub accessors. |
| 403 static Handle<Code> initialize_stub(Isolate* isolate) { | 431 static Handle<Code> initialize_stub(Isolate* isolate) { |
| 404 return isolate->builtins()->LoadIC_Initialize(); | 432 return isolate->builtins()->LoadIC_Initialize(); |
| 405 } | 433 } |
| 406 | 434 |
| 407 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { | 435 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { |
| 408 return isolate->builtins()->LoadIC_PreMonomorphic(); | 436 return isolate->builtins()->LoadIC_PreMonomorphic(); |
| 409 } | 437 } |
| 410 | 438 |
| 411 virtual Handle<Code> pre_monomorphic_stub() { | 439 virtual Handle<Code> pre_monomorphic_stub() { |
| 412 return pre_monomorphic_stub(isolate()); | 440 return pre_monomorphic_stub(isolate()); |
| 413 } | 441 } |
| 414 | 442 |
| 443 Handle<Code> SimpleFieldLoad(int offset, |
| 444 bool inobject = true, |
| 445 Representation representation = |
| 446 Representation::Tagged()); |
| 447 |
| 415 static void Clear(Isolate* isolate, Address address, Code* target); | 448 static void Clear(Isolate* isolate, Address address, Code* target); |
| 416 | 449 |
| 417 friend class IC; | 450 friend class IC; |
| 418 }; | 451 }; |
| 419 | 452 |
| 420 | 453 |
| 421 enum ICMissMode { | 454 enum ICMissMode { |
| 422 MISS_FORCE_GENERIC, | 455 MISS_FORCE_GENERIC, |
| 423 MISS | 456 MISS |
| 424 }; | 457 }; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 virtual Handle<Code> megamorphic_stub() { | 497 virtual Handle<Code> megamorphic_stub() { |
| 465 return isolate()->builtins()->KeyedLoadIC_Generic(); | 498 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 466 } | 499 } |
| 467 virtual Handle<Code> generic_stub() const { | 500 virtual Handle<Code> generic_stub() const { |
| 468 return isolate()->builtins()->KeyedLoadIC_Generic(); | 501 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 469 } | 502 } |
| 470 virtual Handle<Code> slow_stub() const { | 503 virtual Handle<Code> slow_stub() const { |
| 471 return isolate()->builtins()->KeyedLoadIC_Slow(); | 504 return isolate()->builtins()->KeyedLoadIC_Slow(); |
| 472 } | 505 } |
| 473 | 506 |
| 474 // Update the inline cache. | |
| 475 virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup, | |
| 476 Handle<JSObject> receiver, | |
| 477 Handle<String> name); | |
| 478 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } | 507 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } |
| 479 | 508 |
| 480 private: | 509 private: |
| 481 // Stub accessors. | 510 // Stub accessors. |
| 482 static Handle<Code> initialize_stub(Isolate* isolate) { | 511 static Handle<Code> initialize_stub(Isolate* isolate) { |
| 483 return isolate->builtins()->KeyedLoadIC_Initialize(); | 512 return isolate->builtins()->KeyedLoadIC_Initialize(); |
| 484 } | 513 } |
| 485 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { | 514 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { |
| 486 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); | 515 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); |
| 487 } | 516 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 } | 574 } |
| 546 // Stub accessors. | 575 // Stub accessors. |
| 547 virtual Handle<Code> generic_stub() const { | 576 virtual Handle<Code> generic_stub() const { |
| 548 if (strict_mode() == kStrictMode) { | 577 if (strict_mode() == kStrictMode) { |
| 549 return isolate()->builtins()->StoreIC_Generic_Strict(); | 578 return isolate()->builtins()->StoreIC_Generic_Strict(); |
| 550 } else { | 579 } else { |
| 551 return isolate()->builtins()->StoreIC_Generic(); | 580 return isolate()->builtins()->StoreIC_Generic(); |
| 552 } | 581 } |
| 553 } | 582 } |
| 554 | 583 |
| 584 virtual Handle<Code> slow_stub() const { |
| 585 if (strict_mode() == kStrictMode) { |
| 586 return isolate()->builtins()->StoreIC_Slow_Strict(); |
| 587 } else { |
| 588 return isolate()->builtins()->StoreIC_Slow(); |
| 589 } |
| 590 } |
| 591 |
| 555 virtual Handle<Code> pre_monomorphic_stub() { | 592 virtual Handle<Code> pre_monomorphic_stub() { |
| 556 return pre_monomorphic_stub(isolate(), strict_mode()); | 593 return pre_monomorphic_stub(isolate(), strict_mode()); |
| 557 } | 594 } |
| 558 | 595 |
| 559 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, | 596 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, |
| 560 StrictModeFlag strict_mode) { | 597 StrictModeFlag strict_mode) { |
| 561 if (strict_mode == kStrictMode) { | 598 if (strict_mode == kStrictMode) { |
| 562 return isolate->builtins()->StoreIC_PreMonomorphic_Strict(); | 599 return isolate->builtins()->StoreIC_PreMonomorphic_Strict(); |
| 563 } else { | 600 } else { |
| 564 return isolate->builtins()->StoreIC_PreMonomorphic(); | 601 return isolate->builtins()->StoreIC_PreMonomorphic(); |
| 565 } | 602 } |
| 566 } | 603 } |
| 567 | 604 |
| 568 virtual Handle<Code> global_proxy_stub() { | 605 virtual Handle<Code> global_proxy_stub() { |
| 569 if (strict_mode() == kStrictMode) { | 606 if (strict_mode() == kStrictMode) { |
| 570 return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); | 607 return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); |
| 571 } else { | 608 } else { |
| 572 return isolate()->builtins()->StoreIC_GlobalProxy(); | 609 return isolate()->builtins()->StoreIC_GlobalProxy(); |
| 573 } | 610 } |
| 574 } | 611 } |
| 575 | 612 |
| 576 // Update the inline cache and the global stub cache based on the | 613 // Update the inline cache and the global stub cache based on the |
| 577 // lookup result. | 614 // lookup result. |
| 578 void UpdateCaches(LookupResult* lookup, | 615 void UpdateCaches(LookupResult* lookup, |
| 579 Handle<JSObject> receiver, | 616 Handle<JSObject> receiver, |
| 580 Handle<String> name, | 617 Handle<String> name, |
| 581 Handle<Object> value); | 618 Handle<Object> value); |
| 582 // Compute the code stub for this store; used for rewriting to | 619 virtual Handle<Code> CompileHandler(LookupResult* lookup, |
| 583 // monomorphic state and making sure that the code stub is in the | 620 Handle<JSObject> receiver, |
| 584 // stub cache. | 621 Handle<String> name, |
| 585 virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup, | 622 Handle<Object> value); |
| 586 Handle<JSObject> receiver, | |
| 587 Handle<String> name, | |
| 588 Handle<Object> value); | |
| 589 | 623 |
| 590 private: | 624 private: |
| 591 void set_target(Code* code) { | 625 void set_target(Code* code) { |
| 592 // Strict mode must be preserved across IC patching. | 626 // Strict mode must be preserved across IC patching. |
| 593 ASSERT(Code::GetStrictMode(code->extra_ic_state()) == | 627 ASSERT(Code::GetStrictMode(code->extra_ic_state()) == |
| 594 Code::GetStrictMode(target()->extra_ic_state())); | 628 Code::GetStrictMode(target()->extra_ic_state())); |
| 595 IC::set_target(code); | 629 IC::set_target(code); |
| 596 } | 630 } |
| 597 | 631 |
| 598 static Handle<Code> initialize_stub(Isolate* isolate, | 632 static Handle<Code> initialize_stub(Isolate* isolate, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic); | 680 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic); |
| 647 static void GenerateSlow(MacroAssembler* masm); | 681 static void GenerateSlow(MacroAssembler* masm); |
| 648 static void GenerateRuntimeSetProperty(MacroAssembler* masm, | 682 static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 649 StrictModeFlag strict_mode); | 683 StrictModeFlag strict_mode); |
| 650 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); | 684 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); |
| 651 static void GenerateNonStrictArguments(MacroAssembler* masm); | 685 static void GenerateNonStrictArguments(MacroAssembler* masm); |
| 652 | 686 |
| 653 protected: | 687 protected: |
| 654 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } | 688 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } |
| 655 | 689 |
| 656 virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup, | |
| 657 Handle<JSObject> receiver, | |
| 658 Handle<String> name, | |
| 659 Handle<Object> value); | |
| 660 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } | 690 virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } |
| 661 | 691 |
| 662 virtual Handle<Code> pre_monomorphic_stub() { | 692 virtual Handle<Code> pre_monomorphic_stub() { |
| 663 return pre_monomorphic_stub(isolate(), strict_mode()); | 693 return pre_monomorphic_stub(isolate(), strict_mode()); |
| 664 } | 694 } |
| 665 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, | 695 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, |
| 666 StrictModeFlag strict_mode) { | 696 StrictModeFlag strict_mode) { |
| 667 if (strict_mode == kStrictMode) { | 697 if (strict_mode == kStrictMode) { |
| 668 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); | 698 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); |
| 669 } else { | 699 } else { |
| 670 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); | 700 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); |
| 671 } | 701 } |
| 672 } | 702 } |
| 703 virtual Handle<Code> slow_stub() const { |
| 704 if (strict_mode() == kStrictMode) { |
| 705 return isolate()->builtins()->KeyedStoreIC_Slow_Strict(); |
| 706 } else { |
| 707 return isolate()->builtins()->KeyedStoreIC_Slow(); |
| 708 } |
| 709 } |
| 673 virtual Handle<Code> megamorphic_stub() { | 710 virtual Handle<Code> megamorphic_stub() { |
| 674 if (strict_mode() == kStrictMode) { | 711 if (strict_mode() == kStrictMode) { |
| 675 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); | 712 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); |
| 676 } else { | 713 } else { |
| 677 return isolate()->builtins()->KeyedStoreIC_Generic(); | 714 return isolate()->builtins()->KeyedStoreIC_Generic(); |
| 678 } | 715 } |
| 679 } | 716 } |
| 680 | 717 |
| 681 Handle<Code> StoreElementStub(Handle<JSObject> receiver, | 718 Handle<Code> StoreElementStub(Handle<JSObject> receiver, |
| 682 KeyedAccessStoreMode store_mode); | 719 KeyedAccessStoreMode store_mode); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure); | 888 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure); |
| 852 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); | 889 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); |
| 853 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); | 890 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); |
| 854 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); | 891 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); |
| 855 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); | 892 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); |
| 856 | 893 |
| 857 | 894 |
| 858 } } // namespace v8::internal | 895 } } // namespace v8::internal |
| 859 | 896 |
| 860 #endif // V8_IC_H_ | 897 #endif // V8_IC_H_ |
| OLD | NEW |