| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 ScaleFactor scale; | 67 ScaleFactor scale; |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 // MacroAssembler implements a collection of frequently used macros. | 70 // MacroAssembler implements a collection of frequently used macros. |
| 71 class MacroAssembler: public Assembler { | 71 class MacroAssembler: public Assembler { |
| 72 public: | 72 public: |
| 73 MacroAssembler(void* buffer, int size); | 73 MacroAssembler(void* buffer, int size); |
| 74 | 74 |
| 75 void LoadRoot(Register destination, Heap::RootListIndex index); | 75 void LoadRoot(Register destination, Heap::RootListIndex index); |
| 76 void CompareRoot(Register with, Heap::RootListIndex index); | 76 void CompareRoot(Register with, Heap::RootListIndex index); |
| 77 void CompareRoot(Operand with, Heap::RootListIndex index); | 77 void CompareRoot(const Operand& with, Heap::RootListIndex index); |
| 78 void PushRoot(Heap::RootListIndex index); | 78 void PushRoot(Heap::RootListIndex index); |
| 79 void StoreRoot(Register source, Heap::RootListIndex index); | 79 void StoreRoot(Register source, Heap::RootListIndex index); |
| 80 | 80 |
| 81 // --------------------------------------------------------------------------- | 81 // --------------------------------------------------------------------------- |
| 82 // GC Support | 82 // GC Support |
| 83 | 83 |
| 84 // For page containing |object| mark region covering |addr| dirty. | 84 // For page containing |object| mark region covering |addr| dirty. |
| 85 // RecordWriteHelper only works if the object is not in new | 85 // RecordWriteHelper only works if the object is not in new |
| 86 // space. | 86 // space. |
| 87 void RecordWriteHelper(Register object, | 87 void RecordWriteHelper(Register object, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } | 149 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } |
| 150 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } | 150 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } |
| 151 | 151 |
| 152 // Enter specific kind of exit frame; either in normal or | 152 // Enter specific kind of exit frame; either in normal or |
| 153 // debug mode. Expects the number of arguments in register rax and | 153 // debug mode. Expects the number of arguments in register rax and |
| 154 // sets up the number of arguments in register rdi and the pointer | 154 // sets up the number of arguments in register rdi and the pointer |
| 155 // to the first argument in register rsi. | 155 // to the first argument in register rsi. |
| 156 // | 156 // |
| 157 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack | 157 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack |
| 158 // accessible via StackSpaceOperand. | 158 // accessible via StackSpaceOperand. |
| 159 void EnterExitFrame(int arg_stack_space = 0); | 159 void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false); |
| 160 | 160 |
| 161 // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize | 161 // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize |
| 162 // memory (not GCed) on the stack accessible via StackSpaceOperand. | 162 // memory (not GCed) on the stack accessible via StackSpaceOperand. |
| 163 void EnterApiExitFrame(int arg_stack_space); | 163 void EnterApiExitFrame(int arg_stack_space); |
| 164 | 164 |
| 165 // Leave the current exit frame. Expects/provides the return value in | 165 // Leave the current exit frame. Expects/provides the return value in |
| 166 // register rax:rdx (untouched) and the pointer to the first | 166 // register rax:rdx (untouched) and the pointer to the first |
| 167 // argument in register rsi. | 167 // argument in register rsi. |
| 168 void LeaveExitFrame(); | 168 void LeaveExitFrame(bool save_doubles = false); |
| 169 | 169 |
| 170 // Leave the current exit frame. Expects/provides the return value in | 170 // Leave the current exit frame. Expects/provides the return value in |
| 171 // register rax (untouched). | 171 // register rax (untouched). |
| 172 void LeaveApiExitFrame(); | 172 void LeaveApiExitFrame(); |
| 173 | 173 |
| 174 // Push and pop the registers that can hold pointers. | 174 // Push and pop the registers that can hold pointers. |
| 175 void PushSafepointRegisters() { UNIMPLEMENTED(); } | 175 void PushSafepointRegisters() { Pushad(); } |
| 176 void PopSafepointRegisters() { UNIMPLEMENTED(); } | 176 void PopSafepointRegisters() { Popad(); } |
| 177 static int SafepointRegisterStackIndex(int reg_code) { | 177 static int SafepointRegisterStackIndex(int reg_code) { |
| 178 UNIMPLEMENTED(); | 178 return kNumSafepointRegisters - 1 - |
| 179 return 0; | 179 kSafepointPushRegisterIndices[reg_code]; |
| 180 } | 180 } |
| 181 | 181 |
| 182 |
| 182 // --------------------------------------------------------------------------- | 183 // --------------------------------------------------------------------------- |
| 183 // JavaScript invokes | 184 // JavaScript invokes |
| 184 | 185 |
| 185 // Invoke the JavaScript function code by either calling or jumping. | 186 // Invoke the JavaScript function code by either calling or jumping. |
| 186 void InvokeCode(Register code, | 187 void InvokeCode(Register code, |
| 187 const ParameterCount& expected, | 188 const ParameterCount& expected, |
| 188 const ParameterCount& actual, | 189 const ParameterCount& actual, |
| 189 InvokeFlag flag); | 190 InvokeFlag flag); |
| 190 | 191 |
| 191 void InvokeCode(Handle<Code> code, | 192 void InvokeCode(Handle<Code> code, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 // Compare the int32 in src register to the value of the smi stored at dst. | 270 // Compare the int32 in src register to the value of the smi stored at dst. |
| 270 void SmiCompareInteger32(const Operand& dst, Register src); | 271 void SmiCompareInteger32(const Operand& dst, Register src); |
| 271 // Sets sign and zero flags depending on value of smi in register. | 272 // Sets sign and zero flags depending on value of smi in register. |
| 272 void SmiTest(Register src); | 273 void SmiTest(Register src); |
| 273 | 274 |
| 274 // Functions performing a check on a known or potential smi. Returns | 275 // Functions performing a check on a known or potential smi. Returns |
| 275 // a condition that is satisfied if the check is successful. | 276 // a condition that is satisfied if the check is successful. |
| 276 | 277 |
| 277 // Is the value a tagged smi. | 278 // Is the value a tagged smi. |
| 278 Condition CheckSmi(Register src); | 279 Condition CheckSmi(Register src); |
| 280 Condition CheckSmi(const Operand& src); |
| 279 | 281 |
| 280 // Is the value a non-negative tagged smi. | 282 // Is the value a non-negative tagged smi. |
| 281 Condition CheckNonNegativeSmi(Register src); | 283 Condition CheckNonNegativeSmi(Register src); |
| 282 | 284 |
| 283 // Are both values tagged smis. | 285 // Are both values tagged smis. |
| 284 Condition CheckBothSmi(Register first, Register second); | 286 Condition CheckBothSmi(Register first, Register second); |
| 285 | 287 |
| 286 // Are both values non-negative tagged smis. | 288 // Are both values non-negative tagged smis. |
| 287 Condition CheckBothNonNegativeSmi(Register first, Register second); | 289 Condition CheckBothNonNegativeSmi(Register first, Register second); |
| 288 | 290 |
| 289 // Are either value a tagged smi. | 291 // Are either value a tagged smi. |
| 290 Condition CheckEitherSmi(Register first, | 292 Condition CheckEitherSmi(Register first, |
| 291 Register second, | 293 Register second, |
| 292 Register scratch = kScratchRegister); | 294 Register scratch = kScratchRegister); |
| 293 | 295 |
| 294 // Is the value the minimum smi value (since we are using | 296 // Is the value the minimum smi value (since we are using |
| 295 // two's complement numbers, negating the value is known to yield | 297 // two's complement numbers, negating the value is known to yield |
| 296 // a non-smi value). | 298 // a non-smi value). |
| 297 Condition CheckIsMinSmi(Register src); | 299 Condition CheckIsMinSmi(Register src); |
| 298 | 300 |
| 299 // Checks whether an 32-bit integer value is a valid for conversion | 301 // Checks whether an 32-bit integer value is a valid for conversion |
| 300 // to a smi. | 302 // to a smi. |
| 301 Condition CheckInteger32ValidSmiValue(Register src); | 303 Condition CheckInteger32ValidSmiValue(Register src); |
| 302 | 304 |
| 303 // Checks whether an 32-bit unsigned integer value is a valid for | 305 // Checks whether an 32-bit unsigned integer value is a valid for |
| 304 // conversion to a smi. | 306 // conversion to a smi. |
| 305 Condition CheckUInteger32ValidSmiValue(Register src); | 307 Condition CheckUInteger32ValidSmiValue(Register src); |
| 306 | 308 |
| 309 // Check whether src is a Smi, and set dst to zero if it is a smi, |
| 310 // and to one if it isn't. |
| 311 void CheckSmiToIndicator(Register dst, Register src); |
| 312 void CheckSmiToIndicator(Register dst, const Operand& src); |
| 313 |
| 307 // Test-and-jump functions. Typically combines a check function | 314 // Test-and-jump functions. Typically combines a check function |
| 308 // above with a conditional jump. | 315 // above with a conditional jump. |
| 309 | 316 |
| 310 // Jump if the value cannot be represented by a smi. | 317 // Jump if the value cannot be represented by a smi. |
| 311 template <typename LabelType> | 318 template <typename LabelType> |
| 312 void JumpIfNotValidSmiValue(Register src, LabelType* on_invalid); | 319 void JumpIfNotValidSmiValue(Register src, LabelType* on_invalid); |
| 313 | 320 |
| 314 // Jump if the unsigned integer value cannot be represented by a smi. | 321 // Jump if the unsigned integer value cannot be represented by a smi. |
| 315 template <typename LabelType> | 322 template <typename LabelType> |
| 316 void JumpIfUIntNotValidSmiValue(Register src, LabelType* on_invalid); | 323 void JumpIfUIntNotValidSmiValue(Register src, LabelType* on_invalid); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 void Move(const Operand& dst, Smi* source) { | 538 void Move(const Operand& dst, Smi* source) { |
| 532 Register constant = GetSmiConstant(source); | 539 Register constant = GetSmiConstant(source); |
| 533 movq(dst, constant); | 540 movq(dst, constant); |
| 534 } | 541 } |
| 535 | 542 |
| 536 void Push(Smi* smi); | 543 void Push(Smi* smi); |
| 537 void Test(const Operand& dst, Smi* source); | 544 void Test(const Operand& dst, Smi* source); |
| 538 | 545 |
| 539 // --------------------------------------------------------------------------- | 546 // --------------------------------------------------------------------------- |
| 540 // String macros. | 547 // String macros. |
| 548 |
| 549 // If object is a string, its map is loaded into object_map. |
| 550 template <typename LabelType> |
| 551 void JumpIfNotString(Register object, |
| 552 Register object_map, |
| 553 LabelType* not_string); |
| 554 |
| 555 |
| 541 template <typename LabelType> | 556 template <typename LabelType> |
| 542 void JumpIfNotBothSequentialAsciiStrings(Register first_object, | 557 void JumpIfNotBothSequentialAsciiStrings(Register first_object, |
| 543 Register second_object, | 558 Register second_object, |
| 544 Register scratch1, | 559 Register scratch1, |
| 545 Register scratch2, | 560 Register scratch2, |
| 546 LabelType* on_not_both_flat_ascii); | 561 LabelType* on_not_both_flat_ascii); |
| 547 | 562 |
| 548 // Check whether the instance type represents a flat ascii string. Jump to the | 563 // Check whether the instance type represents a flat ascii string. Jump to the |
| 549 // label if not. If the instance type can be scratched specify same register | 564 // label if not. If the instance type can be scratched specify same register |
| 550 // for both instance type and scratch. | 565 // for both instance type and scratch. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 | 602 |
| 588 // Control Flow | 603 // Control Flow |
| 589 void Jump(Address destination, RelocInfo::Mode rmode); | 604 void Jump(Address destination, RelocInfo::Mode rmode); |
| 590 void Jump(ExternalReference ext); | 605 void Jump(ExternalReference ext); |
| 591 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); | 606 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); |
| 592 | 607 |
| 593 void Call(Address destination, RelocInfo::Mode rmode); | 608 void Call(Address destination, RelocInfo::Mode rmode); |
| 594 void Call(ExternalReference ext); | 609 void Call(ExternalReference ext); |
| 595 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); | 610 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); |
| 596 | 611 |
| 612 // Emit call to the code we are currently generating. |
| 613 void CallSelf() { |
| 614 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); |
| 615 Call(self, RelocInfo::CODE_TARGET); |
| 616 } |
| 617 |
| 618 // Non-x64 instructions. |
| 619 // Push/pop all general purpose registers. |
| 620 // Does not push rsp/rbp nor any of the assembler's special purpose registers |
| 621 // (kScratchRegister, kSmiConstantRegister, kRootRegister). |
| 622 void Pushad(); |
| 623 void Popad(); |
| 624 // Sets the stack as after performing Popad, without actually loading the |
| 625 // registers. |
| 626 void Dropad(); |
| 627 |
| 597 // Compare object type for heap object. | 628 // Compare object type for heap object. |
| 598 // Always use unsigned comparisons: above and below, not less and greater. | 629 // Always use unsigned comparisons: above and below, not less and greater. |
| 599 // Incoming register is heap_object and outgoing register is map. | 630 // Incoming register is heap_object and outgoing register is map. |
| 600 // They may be the same register, and may be kScratchRegister. | 631 // They may be the same register, and may be kScratchRegister. |
| 601 void CmpObjectType(Register heap_object, InstanceType type, Register map); | 632 void CmpObjectType(Register heap_object, InstanceType type, Register map); |
| 602 | 633 |
| 603 // Compare instance type for map. | 634 // Compare instance type for map. |
| 604 // Always use unsigned comparisons: above and below, not less and greater. | 635 // Always use unsigned comparisons: above and below, not less and greater. |
| 605 void CmpInstanceType(Register map, InstanceType type); | 636 void CmpInstanceType(Register map, InstanceType type); |
| 606 | 637 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 628 | 659 |
| 629 // Abort execution if argument is not a number. Used in debug code. | 660 // Abort execution if argument is not a number. Used in debug code. |
| 630 void AbortIfNotNumber(Register object); | 661 void AbortIfNotNumber(Register object); |
| 631 | 662 |
| 632 // Abort execution if argument is a smi. Used in debug code. | 663 // Abort execution if argument is a smi. Used in debug code. |
| 633 void AbortIfSmi(Register object); | 664 void AbortIfSmi(Register object); |
| 634 | 665 |
| 635 // Abort execution if argument is not a smi. Used in debug code. | 666 // Abort execution if argument is not a smi. Used in debug code. |
| 636 void AbortIfNotSmi(Register object); | 667 void AbortIfNotSmi(Register object); |
| 637 | 668 |
| 669 // Abort execution if argument is a string. Used in debug code. |
| 670 void AbortIfNotString(Register object); |
| 671 |
| 638 // Abort execution if argument is not the root value with the given index. | 672 // Abort execution if argument is not the root value with the given index. |
| 639 void AbortIfNotRootValue(Register src, | 673 void AbortIfNotRootValue(Register src, |
| 640 Heap::RootListIndex root_value_index, | 674 Heap::RootListIndex root_value_index, |
| 641 const char* message); | 675 const char* message); |
| 642 | 676 |
| 643 // --------------------------------------------------------------------------- | 677 // --------------------------------------------------------------------------- |
| 644 // Exception handling | 678 // Exception handling |
| 645 | 679 |
| 646 // Push a new try handler and link into try handler chain. The return | 680 // Push a new try handler and link into try handler chain. The return |
| 647 // address must be pushed before calling this helper. | 681 // address must be pushed before calling this helper. |
| 648 void PushTryHandler(CodeLocation try_location, HandlerType type); | 682 void PushTryHandler(CodeLocation try_location, HandlerType type); |
| 649 | 683 |
| 650 // Unlink the stack handler on top of the stack from the try handler chain. | 684 // Unlink the stack handler on top of the stack from the try handler chain. |
| 651 void PopTryHandler(); | 685 void PopTryHandler(); |
| 652 | 686 |
| 687 // Activate the top handler in the try hander chain and pass the |
| 688 // thrown value. |
| 689 void Throw(Register value); |
| 690 |
| 691 // Propagate an uncatchable exception out of the current JS stack. |
| 692 void ThrowUncatchable(UncatchableExceptionType type, Register value); |
| 693 |
| 653 // --------------------------------------------------------------------------- | 694 // --------------------------------------------------------------------------- |
| 654 // Inline caching support | 695 // Inline caching support |
| 655 | 696 |
| 656 // Generate code for checking access rights - used for security checks | 697 // Generate code for checking access rights - used for security checks |
| 657 // on access to global objects across environments. The holder register | 698 // on access to global objects across environments. The holder register |
| 658 // is left untouched, but the scratch register and kScratchRegister, | 699 // is left untouched, but the scratch register and kScratchRegister, |
| 659 // which must be different, are clobbered. | 700 // which must be different, are clobbered. |
| 660 void CheckAccessGlobalProxy(Register holder_reg, | 701 void CheckAccessGlobalProxy(Register holder_reg, |
| 661 Register scratch, | 702 Register scratch, |
| 662 Label* miss); | 703 Label* miss); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 // generate the code if necessary. Do not perform a GC but instead return | 842 // generate the code if necessary. Do not perform a GC but instead return |
| 802 // a retry after GC failure. | 843 // a retry after GC failure. |
| 803 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub); | 844 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub); |
| 804 | 845 |
| 805 // Return from a code stub after popping its arguments. | 846 // Return from a code stub after popping its arguments. |
| 806 void StubReturn(int argc); | 847 void StubReturn(int argc); |
| 807 | 848 |
| 808 // Call a runtime routine. | 849 // Call a runtime routine. |
| 809 void CallRuntime(Runtime::Function* f, int num_arguments); | 850 void CallRuntime(Runtime::Function* f, int num_arguments); |
| 810 | 851 |
| 852 // Call a runtime function and save the value of XMM registers. |
| 853 void CallRuntimeSaveDoubles(Runtime::FunctionId id); |
| 854 |
| 811 // Call a runtime function, returning the CodeStub object called. | 855 // Call a runtime function, returning the CodeStub object called. |
| 812 // Try to generate the stub code if necessary. Do not perform a GC | 856 // Try to generate the stub code if necessary. Do not perform a GC |
| 813 // but instead return a retry after GC failure. | 857 // but instead return a retry after GC failure. |
| 814 MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f, | 858 MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f, |
| 815 int num_arguments); | 859 int num_arguments); |
| 816 | 860 |
| 817 // Convenience function: Same as above, but takes the fid instead. | 861 // Convenience function: Same as above, but takes the fid instead. |
| 818 void CallRuntime(Runtime::FunctionId id, int num_arguments); | 862 void CallRuntime(Runtime::FunctionId id, int num_arguments); |
| 819 | 863 |
| 820 // Convenience function: Same as above, but takes the fid instead. | 864 // Convenience function: Same as above, but takes the fid instead. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 | 928 |
| 885 // Calculate the number of stack slots to reserve for arguments when calling a | 929 // Calculate the number of stack slots to reserve for arguments when calling a |
| 886 // C function. | 930 // C function. |
| 887 int ArgumentStackSlotsForCFunctionCall(int num_arguments); | 931 int ArgumentStackSlotsForCFunctionCall(int num_arguments); |
| 888 | 932 |
| 889 // --------------------------------------------------------------------------- | 933 // --------------------------------------------------------------------------- |
| 890 // Utilities | 934 // Utilities |
| 891 | 935 |
| 892 void Ret(); | 936 void Ret(); |
| 893 | 937 |
| 938 // Return and drop arguments from stack, where the number of arguments |
| 939 // may be bigger than 2^16 - 1. Requires a scratch register. |
| 940 void Ret(int bytes_dropped, Register scratch); |
| 941 |
| 894 Handle<Object> CodeObject() { return code_object_; } | 942 Handle<Object> CodeObject() { return code_object_; } |
| 895 | 943 |
| 896 | 944 |
| 897 // --------------------------------------------------------------------------- | 945 // --------------------------------------------------------------------------- |
| 898 // StatsCounter support | 946 // StatsCounter support |
| 899 | 947 |
| 900 void SetCounter(StatsCounter* counter, int value); | 948 void SetCounter(StatsCounter* counter, int value); |
| 901 void IncrementCounter(StatsCounter* counter, int value); | 949 void IncrementCounter(StatsCounter* counter, int value); |
| 902 void DecrementCounter(StatsCounter* counter, int value); | 950 void DecrementCounter(StatsCounter* counter, int value); |
| 903 | 951 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 920 // Check that the stack is aligned. | 968 // Check that the stack is aligned. |
| 921 void CheckStackAlignment(); | 969 void CheckStackAlignment(); |
| 922 | 970 |
| 923 // Verify restrictions about code generated in stubs. | 971 // Verify restrictions about code generated in stubs. |
| 924 void set_generating_stub(bool value) { generating_stub_ = value; } | 972 void set_generating_stub(bool value) { generating_stub_ = value; } |
| 925 bool generating_stub() { return generating_stub_; } | 973 bool generating_stub() { return generating_stub_; } |
| 926 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } | 974 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } |
| 927 bool allow_stub_calls() { return allow_stub_calls_; } | 975 bool allow_stub_calls() { return allow_stub_calls_; } |
| 928 | 976 |
| 929 private: | 977 private: |
| 978 // Order general registers are pushed by Pushad. |
| 979 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14. |
| 980 static int kSafepointPushRegisterIndices[Register::kNumRegisters]; |
| 981 static const int kNumSafepointSavedRegisters = 11; |
| 982 |
| 930 bool generating_stub_; | 983 bool generating_stub_; |
| 931 bool allow_stub_calls_; | 984 bool allow_stub_calls_; |
| 932 | 985 |
| 933 // Returns a register holding the smi value. The register MUST NOT be | 986 // Returns a register holding the smi value. The register MUST NOT be |
| 934 // modified. It may be the "smi 1 constant" register. | 987 // modified. It may be the "smi 1 constant" register. |
| 935 Register GetSmiConstant(Smi* value); | 988 Register GetSmiConstant(Smi* value); |
| 936 | 989 |
| 937 // Moves the smi value to the destination register. | 990 // Moves the smi value to the destination register. |
| 938 void LoadSmiConstant(Register dst, Smi* value); | 991 void LoadSmiConstant(Register dst, Smi* value); |
| 939 | 992 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 950 InvokeFlag flag); | 1003 InvokeFlag flag); |
| 951 | 1004 |
| 952 // Activation support. | 1005 // Activation support. |
| 953 void EnterFrame(StackFrame::Type type); | 1006 void EnterFrame(StackFrame::Type type); |
| 954 void LeaveFrame(StackFrame::Type type); | 1007 void LeaveFrame(StackFrame::Type type); |
| 955 | 1008 |
| 956 void EnterExitFramePrologue(bool save_rax); | 1009 void EnterExitFramePrologue(bool save_rax); |
| 957 | 1010 |
| 958 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack | 1011 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack |
| 959 // accessible via StackSpaceOperand. | 1012 // accessible via StackSpaceOperand. |
| 960 void EnterExitFrameEpilogue(int arg_stack_space); | 1013 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); |
| 961 | 1014 |
| 962 void LeaveExitFrameEpilogue(); | 1015 void LeaveExitFrameEpilogue(); |
| 963 | 1016 |
| 964 // Allocation support helpers. | 1017 // Allocation support helpers. |
| 965 // Loads the top of new-space into the result register. | 1018 // Loads the top of new-space into the result register. |
| 966 // Otherwise the address of the new-space top is loaded into scratch (if | 1019 // Otherwise the address of the new-space top is loaded into scratch (if |
| 967 // scratch is valid), and the new-space top is loaded into result. | 1020 // scratch is valid), and the new-space top is loaded into result. |
| 968 void LoadAllocationTopHelper(Register result, | 1021 void LoadAllocationTopHelper(Register result, |
| 969 Register scratch, | 1022 Register scratch, |
| 970 AllocationFlags flags); | 1023 AllocationFlags flags); |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 | 1486 |
| 1434 template <typename LabelType> | 1487 template <typename LabelType> |
| 1435 void MacroAssembler::SmiShiftLogicalRight(Register dst, | 1488 void MacroAssembler::SmiShiftLogicalRight(Register dst, |
| 1436 Register src1, | 1489 Register src1, |
| 1437 Register src2, | 1490 Register src2, |
| 1438 LabelType* on_not_smi_result) { | 1491 LabelType* on_not_smi_result) { |
| 1439 ASSERT(!dst.is(kScratchRegister)); | 1492 ASSERT(!dst.is(kScratchRegister)); |
| 1440 ASSERT(!src1.is(kScratchRegister)); | 1493 ASSERT(!src1.is(kScratchRegister)); |
| 1441 ASSERT(!src2.is(kScratchRegister)); | 1494 ASSERT(!src2.is(kScratchRegister)); |
| 1442 ASSERT(!dst.is(rcx)); | 1495 ASSERT(!dst.is(rcx)); |
| 1496 // dst and src1 can be the same, because the one case that bails out |
| 1497 // is a shift by 0, which leaves dst, and therefore src1, unchanged. |
| 1443 NearLabel result_ok; | 1498 NearLabel result_ok; |
| 1444 if (src1.is(rcx) || src2.is(rcx)) { | 1499 if (src1.is(rcx) || src2.is(rcx)) { |
| 1445 movq(kScratchRegister, rcx); | 1500 movq(kScratchRegister, rcx); |
| 1446 } | 1501 } |
| 1447 if (!dst.is(src1)) { | 1502 if (!dst.is(src1)) { |
| 1448 movq(dst, src1); | 1503 movq(dst, src1); |
| 1449 } | 1504 } |
| 1450 SmiToInteger32(rcx, src2); | 1505 SmiToInteger32(rcx, src2); |
| 1451 orl(rcx, Immediate(kSmiShift)); | 1506 orl(rcx, Immediate(kSmiShift)); |
| 1452 shr_cl(dst); // Shift is rcx modulo 0x1f + 32. | 1507 shr_cl(dst); // Shift is rcx modulo 0x1f + 32. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 template <typename LabelType> | 1622 template <typename LabelType> |
| 1568 void MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, | 1623 void MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, |
| 1569 Register src2, | 1624 Register src2, |
| 1570 LabelType* on_not_both_smi) { | 1625 LabelType* on_not_both_smi) { |
| 1571 Condition both_smi = CheckBothNonNegativeSmi(src1, src2); | 1626 Condition both_smi = CheckBothNonNegativeSmi(src1, src2); |
| 1572 j(NegateCondition(both_smi), on_not_both_smi); | 1627 j(NegateCondition(both_smi), on_not_both_smi); |
| 1573 } | 1628 } |
| 1574 | 1629 |
| 1575 | 1630 |
| 1576 template <typename LabelType> | 1631 template <typename LabelType> |
| 1632 void MacroAssembler::JumpIfNotString(Register object, |
| 1633 Register object_map, |
| 1634 LabelType* not_string) { |
| 1635 Condition is_smi = CheckSmi(object); |
| 1636 j(is_smi, not_string); |
| 1637 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); |
| 1638 j(above_equal, not_string); |
| 1639 } |
| 1640 |
| 1641 |
| 1642 template <typename LabelType> |
| 1577 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first_object, | 1643 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first_object, |
| 1578 Register second_object, | 1644 Register second_object, |
| 1579 Register scratch1, | 1645 Register scratch1, |
| 1580 Register scratch2, | 1646 Register scratch2, |
| 1581 LabelType* on_fail) { | 1647 LabelType* on_fail) { |
| 1582 // Check that both objects are not smis. | 1648 // Check that both objects are not smis. |
| 1583 Condition either_smi = CheckEitherSmi(first_object, second_object); | 1649 Condition either_smi = CheckEitherSmi(first_object, second_object); |
| 1584 j(either_smi, on_fail); | 1650 j(either_smi, on_fail); |
| 1585 | 1651 |
| 1586 // Load instance type for both strings. | 1652 // Load instance type for both strings. |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1750 Jump(adaptor, RelocInfo::CODE_TARGET); | 1816 Jump(adaptor, RelocInfo::CODE_TARGET); |
| 1751 } | 1817 } |
| 1752 bind(&invoke); | 1818 bind(&invoke); |
| 1753 } | 1819 } |
| 1754 } | 1820 } |
| 1755 | 1821 |
| 1756 | 1822 |
| 1757 } } // namespace v8::internal | 1823 } } // namespace v8::internal |
| 1758 | 1824 |
| 1759 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ | 1825 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ |
| OLD | NEW |