| 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 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // ---------------------------------------------------------------------------- | 39 // ---------------------------------------------------------------------------- |
| 40 // Static helper functions | 40 // Static helper functions |
| 41 | 41 |
| 42 // Generate a MemOperand for loading a field from an object. | 42 // Generate a MemOperand for loading a field from an object. |
| 43 static inline MemOperand FieldMemOperand(Register object, int offset) { | 43 static inline MemOperand FieldMemOperand(Register object, int offset) { |
| 44 return MemOperand(object, offset - kHeapObjectTag); | 44 return MemOperand(object, offset - kHeapObjectTag); |
| 45 } | 45 } |
| 46 | 46 |
| 47 | 47 |
| 48 static inline Operand SmiUntagOperand(Register object) { |
| 49 return Operand(object, ASR, kSmiTagSize); |
| 50 } |
| 51 |
| 52 |
| 53 |
| 48 // Give alias names to registers | 54 // Give alias names to registers |
| 49 const Register cp = { 8 }; // JavaScript context pointer | 55 const Register cp = { 8 }; // JavaScript context pointer |
| 50 const Register roots = { 10 }; // Roots array pointer. | 56 const Register roots = { 10 }; // Roots array pointer. |
| 51 | 57 |
| 52 enum InvokeJSFlags { | 58 enum InvokeJSFlags { |
| 53 CALL_JS, | 59 CALL_JS, |
| 54 JUMP_JS | 60 JUMP_JS |
| 55 }; | 61 }; |
| 56 | 62 |
| 57 | 63 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 Register scratch = no_reg, | 114 Register scratch = no_reg, |
| 109 Condition cond = al); | 115 Condition cond = al); |
| 110 | 116 |
| 111 | 117 |
| 112 void And(Register dst, Register src1, const Operand& src2, | 118 void And(Register dst, Register src1, const Operand& src2, |
| 113 Condition cond = al); | 119 Condition cond = al); |
| 114 void Ubfx(Register dst, Register src, int lsb, int width, | 120 void Ubfx(Register dst, Register src, int lsb, int width, |
| 115 Condition cond = al); | 121 Condition cond = al); |
| 116 void Sbfx(Register dst, Register src, int lsb, int width, | 122 void Sbfx(Register dst, Register src, int lsb, int width, |
| 117 Condition cond = al); | 123 Condition cond = al); |
| 124 // The scratch register is not used for ARMv7. |
| 125 // scratch can be the same register as src (in which case it is trashed), but |
| 126 // not the same as dst. |
| 127 void Bfi(Register dst, |
| 128 Register src, |
| 129 Register scratch, |
| 130 int lsb, |
| 131 int width, |
| 132 Condition cond = al); |
| 118 void Bfc(Register dst, int lsb, int width, Condition cond = al); | 133 void Bfc(Register dst, int lsb, int width, Condition cond = al); |
| 119 void Usat(Register dst, int satpos, const Operand& src, | 134 void Usat(Register dst, int satpos, const Operand& src, |
| 120 Condition cond = al); | 135 Condition cond = al); |
| 121 | 136 |
| 122 void Call(Label* target); | 137 void Call(Label* target); |
| 123 void Move(Register dst, Handle<Object> value); | 138 void Move(Register dst, Handle<Object> value); |
| 124 // May do nothing if the registers are identical. | 139 // May do nothing if the registers are identical. |
| 125 void Move(Register dst, Register src); | 140 void Move(Register dst, Register src); |
| 126 // Jumps to the label at the index given by the Smi in "index". | 141 // Jumps to the label at the index given by the Smi in "index". |
| 127 void SmiJumpTable(Register index, Vector<Label*> targets); | 142 void SmiJumpTable(Register index, Vector<Label*> targets); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 } else { | 236 } else { |
| 222 stm(db_w, sp, src1.bit() | src2.bit(), cond); | 237 stm(db_w, sp, src1.bit() | src2.bit(), cond); |
| 223 Push(src3, src4, cond); | 238 Push(src3, src4, cond); |
| 224 } | 239 } |
| 225 } else { | 240 } else { |
| 226 str(src1, MemOperand(sp, 4, NegPreIndex), cond); | 241 str(src1, MemOperand(sp, 4, NegPreIndex), cond); |
| 227 Push(src2, src3, src4, cond); | 242 Push(src2, src3, src4, cond); |
| 228 } | 243 } |
| 229 } | 244 } |
| 230 | 245 |
| 246 // Pop two registers. Pops rightmost register first (from lower address). |
| 247 void Pop(Register src1, Register src2, Condition cond = al) { |
| 248 ASSERT(!src1.is(src2)); |
| 249 if (src1.code() > src2.code()) { |
| 250 ldm(ia_w, sp, src1.bit() | src2.bit(), cond); |
| 251 } else { |
| 252 ldr(src2, MemOperand(sp, 4, PostIndex), cond); |
| 253 ldr(src1, MemOperand(sp, 4, PostIndex), cond); |
| 254 } |
| 255 } |
| 256 |
| 231 // Push and pop the registers that can hold pointers, as defined by the | 257 // Push and pop the registers that can hold pointers, as defined by the |
| 232 // RegList constant kSafepointSavedRegisters. | 258 // RegList constant kSafepointSavedRegisters. |
| 233 void PushSafepointRegisters(); | 259 void PushSafepointRegisters(); |
| 234 void PopSafepointRegisters(); | 260 void PopSafepointRegisters(); |
| 235 void PushSafepointRegistersAndDoubles(); | 261 void PushSafepointRegistersAndDoubles(); |
| 236 void PopSafepointRegistersAndDoubles(); | 262 void PopSafepointRegistersAndDoubles(); |
| 237 void StoreToSafepointRegisterSlot(Register reg); | 263 // Store value in register src in the safepoint stack slot for |
| 238 void StoreToSafepointRegistersAndDoublesSlot(Register reg); | 264 // register dst. |
| 239 void LoadFromSafepointRegisterSlot(Register reg); | 265 void StoreToSafepointRegisterSlot(Register src, Register dst); |
| 240 static int SafepointRegisterStackIndex(int reg_code); | 266 void StoreToSafepointRegistersAndDoublesSlot(Register src, Register dst); |
| 241 static MemOperand SafepointRegisterSlot(Register reg); | 267 // Load the value of the src register from its safepoint stack slot |
| 242 static MemOperand SafepointRegistersAndDoublesSlot(Register reg); | 268 // into register dst. |
| 269 void LoadFromSafepointRegisterSlot(Register dst, Register src); |
| 243 | 270 |
| 244 // Load two consecutive registers with two consecutive memory locations. | 271 // Load two consecutive registers with two consecutive memory locations. |
| 245 void Ldrd(Register dst1, | 272 void Ldrd(Register dst1, |
| 246 Register dst2, | 273 Register dst2, |
| 247 const MemOperand& src, | 274 const MemOperand& src, |
| 248 Condition cond = al); | 275 Condition cond = al); |
| 249 | 276 |
| 250 // Store two consecutive registers to two consecutive memory locations. | 277 // Store two consecutive registers to two consecutive memory locations. |
| 251 void Strd(Register src1, | 278 void Strd(Register src1, |
| 252 Register src2, | 279 Register src2, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } | 311 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } |
| 285 | 312 |
| 286 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } | 313 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } |
| 287 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } | 314 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } |
| 288 | 315 |
| 289 // Enter exit frame. | 316 // Enter exit frame. |
| 290 // stack_space - extra stack space, used for alignment before call to C. | 317 // stack_space - extra stack space, used for alignment before call to C. |
| 291 void EnterExitFrame(bool save_doubles, int stack_space = 0); | 318 void EnterExitFrame(bool save_doubles, int stack_space = 0); |
| 292 | 319 |
| 293 // Leave the current exit frame. Expects the return value in r0. | 320 // Leave the current exit frame. Expects the return value in r0. |
| 294 void LeaveExitFrame(bool save_doubles); | 321 // Expect the number of values, pushed prior to the exit frame, to |
| 322 // remove in a register (or no_reg, if there is nothing to remove). |
| 323 void LeaveExitFrame(bool save_doubles, Register argument_count); |
| 295 | 324 |
| 296 // Get the actual activation frame alignment for target environment. | 325 // Get the actual activation frame alignment for target environment. |
| 297 static int ActivationFrameAlignment(); | 326 static int ActivationFrameAlignment(); |
| 298 | 327 |
| 299 void LoadContext(Register dst, int context_chain_length); | 328 void LoadContext(Register dst, int context_chain_length); |
| 300 | 329 |
| 301 void LoadGlobalFunction(int index, Register function); | 330 void LoadGlobalFunction(int index, Register function); |
| 302 | 331 |
| 303 // Load the initial map from the global function. The registers | 332 // Load the initial map from the global function. The registers |
| 304 // function and map can be the same, function is then overwritten. | 333 // function and map can be the same, function is then overwritten. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 | 387 |
| 359 // Push a new try handler and link into try handler chain. | 388 // Push a new try handler and link into try handler chain. |
| 360 // The return address must be passed in register lr. | 389 // The return address must be passed in register lr. |
| 361 // On exit, r0 contains TOS (code slot). | 390 // On exit, r0 contains TOS (code slot). |
| 362 void PushTryHandler(CodeLocation try_location, HandlerType type); | 391 void PushTryHandler(CodeLocation try_location, HandlerType type); |
| 363 | 392 |
| 364 // Unlink the stack handler on top of the stack from the try handler chain. | 393 // Unlink the stack handler on top of the stack from the try handler chain. |
| 365 // Must preserve the result register. | 394 // Must preserve the result register. |
| 366 void PopTryHandler(); | 395 void PopTryHandler(); |
| 367 | 396 |
| 397 // Passes thrown value (in r0) to the handler of top of the try handler chain. |
| 398 void Throw(Register value); |
| 399 |
| 400 // Propagates an uncatchable exception to the top of the current JS stack's |
| 401 // handler chain. |
| 402 void ThrowUncatchable(UncatchableExceptionType type, Register value); |
| 403 |
| 368 // --------------------------------------------------------------------------- | 404 // --------------------------------------------------------------------------- |
| 369 // Inline caching support | 405 // Inline caching support |
| 370 | 406 |
| 371 // Generate code for checking access rights - used for security checks | 407 // Generate code for checking access rights - used for security checks |
| 372 // on access to global objects across environments. The holder register | 408 // on access to global objects across environments. The holder register |
| 373 // is left untouched, whereas both scratch registers are clobbered. | 409 // is left untouched, whereas both scratch registers are clobbered. |
| 374 void CheckAccessGlobalProxy(Register holder_reg, | 410 void CheckAccessGlobalProxy(Register holder_reg, |
| 375 Register scratch, | 411 Register scratch, |
| 376 Label* miss); | 412 Label* miss); |
| 377 | 413 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 void AllocateHeapNumberWithValue(Register result, | 510 void AllocateHeapNumberWithValue(Register result, |
| 475 DwVfpRegister value, | 511 DwVfpRegister value, |
| 476 Register scratch1, | 512 Register scratch1, |
| 477 Register scratch2, | 513 Register scratch2, |
| 478 Register heap_number_map, | 514 Register heap_number_map, |
| 479 Label* gc_required); | 515 Label* gc_required); |
| 480 | 516 |
| 481 // Copies a fixed number of fields of heap objects from src to dst. | 517 // Copies a fixed number of fields of heap objects from src to dst. |
| 482 void CopyFields(Register dst, Register src, RegList temps, int field_count); | 518 void CopyFields(Register dst, Register src, RegList temps, int field_count); |
| 483 | 519 |
| 520 // Copies a number of bytes from src to dst. All registers are clobbered. On |
| 521 // exit src and dst will point to the place just after where the last byte was |
| 522 // read or written and length will be zero. |
| 523 void CopyBytes(Register src, |
| 524 Register dst, |
| 525 Register length, |
| 526 Register scratch); |
| 527 |
| 484 // --------------------------------------------------------------------------- | 528 // --------------------------------------------------------------------------- |
| 485 // Support functions. | 529 // Support functions. |
| 486 | 530 |
| 487 // Try to get function prototype of a function and puts the value in | 531 // Try to get function prototype of a function and puts the value in |
| 488 // the result register. Checks that the function really is a | 532 // the result register. Checks that the function really is a |
| 489 // function and jumps to the miss label if the fast checks fail. The | 533 // function and jumps to the miss label if the fast checks fail. The |
| 490 // function register will be untouched; the other registers may be | 534 // function register will be untouched; the other registers may be |
| 491 // clobbered. | 535 // clobbered. |
| 492 void TryGetFunctionPrototype(Register function, | 536 void TryGetFunctionPrototype(Register function, |
| 493 Register result, | 537 Register result, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 void IllegalOperation(int num_arguments); | 595 void IllegalOperation(int num_arguments); |
| 552 | 596 |
| 553 // Picks out an array index from the hash field. | 597 // Picks out an array index from the hash field. |
| 554 // Register use: | 598 // Register use: |
| 555 // hash - holds the index's hash. Clobbered. | 599 // hash - holds the index's hash. Clobbered. |
| 556 // index - holds the overwritten index on exit. | 600 // index - holds the overwritten index on exit. |
| 557 void IndexFromHash(Register hash, Register index); | 601 void IndexFromHash(Register hash, Register index); |
| 558 | 602 |
| 559 // Get the number of least significant bits from a register | 603 // Get the number of least significant bits from a register |
| 560 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits); | 604 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits); |
| 605 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits); |
| 561 | 606 |
| 562 // Uses VFP instructions to Convert a Smi to a double. | 607 // Uses VFP instructions to Convert a Smi to a double. |
| 563 void IntegerToDoubleConversionWithVFP3(Register inReg, | 608 void IntegerToDoubleConversionWithVFP3(Register inReg, |
| 564 Register outHighReg, | 609 Register outHighReg, |
| 565 Register outLowReg); | 610 Register outLowReg); |
| 566 | 611 |
| 567 // Load the value of a number object into a VFP double register. If the object | 612 // Load the value of a number object into a VFP double register. If the object |
| 568 // is not a number a jump to the label not_number is performed and the VFP | 613 // is not a number a jump to the label not_number is performed and the VFP |
| 569 // double register is unchanged. | 614 // double register is unchanged. |
| 570 void ObjectToDoubleVFPRegister( | 615 void ObjectToDoubleVFPRegister( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 589 // dest. If the HeapNumber does not fit into a 32bits signed integer branch | 634 // dest. If the HeapNumber does not fit into a 32bits signed integer branch |
| 590 // to not_int32 label. If VFP3 is available double_scratch is used but not | 635 // to not_int32 label. If VFP3 is available double_scratch is used but not |
| 591 // scratch2. | 636 // scratch2. |
| 592 void ConvertToInt32(Register source, | 637 void ConvertToInt32(Register source, |
| 593 Register dest, | 638 Register dest, |
| 594 Register scratch, | 639 Register scratch, |
| 595 Register scratch2, | 640 Register scratch2, |
| 596 DwVfpRegister double_scratch, | 641 DwVfpRegister double_scratch, |
| 597 Label *not_int32); | 642 Label *not_int32); |
| 598 | 643 |
| 644 // Truncates a double using a specific rounding mode. |
| 645 // Clears the z flag (ne condition) if an overflow occurs. |
| 646 // If exact_conversion is true, the z flag is also cleared if the conversion |
| 647 // was inexact, ie. if the double value could not be converted exactly |
| 648 // to a 32bit integer. |
| 649 void EmitVFPTruncate(VFPRoundingMode rounding_mode, |
| 650 SwVfpRegister result, |
| 651 DwVfpRegister double_input, |
| 652 Register scratch1, |
| 653 Register scratch2, |
| 654 CheckForInexactConversion check |
| 655 = kDontCheckForInexactConversion); |
| 656 |
| 599 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz | 657 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz |
| 600 // instruction. On pre-ARM5 hardware this routine gives the wrong answer | 658 // instruction. On pre-ARM5 hardware this routine gives the wrong answer |
| 601 // for 0 (31 instead of 32). Source and scratch can be the same in which case | 659 // for 0 (31 instead of 32). Source and scratch can be the same in which case |
| 602 // the source is clobbered. Source and zeros can also be the same in which | 660 // the source is clobbered. Source and zeros can also be the same in which |
| 603 // case scratch should be a different register. | 661 // case scratch should be a different register. |
| 604 void CountLeadingZeros(Register zeros, | 662 void CountLeadingZeros(Register zeros, |
| 605 Register source, | 663 Register source, |
| 606 Register scratch); | 664 Register scratch); |
| 607 | 665 |
| 608 // --------------------------------------------------------------------------- | 666 // --------------------------------------------------------------------------- |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 void PrepareCallCFunction(int num_arguments, Register scratch); | 718 void PrepareCallCFunction(int num_arguments, Register scratch); |
| 661 | 719 |
| 662 // Calls a C function and cleans up the space for arguments allocated | 720 // Calls a C function and cleans up the space for arguments allocated |
| 663 // by PrepareCallCFunction. The called function is not allowed to trigger a | 721 // by PrepareCallCFunction. The called function is not allowed to trigger a |
| 664 // garbage collection, since that might move the code and invalidate the | 722 // garbage collection, since that might move the code and invalidate the |
| 665 // return address (unless this is somehow accounted for by the called | 723 // return address (unless this is somehow accounted for by the called |
| 666 // function). | 724 // function). |
| 667 void CallCFunction(ExternalReference function, int num_arguments); | 725 void CallCFunction(ExternalReference function, int num_arguments); |
| 668 void CallCFunction(Register function, Register scratch, int num_arguments); | 726 void CallCFunction(Register function, Register scratch, int num_arguments); |
| 669 | 727 |
| 728 void GetCFunctionDoubleResult(const DoubleRegister dst); |
| 729 |
| 670 // Calls an API function. Allocates HandleScope, extracts returned value | 730 // Calls an API function. Allocates HandleScope, extracts returned value |
| 671 // from handle and propagates exceptions. Restores context. | 731 // from handle and propagates exceptions. Restores context. |
| 672 // stack_space - space to be unwound on exit (includes the call js | 732 // stack_space - space to be unwound on exit (includes the call js |
| 673 // arguments space and the additional space allocated for the fast call). | 733 // arguments space and the additional space allocated for the fast call). |
| 674 MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function, | 734 MaybeObject* TryCallApiFunctionAndReturn(ExternalReference function, |
| 675 int stack_space); | 735 int stack_space); |
| 676 | 736 |
| 677 // Jump to a runtime routine. | 737 // Jump to a runtime routine. |
| 678 void JumpToExternalReference(const ExternalReference& builtin); | 738 void JumpToExternalReference(const ExternalReference& builtin); |
| 679 | 739 |
| 680 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext); | 740 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext); |
| 681 | 741 |
| 682 // Invoke specified builtin JavaScript function. Adds an entry to | 742 // Invoke specified builtin JavaScript function. Adds an entry to |
| 683 // the unresolved list if the name does not resolve. | 743 // the unresolved list if the name does not resolve. |
| 684 void InvokeBuiltin(Builtins::JavaScript id, | 744 void InvokeBuiltin(Builtins::JavaScript id, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 // Try to convert int32 to smi. If the value is to large, preserve | 811 // Try to convert int32 to smi. If the value is to large, preserve |
| 752 // the original value and jump to not_a_smi. Destroys scratch and | 812 // the original value and jump to not_a_smi. Destroys scratch and |
| 753 // sets flags. | 813 // sets flags. |
| 754 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) { | 814 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) { |
| 755 mov(scratch, reg); | 815 mov(scratch, reg); |
| 756 SmiTag(scratch, SetCC); | 816 SmiTag(scratch, SetCC); |
| 757 b(vs, not_a_smi); | 817 b(vs, not_a_smi); |
| 758 mov(reg, scratch); | 818 mov(reg, scratch); |
| 759 } | 819 } |
| 760 | 820 |
| 761 void SmiUntag(Register reg) { | 821 void SmiUntag(Register reg, SBit s = LeaveCC) { |
| 762 mov(reg, Operand(reg, ASR, kSmiTagSize)); | 822 mov(reg, Operand(reg, ASR, kSmiTagSize), s); |
| 763 } | 823 } |
| 764 void SmiUntag(Register dst, Register src) { | 824 void SmiUntag(Register dst, Register src, SBit s = LeaveCC) { |
| 765 mov(dst, Operand(src, ASR, kSmiTagSize)); | 825 mov(dst, Operand(src, ASR, kSmiTagSize), s); |
| 766 } | 826 } |
| 767 | 827 |
| 768 // Jump the register contains a smi. | 828 // Jump the register contains a smi. |
| 769 inline void JumpIfSmi(Register value, Label* smi_label) { | 829 inline void JumpIfSmi(Register value, Label* smi_label) { |
| 770 tst(value, Operand(kSmiTagMask)); | 830 tst(value, Operand(kSmiTagMask)); |
| 771 b(eq, smi_label); | 831 b(eq, smi_label); |
| 772 } | 832 } |
| 773 // Jump if either of the registers contain a non-smi. | 833 // Jump if either of the registers contain a non-smi. |
| 774 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { | 834 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { |
| 775 tst(value, Operand(kSmiTagMask)); | 835 tst(value, Operand(kSmiTagMask)); |
| 776 b(ne, not_smi_label); | 836 b(ne, not_smi_label); |
| 777 } | 837 } |
| 778 // Jump if either of the registers contain a non-smi. | 838 // Jump if either of the registers contain a non-smi. |
| 779 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); | 839 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); |
| 780 // Jump if either of the registers contain a smi. | 840 // Jump if either of the registers contain a smi. |
| 781 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); | 841 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); |
| 782 | 842 |
| 783 // Abort execution if argument is a smi. Used in debug code. | 843 // Abort execution if argument is a smi. Used in debug code. |
| 784 void AbortIfSmi(Register object); | 844 void AbortIfSmi(Register object); |
| 785 void AbortIfNotSmi(Register object); | 845 void AbortIfNotSmi(Register object); |
| 786 | 846 |
| 847 // Abort execution if argument is a string. Used in debug code. |
| 848 void AbortIfNotString(Register object); |
| 849 |
| 787 // Abort execution if argument is not the root value with the given index. | 850 // Abort execution if argument is not the root value with the given index. |
| 788 void AbortIfNotRootValue(Register src, | 851 void AbortIfNotRootValue(Register src, |
| 789 Heap::RootListIndex root_value_index, | 852 Heap::RootListIndex root_value_index, |
| 790 const char* message); | 853 const char* message); |
| 791 | 854 |
| 792 // --------------------------------------------------------------------------- | 855 // --------------------------------------------------------------------------- |
| 793 // HeapNumber utilities | 856 // HeapNumber utilities |
| 794 | 857 |
| 795 void JumpIfNotHeapNumber(Register object, | 858 void JumpIfNotHeapNumber(Register object, |
| 796 Register heap_number_map, | 859 Register heap_number_map, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 // Activation support. | 925 // Activation support. |
| 863 void EnterFrame(StackFrame::Type type); | 926 void EnterFrame(StackFrame::Type type); |
| 864 void LeaveFrame(StackFrame::Type type); | 927 void LeaveFrame(StackFrame::Type type); |
| 865 | 928 |
| 866 void InitializeNewString(Register string, | 929 void InitializeNewString(Register string, |
| 867 Register length, | 930 Register length, |
| 868 Heap::RootListIndex map_index, | 931 Heap::RootListIndex map_index, |
| 869 Register scratch1, | 932 Register scratch1, |
| 870 Register scratch2); | 933 Register scratch2); |
| 871 | 934 |
| 935 // Compute memory operands for safepoint stack slots. |
| 936 static int SafepointRegisterStackIndex(int reg_code); |
| 937 MemOperand SafepointRegisterSlot(Register reg); |
| 938 MemOperand SafepointRegistersAndDoublesSlot(Register reg); |
| 939 |
| 872 bool generating_stub_; | 940 bool generating_stub_; |
| 873 bool allow_stub_calls_; | 941 bool allow_stub_calls_; |
| 874 // This handle will be patched with the code object on installation. | 942 // This handle will be patched with the code object on installation. |
| 875 Handle<Object> code_object_; | 943 Handle<Object> code_object_; |
| 944 |
| 945 // Needs access to SafepointRegisterStackIndex for optimized frame |
| 946 // traversal. |
| 947 friend class OptimizedFrame; |
| 876 }; | 948 }; |
| 877 | 949 |
| 878 | 950 |
| 879 #ifdef ENABLE_DEBUGGER_SUPPORT | 951 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 880 // The code patcher is used to patch (typically) small parts of code e.g. for | 952 // The code patcher is used to patch (typically) small parts of code e.g. for |
| 881 // debugging and other types of instrumentation. When using the code patcher | 953 // debugging and other types of instrumentation. When using the code patcher |
| 882 // the exact number of bytes specified must be emitted. It is not legal to emit | 954 // the exact number of bytes specified must be emitted. It is not legal to emit |
| 883 // relocation information. If any of these constraints are violated it causes | 955 // relocation information. If any of these constraints are violated it causes |
| 884 // an assertion to fail. | 956 // an assertion to fail. |
| 885 class CodePatcher { | 957 class CodePatcher { |
| 886 public: | 958 public: |
| 887 CodePatcher(byte* address, int instructions); | 959 CodePatcher(byte* address, int instructions); |
| 888 virtual ~CodePatcher(); | 960 virtual ~CodePatcher(); |
| 889 | 961 |
| 890 // Macro assembler to emit code. | 962 // Macro assembler to emit code. |
| 891 MacroAssembler* masm() { return &masm_; } | 963 MacroAssembler* masm() { return &masm_; } |
| 892 | 964 |
| 893 // Emit an instruction directly. | 965 // Emit an instruction directly. |
| 894 void Emit(Instr x); | 966 void Emit(Instr instr); |
| 895 | 967 |
| 896 // Emit an address directly. | 968 // Emit an address directly. |
| 897 void Emit(Address addr); | 969 void Emit(Address addr); |
| 898 | 970 |
| 971 // Emit the condition part of an instruction leaving the rest of the current |
| 972 // instruction unchanged. |
| 973 void EmitCondition(Condition cond); |
| 974 |
| 899 private: | 975 private: |
| 900 byte* address_; // The address of the code being patched. | 976 byte* address_; // The address of the code being patched. |
| 901 int instructions_; // Number of instructions of the expected patch size. | 977 int instructions_; // Number of instructions of the expected patch size. |
| 902 int size_; // Number of bytes of the expected patch size. | 978 int size_; // Number of bytes of the expected patch size. |
| 903 MacroAssembler masm_; // Macro assembler used to generate the code. | 979 MacroAssembler masm_; // Macro assembler used to generate the code. |
| 904 }; | 980 }; |
| 905 #endif // ENABLE_DEBUGGER_SUPPORT | 981 #endif // ENABLE_DEBUGGER_SUPPORT |
| 906 | 982 |
| 907 | 983 |
| 908 // Helper class for generating code or data associated with the code | 984 // Helper class for generating code or data associated with the code |
| (...skipping 26 matching lines...) Expand all Loading... |
| 935 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) | 1011 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) |
| 936 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> | 1012 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> |
| 937 #else | 1013 #else |
| 938 #define ACCESS_MASM(masm) masm-> | 1014 #define ACCESS_MASM(masm) masm-> |
| 939 #endif | 1015 #endif |
| 940 | 1016 |
| 941 | 1017 |
| 942 } } // namespace v8::internal | 1018 } } // namespace v8::internal |
| 943 | 1019 |
| 944 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_ | 1020 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_ |
| OLD | NEW |