| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 // Actual value of root register is offset from the root array's start | 46 // Actual value of root register is offset from the root array's start |
| 47 // to take advantage of negitive 8-bit displacement values. | 47 // to take advantage of negitive 8-bit displacement values. |
| 48 const int kRootRegisterBias = 128; | 48 const int kRootRegisterBias = 128; |
| 49 | 49 |
| 50 // Convenience for platform-independent signatures. | 50 // Convenience for platform-independent signatures. |
| 51 typedef Operand MemOperand; | 51 typedef Operand MemOperand; |
| 52 | 52 |
| 53 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; | 53 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; |
| 54 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; | 54 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; |
| 55 | 55 |
| 56 enum SmiOperationConstraint { |
| 57 PRESERVE_SOURCE_REGISTER, |
| 58 BAILOUT_ON_NO_OVERFLOW, |
| 59 BAILOUT_ON_OVERFLOW, |
| 60 NUMBER_OF_CONSTRAINTS |
| 61 }; |
| 62 |
| 63 STATIC_ASSERT(NUMBER_OF_CONSTRAINTS <= 8); |
| 64 |
| 65 class SmiOperationExecutionMode : public EnumSet<SmiOperationConstraint, byte> { |
| 66 public: |
| 67 SmiOperationExecutionMode() : EnumSet<SmiOperationConstraint, byte>(0) { } |
| 68 explicit SmiOperationExecutionMode(byte bits) |
| 69 : EnumSet<SmiOperationConstraint, byte>(bits) { } |
| 70 }; |
| 71 |
| 56 bool AreAliased(Register r1, Register r2, Register r3, Register r4); | 72 bool AreAliased(Register r1, Register r2, Register r3, Register r4); |
| 57 | 73 |
| 58 // Forward declaration. | 74 // Forward declaration. |
| 59 class JumpTarget; | 75 class JumpTarget; |
| 60 | 76 |
| 61 struct SmiIndex { | 77 struct SmiIndex { |
| 62 SmiIndex(Register index_register, ScaleFactor scale) | 78 SmiIndex(Register index_register, ScaleFactor scale) |
| 63 : reg(index_register), | 79 : reg(index_register), |
| 64 scale(scale) {} | 80 scale(scale) {} |
| 65 Register reg; | 81 Register reg; |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 void PopSafepointRegisters() { Popad(); } | 328 void PopSafepointRegisters() { Popad(); } |
| 313 // Store the value in register src in the safepoint register stack | 329 // Store the value in register src in the safepoint register stack |
| 314 // slot for register dst. | 330 // slot for register dst. |
| 315 void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm); | 331 void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm); |
| 316 void StoreToSafepointRegisterSlot(Register dst, Register src); | 332 void StoreToSafepointRegisterSlot(Register dst, Register src); |
| 317 void LoadFromSafepointRegisterSlot(Register dst, Register src); | 333 void LoadFromSafepointRegisterSlot(Register dst, Register src); |
| 318 | 334 |
| 319 void InitializeRootRegister() { | 335 void InitializeRootRegister() { |
| 320 ExternalReference roots_array_start = | 336 ExternalReference roots_array_start = |
| 321 ExternalReference::roots_array_start(isolate()); | 337 ExternalReference::roots_array_start(isolate()); |
| 322 movq(kRootRegister, roots_array_start); | 338 Move(kRootRegister, roots_array_start); |
| 323 addq(kRootRegister, Immediate(kRootRegisterBias)); | 339 addq(kRootRegister, Immediate(kRootRegisterBias)); |
| 324 } | 340 } |
| 325 | 341 |
| 326 // --------------------------------------------------------------------------- | 342 // --------------------------------------------------------------------------- |
| 327 // JavaScript invokes | 343 // JavaScript invokes |
| 328 | 344 |
| 329 // Set up call kind marking in rcx. The method takes rcx as an | 345 // Set up call kind marking in rcx. The method takes rcx as an |
| 330 // explicit first parameter to make the code more readable at the | 346 // explicit first parameter to make the code more readable at the |
| 331 // call sites. | 347 // call sites. |
| 332 void SetCallKind(Register dst, CallKind kind); | 348 void SetCallKind(Register dst, CallKind kind); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 | 393 |
| 378 // --------------------------------------------------------------------------- | 394 // --------------------------------------------------------------------------- |
| 379 // Smi tagging, untagging and operations on tagged smis. | 395 // Smi tagging, untagging and operations on tagged smis. |
| 380 | 396 |
| 381 // Support for constant splitting. | 397 // Support for constant splitting. |
| 382 bool IsUnsafeInt(const int32_t x); | 398 bool IsUnsafeInt(const int32_t x); |
| 383 void SafeMove(Register dst, Smi* src); | 399 void SafeMove(Register dst, Smi* src); |
| 384 void SafePush(Smi* src); | 400 void SafePush(Smi* src); |
| 385 | 401 |
| 386 void InitializeSmiConstantRegister() { | 402 void InitializeSmiConstantRegister() { |
| 387 movq(kSmiConstantRegister, | 403 movq(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), |
| 388 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), | |
| 389 RelocInfo::NONE64); | 404 RelocInfo::NONE64); |
| 390 } | 405 } |
| 391 | 406 |
| 392 // Conversions between tagged smi values and non-tagged integer values. | 407 // Conversions between tagged smi values and non-tagged integer values. |
| 393 | 408 |
| 394 // Tag an integer value. The result must be known to be a valid smi value. | 409 // Tag an integer value. The result must be known to be a valid smi value. |
| 395 // Only uses the low 32 bits of the src register. Sets the N and Z flags | 410 // Only uses the low 32 bits of the src register. Sets the N and Z flags |
| 396 // based on the value of the resulting smi. | 411 // based on the value of the resulting smi. |
| 397 void Integer32ToSmi(Register dst, Register src); | 412 void Integer32ToSmi(Register dst, Register src); |
| 398 | 413 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 | 556 |
| 542 // Add an integer constant to a tagged smi, giving a tagged smi as result. | 557 // Add an integer constant to a tagged smi, giving a tagged smi as result. |
| 543 // No overflow testing on the result is done. | 558 // No overflow testing on the result is done. |
| 544 void SmiAddConstant(const Operand& dst, Smi* constant); | 559 void SmiAddConstant(const Operand& dst, Smi* constant); |
| 545 | 560 |
| 546 // Add an integer constant to a tagged smi, giving a tagged smi as result, | 561 // Add an integer constant to a tagged smi, giving a tagged smi as result, |
| 547 // or jumping to a label if the result cannot be represented by a smi. | 562 // or jumping to a label if the result cannot be represented by a smi. |
| 548 void SmiAddConstant(Register dst, | 563 void SmiAddConstant(Register dst, |
| 549 Register src, | 564 Register src, |
| 550 Smi* constant, | 565 Smi* constant, |
| 551 Label* on_not_smi_result, | 566 SmiOperationExecutionMode mode, |
| 567 Label* bailout_label, |
| 552 Label::Distance near_jump = Label::kFar); | 568 Label::Distance near_jump = Label::kFar); |
| 553 | 569 |
| 554 // Subtract an integer constant from a tagged smi, giving a tagged smi as | 570 // Subtract an integer constant from a tagged smi, giving a tagged smi as |
| 555 // result. No testing on the result is done. Sets the N and Z flags | 571 // result. No testing on the result is done. Sets the N and Z flags |
| 556 // based on the value of the resulting integer. | 572 // based on the value of the resulting integer. |
| 557 void SmiSubConstant(Register dst, Register src, Smi* constant); | 573 void SmiSubConstant(Register dst, Register src, Smi* constant); |
| 558 | 574 |
| 559 // Subtract an integer constant from a tagged smi, giving a tagged smi as | 575 // Subtract an integer constant from a tagged smi, giving a tagged smi as |
| 560 // result, or jumping to a label if the result cannot be represented by a smi. | 576 // result, or jumping to a label if the result cannot be represented by a smi. |
| 561 void SmiSubConstant(Register dst, | 577 void SmiSubConstant(Register dst, |
| 562 Register src, | 578 Register src, |
| 563 Smi* constant, | 579 Smi* constant, |
| 564 Label* on_not_smi_result, | 580 SmiOperationExecutionMode mode, |
| 581 Label* bailout_label, |
| 565 Label::Distance near_jump = Label::kFar); | 582 Label::Distance near_jump = Label::kFar); |
| 566 | 583 |
| 567 // Negating a smi can give a negative zero or too large positive value. | 584 // Negating a smi can give a negative zero or too large positive value. |
| 568 // NOTICE: This operation jumps on success, not failure! | 585 // NOTICE: This operation jumps on success, not failure! |
| 569 void SmiNeg(Register dst, | 586 void SmiNeg(Register dst, |
| 570 Register src, | 587 Register src, |
| 571 Label* on_smi_result, | 588 Label* on_smi_result, |
| 572 Label::Distance near_jump = Label::kFar); | 589 Label::Distance near_jump = Label::kFar); |
| 573 | 590 |
| 574 // Adds smi values and return the result as a smi. | 591 // Adds smi values and return the result as a smi. |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 839 |
| 823 // Emit code to discard a non-negative number of pointer-sized elements | 840 // Emit code to discard a non-negative number of pointer-sized elements |
| 824 // from the stack, clobbering only the rsp register. | 841 // from the stack, clobbering only the rsp register. |
| 825 void Drop(int stack_elements); | 842 void Drop(int stack_elements); |
| 826 | 843 |
| 827 void Call(Label* target) { call(target); } | 844 void Call(Label* target) { call(target); } |
| 828 void Push(Register src) { push(src); } | 845 void Push(Register src) { push(src); } |
| 829 void Pop(Register dst) { pop(dst); } | 846 void Pop(Register dst) { pop(dst); } |
| 830 void PushReturnAddressFrom(Register src) { push(src); } | 847 void PushReturnAddressFrom(Register src) { push(src); } |
| 831 void PopReturnAddressTo(Register dst) { pop(dst); } | 848 void PopReturnAddressTo(Register dst) { pop(dst); } |
| 849 void MoveDouble(Register dst, const Operand& src) { movq(dst, src); } |
| 850 void MoveDouble(const Operand& dst, Register src) { movq(dst, src); } |
| 851 void Move(Register dst, ExternalReference ext) { |
| 852 movq(dst, reinterpret_cast<Address>(ext.address()), |
| 853 RelocInfo::EXTERNAL_REFERENCE); |
| 854 } |
| 832 | 855 |
| 833 // Control Flow | 856 // Control Flow |
| 834 void Jump(Address destination, RelocInfo::Mode rmode); | 857 void Jump(Address destination, RelocInfo::Mode rmode); |
| 835 void Jump(ExternalReference ext); | 858 void Jump(ExternalReference ext); |
| 836 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); | 859 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); |
| 837 | 860 |
| 838 void Call(Address destination, RelocInfo::Mode rmode); | 861 void Call(Address destination, RelocInfo::Mode rmode); |
| 839 void Call(ExternalReference ext); | 862 void Call(ExternalReference ext); |
| 840 void Call(Handle<Code> code_object, | 863 void Call(Handle<Code> code_object, |
| 841 RelocInfo::Mode rmode, | 864 RelocInfo::Mode rmode, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 // FastDoubleElements. If it can, store it at the index specified by index in | 930 // FastDoubleElements. If it can, store it at the index specified by index in |
| 908 // the FastDoubleElements array elements, otherwise jump to fail. Note that | 931 // the FastDoubleElements array elements, otherwise jump to fail. Note that |
| 909 // index must not be smi-tagged. | 932 // index must not be smi-tagged. |
| 910 void StoreNumberToDoubleElements(Register maybe_number, | 933 void StoreNumberToDoubleElements(Register maybe_number, |
| 911 Register elements, | 934 Register elements, |
| 912 Register index, | 935 Register index, |
| 913 XMMRegister xmm_scratch, | 936 XMMRegister xmm_scratch, |
| 914 Label* fail, | 937 Label* fail, |
| 915 int elements_offset = 0); | 938 int elements_offset = 0); |
| 916 | 939 |
| 917 // Compare an object's map with the specified map and its transitioned | 940 // Compare an object's map with the specified map. |
| 918 // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with | 941 void CompareMap(Register obj, Handle<Map> map); |
| 919 // result of map compare. If multiple map compares are required, the compare | |
| 920 // sequences branches to early_success. | |
| 921 void CompareMap(Register obj, | |
| 922 Handle<Map> map, | |
| 923 Label* early_success); | |
| 924 | 942 |
| 925 // Check if the map of an object is equal to a specified map and branch to | 943 // Check if the map of an object is equal to a specified map and branch to |
| 926 // label if not. Skip the smi check if not required (object is known to be a | 944 // label if not. Skip the smi check if not required (object is known to be a |
| 927 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 945 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
| 928 // against maps that are ElementsKind transition maps of the specified map. | 946 // against maps that are ElementsKind transition maps of the specified map. |
| 929 void CheckMap(Register obj, | 947 void CheckMap(Register obj, |
| 930 Handle<Map> map, | 948 Handle<Map> map, |
| 931 Label* fail, | 949 Label* fail, |
| 932 SmiCheckType smi_check_type); | 950 SmiCheckType smi_check_type); |
| 933 | 951 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 Label* gc_required, | 1109 Label* gc_required, |
| 1092 AllocationFlags flags); | 1110 AllocationFlags flags); |
| 1093 | 1111 |
| 1094 void Allocate(Register object_size, | 1112 void Allocate(Register object_size, |
| 1095 Register result, | 1113 Register result, |
| 1096 Register result_end, | 1114 Register result_end, |
| 1097 Register scratch, | 1115 Register scratch, |
| 1098 Label* gc_required, | 1116 Label* gc_required, |
| 1099 AllocationFlags flags); | 1117 AllocationFlags flags); |
| 1100 | 1118 |
| 1101 // Record a JS object allocation if allocations tracking mode is on. | |
| 1102 void RecordObjectAllocation(Isolate* isolate, | |
| 1103 Register object, | |
| 1104 Register object_size); | |
| 1105 | |
| 1106 void RecordObjectAllocation(Isolate* isolate, | |
| 1107 Register object, | |
| 1108 int object_size); | |
| 1109 | |
| 1110 // Undo allocation in new space. The object passed and objects allocated after | 1119 // Undo allocation in new space. The object passed and objects allocated after |
| 1111 // it will no longer be allocated. Make sure that no pointers are left to the | 1120 // it will no longer be allocated. Make sure that no pointers are left to the |
| 1112 // object(s) no longer allocated as they would be invalid when allocation is | 1121 // object(s) no longer allocated as they would be invalid when allocation is |
| 1113 // un-done. | 1122 // un-done. |
| 1114 void UndoAllocationInNewSpace(Register object); | 1123 void UndoAllocationInNewSpace(Register object); |
| 1115 | 1124 |
| 1116 // Allocate a heap number in new space with undefined value. Returns | 1125 // Allocate a heap number in new space with undefined value. Returns |
| 1117 // tagged pointer in result register, or jumps to gc_required if new | 1126 // tagged pointer in result register, or jumps to gc_required if new |
| 1118 // space is full. | 1127 // space is full. |
| 1119 void AllocateHeapNumber(Register result, | 1128 void AllocateHeapNumber(Register result, |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1403 void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, | 1412 void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, |
| 1404 Register scratch_reg, | 1413 Register scratch_reg, |
| 1405 Label* memento_found) { | 1414 Label* memento_found) { |
| 1406 Label no_memento_found; | 1415 Label no_memento_found; |
| 1407 TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, | 1416 TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, |
| 1408 &no_memento_found); | 1417 &no_memento_found); |
| 1409 j(equal, memento_found); | 1418 j(equal, memento_found); |
| 1410 bind(&no_memento_found); | 1419 bind(&no_memento_found); |
| 1411 } | 1420 } |
| 1412 | 1421 |
| 1422 // Jumps to found label if a prototype map has dictionary elements. |
| 1423 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, |
| 1424 Register scratch1, Label* found); |
| 1425 |
| 1413 private: | 1426 private: |
| 1414 // Order general registers are pushed by Pushad. | 1427 // Order general registers are pushed by Pushad. |
| 1415 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. | 1428 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. |
| 1416 static const int kSafepointPushRegisterIndices[Register::kNumRegisters]; | 1429 static const int kSafepointPushRegisterIndices[Register::kNumRegisters]; |
| 1417 static const int kNumSafepointSavedRegisters = 11; | 1430 static const int kNumSafepointSavedRegisters = 11; |
| 1418 static const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 1431 static const int kSmiShift = kSmiTagSize + kSmiShiftSize; |
| 1419 | 1432 |
| 1420 bool generating_stub_; | 1433 bool generating_stub_; |
| 1421 bool allow_stub_calls_; | 1434 bool allow_stub_calls_; |
| 1422 bool has_frame_; | 1435 bool has_frame_; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1586 masm->popfq(); \ | 1599 masm->popfq(); \ |
| 1587 } \ | 1600 } \ |
| 1588 masm-> | 1601 masm-> |
| 1589 #else | 1602 #else |
| 1590 #define ACCESS_MASM(masm) masm-> | 1603 #define ACCESS_MASM(masm) masm-> |
| 1591 #endif | 1604 #endif |
| 1592 | 1605 |
| 1593 } } // namespace v8::internal | 1606 } } // namespace v8::internal |
| 1594 | 1607 |
| 1595 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ | 1608 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ |
| OLD | NEW |