OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_X87_MACRO_ASSEMBLER_X87_H_ | 5 #ifndef V8_X87_MACRO_ASSEMBLER_X87_H_ |
6 #define V8_X87_MACRO_ASSEMBLER_X87_H_ | 6 #define V8_X87_MACRO_ASSEMBLER_X87_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/frames.h" | 10 #include "src/frames.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 SaveFPRegsMode save_fp, | 190 SaveFPRegsMode save_fp, |
191 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 191 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
192 SmiCheck smi_check = INLINE_SMI_CHECK, | 192 SmiCheck smi_check = INLINE_SMI_CHECK, |
193 PointersToHereCheck pointers_to_here_check_for_value = | 193 PointersToHereCheck pointers_to_here_check_for_value = |
194 kPointersToHereMaybeInteresting) { | 194 kPointersToHereMaybeInteresting) { |
195 RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, | 195 RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp, |
196 remembered_set_action, smi_check, | 196 remembered_set_action, smi_check, |
197 pointers_to_here_check_for_value); | 197 pointers_to_here_check_for_value); |
198 } | 198 } |
199 | 199 |
200 // Notify the garbage collector that we wrote a pointer into a fixed array. | |
201 // |array| is the array being stored into, |value| is the | |
202 // object being stored. |index| is the array index represented as a | |
203 // Smi. All registers are clobbered by the operation RecordWriteArray | |
204 // filters out smis so it does not update the write barrier if the | |
205 // value is a smi. | |
206 void RecordWriteArray( | |
207 Register array, Register value, Register index, SaveFPRegsMode save_fp, | |
208 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | |
209 SmiCheck smi_check = INLINE_SMI_CHECK, | |
210 PointersToHereCheck pointers_to_here_check_for_value = | |
211 kPointersToHereMaybeInteresting); | |
212 | |
213 // For page containing |object| mark region covering |address| | 200 // For page containing |object| mark region covering |address| |
214 // dirty. |object| is the object being stored into, |value| is the | 201 // dirty. |object| is the object being stored into, |value| is the |
215 // object being stored. The address and value registers are clobbered by the | 202 // object being stored. The address and value registers are clobbered by the |
216 // operation. RecordWrite filters out smis so it does not update the | 203 // operation. RecordWrite filters out smis so it does not update the |
217 // write barrier if the value is a smi. | 204 // write barrier if the value is a smi. |
218 void RecordWrite( | 205 void RecordWrite( |
219 Register object, Register address, Register value, SaveFPRegsMode save_fp, | 206 Register object, Register address, Register value, SaveFPRegsMode save_fp, |
220 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, | 207 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
221 SmiCheck smi_check = INLINE_SMI_CHECK, | 208 SmiCheck smi_check = INLINE_SMI_CHECK, |
222 PointersToHereCheck pointers_to_here_check_for_value = | 209 PointersToHereCheck pointers_to_here_check_for_value = |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 286 |
300 void CmpObject(Register reg, Handle<Object> object) { | 287 void CmpObject(Register reg, Handle<Object> object) { |
301 AllowDeferredHandleDereference heap_object_check; | 288 AllowDeferredHandleDereference heap_object_check; |
302 if (object->IsHeapObject()) { | 289 if (object->IsHeapObject()) { |
303 CmpHeapObject(reg, Handle<HeapObject>::cast(object)); | 290 CmpHeapObject(reg, Handle<HeapObject>::cast(object)); |
304 } else { | 291 } else { |
305 cmp(reg, Immediate(object)); | 292 cmp(reg, Immediate(object)); |
306 } | 293 } |
307 } | 294 } |
308 | 295 |
309 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch); | |
310 void GetWeakValue(Register value, Handle<WeakCell> cell); | 296 void GetWeakValue(Register value, Handle<WeakCell> cell); |
311 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); | 297 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); |
312 | 298 |
313 // --------------------------------------------------------------------------- | 299 // --------------------------------------------------------------------------- |
314 // JavaScript invokes | 300 // JavaScript invokes |
315 | 301 |
316 // Removes current frame and its arguments from the stack preserving | 302 // Removes current frame and its arguments from the stack preserving |
317 // the arguments and a return address pushed to the stack for the next call. | 303 // the arguments and a return address pushed to the stack for the next call. |
318 // |ra_state| defines whether return address is already pushed to stack or | 304 // |ra_state| defines whether return address is already pushed to stack or |
319 // not. Both |callee_args_count| and |caller_args_count_reg| do not include | 305 // not. Both |callee_args_count| and |caller_args_count_reg| do not include |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 // Compare an object's map with the specified map. | 363 // Compare an object's map with the specified map. |
378 void CompareMap(Register obj, Handle<Map> map); | 364 void CompareMap(Register obj, Handle<Map> map); |
379 | 365 |
380 // Check if the map of an object is equal to a specified map and branch to | 366 // Check if the map of an object is equal to a specified map and branch to |
381 // label if not. Skip the smi check if not required (object is known to be a | 367 // label if not. Skip the smi check if not required (object is known to be a |
382 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 368 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
383 // against maps that are ElementsKind transition maps of the specified map. | 369 // against maps that are ElementsKind transition maps of the specified map. |
384 void CheckMap(Register obj, Handle<Map> map, Label* fail, | 370 void CheckMap(Register obj, Handle<Map> map, Label* fail, |
385 SmiCheckType smi_check_type); | 371 SmiCheckType smi_check_type); |
386 | 372 |
387 // Check if the map of an object is equal to a specified weak map and branch | |
388 // to a specified target if equal. Skip the smi check if not required | |
389 // (object is known to be a heap object) | |
390 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, | |
391 Handle<WeakCell> cell, Handle<Code> success, | |
392 SmiCheckType smi_check_type); | |
393 | |
394 // Check if the object in register heap_object is a string. Afterwards the | 373 // Check if the object in register heap_object is a string. Afterwards the |
395 // register map contains the object map and the register instance_type | 374 // register map contains the object map and the register instance_type |
396 // contains the instance_type. The registers map and instance_type can be the | 375 // contains the instance_type. The registers map and instance_type can be the |
397 // same in which case it contains the instance type afterwards. Either of the | 376 // same in which case it contains the instance type afterwards. Either of the |
398 // registers map and instance_type can be the same as heap_object. | 377 // registers map and instance_type can be the same as heap_object. |
399 Condition IsObjectStringType(Register heap_object, Register map, | 378 Condition IsObjectStringType(Register heap_object, Register map, |
400 Register instance_type); | 379 Register instance_type); |
401 | 380 |
402 // Check if the object in register heap_object is a name. Afterwards the | |
403 // register map contains the object map and the register instance_type | |
404 // contains the instance_type. The registers map and instance_type can be the | |
405 // same in which case it contains the instance type afterwards. Either of the | |
406 // registers map and instance_type can be the same as heap_object. | |
407 Condition IsObjectNameType(Register heap_object, Register map, | |
408 Register instance_type); | |
409 | |
410 // FCmp is similar to integer cmp, but requires unsigned | 381 // FCmp is similar to integer cmp, but requires unsigned |
411 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). | 382 // jcc instructions (je, ja, jae, jb, jbe, je, and jz). |
412 void FCmp(); | 383 void FCmp(); |
413 void FXamMinusZero(); | 384 void FXamMinusZero(); |
414 void FXamSign(); | 385 void FXamSign(); |
415 void X87CheckIA(); | 386 void X87CheckIA(); |
416 void X87SetRC(int rc); | 387 void X87SetRC(int rc); |
417 void X87SetFPUCW(int cw); | 388 void X87SetFPUCW(int cw); |
418 | 389 |
419 void ClampUint8(Register reg); | 390 void ClampUint8(Register reg); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); | 487 STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); |
517 STATIC_ASSERT(kSmiTag == 0); | 488 STATIC_ASSERT(kSmiTag == 0); |
518 if (shift < kSmiTagSize) { | 489 if (shift < kSmiTagSize) { |
519 shl(reg, kSmiTagSize - shift); | 490 shl(reg, kSmiTagSize - shift); |
520 } else if (shift > kSmiTagSize) { | 491 } else if (shift > kSmiTagSize) { |
521 sar(reg, shift - kSmiTagSize); | 492 sar(reg, shift - kSmiTagSize); |
522 } | 493 } |
523 and_(reg, Immediate(mask)); | 494 and_(reg, Immediate(mask)); |
524 } | 495 } |
525 | 496 |
526 // Abort execution if argument is not a number, enabled via --debug-code. | |
527 void AssertNumber(Register object); | |
528 void AssertNotNumber(Register object); | |
529 | |
530 // Abort execution if argument is not a smi, enabled via --debug-code. | 497 // Abort execution if argument is not a smi, enabled via --debug-code. |
531 void AssertSmi(Register object); | 498 void AssertSmi(Register object); |
532 | 499 |
533 // Abort execution if argument is a smi, enabled via --debug-code. | 500 // Abort execution if argument is a smi, enabled via --debug-code. |
534 void AssertNotSmi(Register object); | 501 void AssertNotSmi(Register object); |
535 | 502 |
536 // Abort execution if argument is not a string, enabled via --debug-code. | |
537 void AssertString(Register object); | |
538 | |
539 // Abort execution if argument is not a name, enabled via --debug-code. | |
540 void AssertName(Register object); | |
541 | |
542 // Abort execution if argument is not a JSFunction, enabled via --debug-code. | 503 // Abort execution if argument is not a JSFunction, enabled via --debug-code. |
543 void AssertFunction(Register object); | 504 void AssertFunction(Register object); |
544 | 505 |
545 // Abort execution if argument is not a JSBoundFunction, | 506 // Abort execution if argument is not a JSBoundFunction, |
546 // enabled via --debug-code. | 507 // enabled via --debug-code. |
547 void AssertBoundFunction(Register object); | 508 void AssertBoundFunction(Register object); |
548 | 509 |
549 // Abort execution if argument is not a JSGeneratorObject, | 510 // Abort execution if argument is not a JSGeneratorObject, |
550 // enabled via --debug-code. | 511 // enabled via --debug-code. |
551 void AssertGeneratorObject(Register object); | 512 void AssertGeneratorObject(Register object); |
552 | 513 |
553 // Abort execution if argument is not a JSReceiver, enabled via --debug-code. | |
554 void AssertReceiver(Register object); | |
555 | |
556 // Abort execution if argument is not undefined or an AllocationSite, enabled | 514 // Abort execution if argument is not undefined or an AllocationSite, enabled |
557 // via --debug-code. | 515 // via --debug-code. |
558 void AssertUndefinedOrAllocationSite(Register object); | 516 void AssertUndefinedOrAllocationSite(Register object); |
559 | 517 |
560 // --------------------------------------------------------------------------- | 518 // --------------------------------------------------------------------------- |
561 // Exception handling | 519 // Exception handling |
562 | 520 |
563 // Push a new stack handler and link it into stack handler chain. | 521 // Push a new stack handler and link it into stack handler chain. |
564 void PushStackHandler(); | 522 void PushStackHandler(); |
565 | 523 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 // the end the loop, |current_address| takes the value of |end_address|. | 578 // the end the loop, |current_address| takes the value of |end_address|. |
621 void InitializeFieldsWithFiller(Register current_address, | 579 void InitializeFieldsWithFiller(Register current_address, |
622 Register end_address, Register filler); | 580 Register end_address, Register filler); |
623 | 581 |
624 // --------------------------------------------------------------------------- | 582 // --------------------------------------------------------------------------- |
625 // Support functions. | 583 // Support functions. |
626 | 584 |
627 // Check a boolean-bit of a Smi field. | 585 // Check a boolean-bit of a Smi field. |
628 void BooleanBitTest(Register object, int field_offset, int bit_index); | 586 void BooleanBitTest(Register object, int field_offset, int bit_index); |
629 | 587 |
630 // Check if result is zero and op is negative. | |
631 void NegativeZeroTest(Register result, Register op, Label* then_label); | |
632 | |
633 // Check if result is zero and any of op1 and op2 are negative. | |
634 // Register scratch is destroyed, and it must be different from op2. | |
635 void NegativeZeroTest(Register result, Register op1, Register op2, | |
636 Register scratch, Label* then_label); | |
637 | |
638 // --------------------------------------------------------------------------- | 588 // --------------------------------------------------------------------------- |
639 // Runtime calls | 589 // Runtime calls |
640 | 590 |
641 // Call a code stub. Generate the code if necessary. | 591 // Call a code stub. Generate the code if necessary. |
642 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); | 592 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); |
643 | 593 |
644 // Tail call a code stub (jump). Generate the code if necessary. | 594 // Tail call a code stub (jump). Generate the code if necessary. |
645 void TailCallStub(CodeStub* stub); | 595 void TailCallStub(CodeStub* stub); |
646 | 596 |
647 // Return from a code stub after popping its arguments. | |
648 void StubReturn(int argc); | |
649 | |
650 // Call a runtime routine. | 597 // Call a runtime routine. |
651 void CallRuntime(const Runtime::Function* f, int num_arguments, | 598 void CallRuntime(const Runtime::Function* f, int num_arguments, |
652 SaveFPRegsMode save_doubles = kDontSaveFPRegs); | 599 SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
653 void CallRuntimeSaveDoubles(Runtime::FunctionId fid) { | 600 void CallRuntimeSaveDoubles(Runtime::FunctionId fid) { |
654 const Runtime::Function* function = Runtime::FunctionForId(fid); | 601 const Runtime::Function* function = Runtime::FunctionForId(fid); |
655 CallRuntime(function, function->nargs, kSaveFPRegs); | 602 CallRuntime(function, function->nargs, kSaveFPRegs); |
656 } | 603 } |
657 | 604 |
658 // Convenience function: Same as above, but takes the fid instead. | 605 // Convenience function: Same as above, but takes the fid instead. |
659 void CallRuntime(Runtime::FunctionId fid, | 606 void CallRuntime(Runtime::FunctionId fid, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 void IncrementCounter(Condition cc, StatsCounter* counter, int value); | 731 void IncrementCounter(Condition cc, StatsCounter* counter, int value); |
785 void DecrementCounter(Condition cc, StatsCounter* counter, int value); | 732 void DecrementCounter(Condition cc, StatsCounter* counter, int value); |
786 | 733 |
787 // --------------------------------------------------------------------------- | 734 // --------------------------------------------------------------------------- |
788 // Debugging | 735 // Debugging |
789 | 736 |
790 // Calls Abort(msg) if the condition cc is not satisfied. | 737 // Calls Abort(msg) if the condition cc is not satisfied. |
791 // Use --debug_code to enable. | 738 // Use --debug_code to enable. |
792 void Assert(Condition cc, BailoutReason reason); | 739 void Assert(Condition cc, BailoutReason reason); |
793 | 740 |
794 void AssertFastElements(Register elements); | |
795 | |
796 // Like Assert(), but always enabled. | 741 // Like Assert(), but always enabled. |
797 void Check(Condition cc, BailoutReason reason); | 742 void Check(Condition cc, BailoutReason reason); |
798 | 743 |
799 // Print a message to stdout and abort execution. | 744 // Print a message to stdout and abort execution. |
800 void Abort(BailoutReason reason); | 745 void Abort(BailoutReason reason); |
801 | 746 |
802 // Check that the stack is aligned. | 747 // Check that the stack is aligned. |
803 void CheckStackAlignment(); | 748 void CheckStackAlignment(); |
804 | 749 |
805 // Verify restrictions about code generated in stubs. | 750 // Verify restrictions about code generated in stubs. |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 inline Operand NativeContextOperand() { | 901 inline Operand NativeContextOperand() { |
957 return ContextOperand(esi, Context::NATIVE_CONTEXT_INDEX); | 902 return ContextOperand(esi, Context::NATIVE_CONTEXT_INDEX); |
958 } | 903 } |
959 | 904 |
960 #define ACCESS_MASM(masm) masm-> | 905 #define ACCESS_MASM(masm) masm-> |
961 | 906 |
962 } // namespace internal | 907 } // namespace internal |
963 } // namespace v8 | 908 } // namespace v8 |
964 | 909 |
965 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ | 910 #endif // V8_X87_MACRO_ASSEMBLER_X87_H_ |
OLD | NEW |