47
47
// Default scratch register used by MacroAssembler (and other code that needs
48
48
// a spare register). The register isn't callee save, and not used by the
49
49
// function calling convention.
50
static const Register kScratchRegister = { 10 }; // r10.
51
static const Register kRootRegister = { 13 }; // r13
50
static const Register kScratchRegister = { 10 }; // r10.
51
static const Register kSmiConstantRegister = { 15 }; // r15 (callee save).
52
static const Register kRootRegister = { 13 }; // r13 (callee save).
53
// Value of smi in kSmiConstantRegister.
54
static const int kSmiConstantRegisterValue = 1;
53
56
// Convenience for platform-independent signatures.
54
57
typedef Operand MemOperand;
78
81
// ---------------------------------------------------------------------------
81
// Set the remebered set bit for an address which points into an
82
// object. RecordWriteHelper only works if the object is not in new
84
// For page containing |object| mark region covering |addr| dirty.
85
// RecordWriteHelper only works if the object is not in new
84
87
void RecordWriteHelper(Register object,
96
// Set the remembered set bit for [object+offset].
97
// object is the object being stored into, value is the object being stored.
98
// If offset is zero, then the scratch register contains the array index into
99
// the elements array represented as a Smi.
100
// All registers are clobbered by the operation.
99
// For page containing |object| mark region covering [object+offset]
100
// dirty. |object| is the object being stored into, |value| is the
101
// object being stored. If |offset| is zero, then the |scratch|
102
// register contains the array index into the elements array
103
// represented as a Smi. All registers are clobbered by the
104
// operation. RecordWrite filters out smis so it does not update the
105
// write barrier if the value is a smi.
101
106
void RecordWrite(Register object,
104
109
Register scratch);
106
// Set the remembered set bit for [object+offset].
111
// For page containing |object| mark region covering [address]
112
// dirty. |object| is the object being stored into, |value| is the
113
// object being stored. All registers are clobbered by the
114
// operation. RecordWrite filters out smis so it does not update
115
// the write barrier if the value is a smi.
116
void RecordWrite(Register object,
120
// For page containing |object| mark region covering [object+offset] dirty.
107
121
// The value is known to not be a smi.
108
122
// object is the object being stored into, value is the object being stored.
109
123
// If offset is zero, then the scratch register contains the array index into
149
163
// to the first argument in register rsi.
150
164
void EnterExitFrame(ExitFrame::Mode mode, int result_size = 1);
166
void EnterApiExitFrame(ExitFrame::Mode mode,
169
int result_size = 1);
152
171
// Leave the current exit frame. Expects/provides the return value in
153
172
// register rax:rdx (untouched) and the pointer to the first
154
173
// argument in register rsi.
191
210
// ---------------------------------------------------------------------------
192
211
// Smi tagging, untagging and operations on tagged smis.
213
void InitializeSmiConstantRegister() {
214
movq(kSmiConstantRegister,
215
reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
194
219
// Conversions between tagged smi values and non-tagged integer values.
196
221
// Tag an integer value. The result must be known to be a valid smi value.
203
228
// NOTICE: Destroys the dst register even if unsuccessful!
204
229
void Integer32ToSmi(Register dst, Register src, Label* on_overflow);
231
// Stores an integer32 value into a memory field that already holds a smi.
232
void Integer32ToSmiField(const Operand& dst, Register src);
206
234
// Adds constant to src and tags the result as a smi.
207
235
// Result must be a valid smi.
208
236
void Integer64PlusConstantToSmi(Register dst, Register src, int constant);
210
238
// Convert smi to 32-bit integer. I.e., not sign extended into
211
239
// high 32 bits of destination.
212
240
void SmiToInteger32(Register dst, Register src);
241
void SmiToInteger32(Register dst, const Operand& src);
214
243
// Convert smi to 64-bit integer (sign extended if necessary).
215
244
void SmiToInteger64(Register dst, Register src);
245
void SmiToInteger64(Register dst, const Operand& src);
217
247
// Multiply a positive smi's integer value by a power of two.
218
248
// Provides result as 64-bit integer value.
253
// Divide a positive smi's integer value by a power of two.
254
// Provides result as 32-bit integer value.
255
void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
223
260
// Simple comparison of smis.
224
261
void SmiCompare(Register dst, Register src);
225
262
void SmiCompare(Register dst, Smi* src);
226
263
void SmiCompare(Register dst, const Operand& src);
227
264
void SmiCompare(const Operand& dst, Register src);
228
265
void SmiCompare(const Operand& dst, Smi* src);
266
// Compare the int32 in src register to the value of the smi stored at dst.
267
void SmiCompareInteger32(const Operand& dst, Register src);
229
268
// Sets sign and zero flags depending on value of smi in register.
230
269
void SmiTest(Register src);
245
284
Condition CheckBothPositiveSmi(Register first, Register second);
247
286
// Are either value a tagged smi.
248
Condition CheckEitherSmi(Register first, Register second);
287
Condition CheckEitherSmi(Register first,
289
Register scratch = kScratchRegister);
250
291
// Is the value the minimum smi value (since we are using
251
292
// two's complement numbers, negating the value is known to yield
445
486
// Basic Smi operations.
446
487
void Move(Register dst, Smi* source) {
447
Set(dst, reinterpret_cast<int64_t>(source));
488
LoadSmiConstant(dst, source);
450
491
void Move(const Operand& dst, Smi* source) {
451
Set(dst, reinterpret_cast<int64_t>(source));
492
Register constant = GetSmiConstant(source);
454
496
void Push(Smi* smi);
533
575
Register instance_type);
535
// FCmp is similar to integer cmp, but requires unsigned
577
// FCmp compares and pops the two values on top of the FPU stack.
578
// The flag results are similar to integer cmp, but requires unsigned
536
579
// jcc instructions (je, ja, jae, jb, jbe, je, and jz).
539
582
// Abort execution if argument is not a number. Used in debug code.
540
583
void AbortIfNotNumber(Register object);
585
// Abort execution if argument is a smi. Used in debug code.
586
void AbortIfSmi(Register object);
542
588
// Abort execution if argument is not a smi. Used in debug code.
543
589
void AbortIfNotSmi(Register object);
591
// Abort execution if argument is not the root value with the given index.
592
void AbortIfNotRootValue(Register src,
593
Heap::RootListIndex root_value_index,
594
const char* message);
545
596
// ---------------------------------------------------------------------------
546
597
// Exception handling
555
606
// ---------------------------------------------------------------------------
556
607
// Inline caching support
558
// Generates code that verifies that the maps of objects in the
559
// prototype chain of object hasn't changed since the code was
560
// generated and branches to the miss label if any map has. If
561
// necessary the function also generates code for security check
562
// in case of global object holders. The scratch and holder
563
// registers are always clobbered, but the object register is only
564
// clobbered if it the same as the holder register. The function
565
// returns a register containing the holder - either object_reg or
567
// The function can optionally (when save_at_depth !=
568
// kInvalidProtoDepth) save the object at the given depth by moving
569
// it to [rsp + kPointerSize].
570
Register CheckMaps(JSObject* object, Register object_reg,
571
JSObject* holder, Register holder_reg,
576
609
// Generate code for checking access rights - used for security checks
577
610
// on access to global objects across environments. The holder register
578
611
// is left untouched, but the scratch register and kScratchRegister,
696
729
// Call a code stub.
697
730
void CallStub(CodeStub* stub);
732
// Call a code stub and return the code object called. Try to generate
733
// the code if necessary. Do not perform a GC but instead return a retry
735
Object* TryCallStub(CodeStub* stub);
699
737
// Tail call a code stub (jump).
700
738
void TailCallStub(CodeStub* stub);
740
// Tail call a code stub (jump) and return the code object called. Try to
741
// generate the code if necessary. Do not perform a GC but instead return
742
// a retry after GC failure.
743
Object* TryTailCallStub(CodeStub* stub);
702
745
// Return from a code stub after popping its arguments.
703
746
void StubReturn(int argc);
705
748
// Call a runtime routine.
706
749
void CallRuntime(Runtime::Function* f, int num_arguments);
751
// Call a runtime function, returning the CodeStub object called.
752
// Try to generate the stub code if necessary. Do not perform a GC
753
// but instead return a retry after GC failure.
754
Object* TryCallRuntime(Runtime::Function* f, int num_arguments);
708
756
// Convenience function: Same as above, but takes the fid instead.
709
757
void CallRuntime(Runtime::FunctionId id, int num_arguments);
759
// Convenience function: Same as above, but takes the fid instead.
760
Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
711
762
// Convenience function: call an external reference.
712
763
void CallExternalReference(const ExternalReference& ext,
713
764
int num_arguments);
724
775
int num_arguments,
725
776
int result_size);
778
void PushHandleScope(Register scratch);
780
// Pops a handle scope using the specified scratch register and
781
// ensuring that saved register is left unchanged.
782
void PopHandleScope(Register saved, Register scratch);
784
// As PopHandleScope, but does not perform a GC. Instead, returns a
785
// retry after GC failure object if GC is necessary.
786
Object* TryPopHandleScope(Register saved, Register scratch);
727
788
// Jump to a runtime routine.
728
789
void JumpToExternalReference(const ExternalReference& ext, int result_size);
790
851
bool generating_stub_;
791
852
bool allow_stub_calls_;
854
// Returns a register holding the smi value. The register MUST NOT be
855
// modified. It may be the "smi 1 constant" register.
856
Register GetSmiConstant(Smi* value);
858
// Moves the smi value to the destination register.
859
void LoadSmiConstant(Register dst, Smi* value);
792
861
// This handle will be patched with the code object on installation.
793
862
Handle<Object> code_object_;
804
873
void EnterFrame(StackFrame::Type type);
805
874
void LeaveFrame(StackFrame::Type type);
876
void EnterExitFramePrologue(ExitFrame::Mode mode, bool save_rax);
877
void EnterExitFrameEpilogue(ExitFrame::Mode mode, int result_size, int argc);
807
879
// Allocation support helpers.
808
880
// Loads the top of new-space into the result register.
809
881
// If flags contains RESULT_CONTAINS_TOP then result_end is valid and
817
889
// Update allocation top with value in result_end register.
818
890
// If scratch is valid, it contains the address of the allocation top.
819
891
void UpdateAllocationTopHelper(Register result_end, Register scratch);
893
// Helper for PopHandleScope. Allowed to perform a GC and returns
894
// NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
895
// possibly returns a failure object indicating an allocation failure.
896
Object* PopHandleScopeHelper(Register saved,