Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(871)

Side by Side Diff: src/arm/macro-assembler-arm.h

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-gap-resolver-arm.cc ('k') | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 16 matching lines...) Expand all
27 27
28 #ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_ 28 #ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_
29 #define V8_ARM_MACRO_ASSEMBLER_ARM_H_ 29 #define V8_ARM_MACRO_ASSEMBLER_ARM_H_
30 30
31 #include "assembler.h" 31 #include "assembler.h"
32 32
33 namespace v8 { 33 namespace v8 {
34 namespace internal { 34 namespace internal {
35 35
36 // Forward declaration. 36 // Forward declaration.
37 class PostCallGenerator; 37 class CallWrapper;
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
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 // MacroAssembler implements a collection of frequently used macros. 90 // MacroAssembler implements a collection of frequently used macros.
91 class MacroAssembler: public Assembler { 91 class MacroAssembler: public Assembler {
92 public: 92 public:
93 MacroAssembler(void* buffer, int size); 93 MacroAssembler(void* buffer, int size);
94 94
95 // Jump, Call, and Ret pseudo instructions implementing inter-working. 95 // Jump, Call, and Ret pseudo instructions implementing inter-working.
96 void Jump(Register target, Condition cond = al); 96 void Jump(Register target, Condition cond = al);
97 void Jump(byte* target, RelocInfo::Mode rmode, Condition cond = al); 97 void Jump(byte* target, RelocInfo::Mode rmode, Condition cond = al);
98 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al); 98 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
99 int CallSize(Register target, Condition cond = al);
99 void Call(Register target, Condition cond = al); 100 void Call(Register target, Condition cond = al);
101 int CallSize(byte* target, RelocInfo::Mode rmode, Condition cond = al);
100 void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al); 102 void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al);
103 int CallSize(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
101 void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al); 104 void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
102 void Ret(Condition cond = al); 105 void Ret(Condition cond = al);
103 106
104 // Emit code to discard a non-negative number of pointer-sized elements 107 // Emit code to discard a non-negative number of pointer-sized elements
105 // from the stack, clobbering only the sp register. 108 // from the stack, clobbering only the sp register.
106 void Drop(int count, Condition cond = al); 109 void Drop(int count, Condition cond = al);
107 110
108 void Ret(int drop, Condition cond = al); 111 void Ret(int drop, Condition cond = al);
109 112
110 // Swap two registers. If the scratch register is omitted then a slightly 113 // Swap two registers. If the scratch register is omitted then a slightly
111 // less efficient form using xor instead of mov is emitted. 114 // less efficient form using xor instead of mov is emitted.
112 void Swap(Register reg1, 115 void Swap(Register reg1,
113 Register reg2, 116 Register reg2,
114 Register scratch = no_reg, 117 Register scratch = no_reg,
115 Condition cond = al); 118 Condition cond = al);
116 119
117 120
118 void And(Register dst, Register src1, const Operand& src2, 121 void And(Register dst, Register src1, const Operand& src2,
119 Condition cond = al); 122 Condition cond = al);
120 void Ubfx(Register dst, Register src, int lsb, int width, 123 void Ubfx(Register dst, Register src, int lsb, int width,
121 Condition cond = al); 124 Condition cond = al);
122 void Sbfx(Register dst, Register src, int lsb, int width, 125 void Sbfx(Register dst, Register src, int lsb, int width,
123 Condition cond = al); 126 Condition cond = al);
127 // The scratch register is not used for ARMv7.
128 // scratch can be the same register as src (in which case it is trashed), but
129 // not the same as dst.
130 void Bfi(Register dst,
131 Register src,
132 Register scratch,
133 int lsb,
134 int width,
135 Condition cond = al);
124 void Bfc(Register dst, int lsb, int width, Condition cond = al); 136 void Bfc(Register dst, int lsb, int width, Condition cond = al);
125 void Usat(Register dst, int satpos, const Operand& src, 137 void Usat(Register dst, int satpos, const Operand& src,
126 Condition cond = al); 138 Condition cond = al);
127 139
128 void Call(Label* target); 140 void Call(Label* target);
129 void Move(Register dst, Handle<Object> value); 141 void Move(Register dst, Handle<Object> value);
130 // May do nothing if the registers are identical. 142 // May do nothing if the registers are identical.
131 void Move(Register dst, Register src); 143 void Move(Register dst, Register src);
132 // Jumps to the label at the index given by the Smi in "index". 144 // Jumps to the label at the index given by the Smi in "index".
133 void SmiJumpTable(Register index, Vector<Label*> targets); 145 void SmiJumpTable(Register index, Vector<Label*> targets);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } else { 240 } else {
229 stm(db_w, sp, src1.bit() | src2.bit(), cond); 241 stm(db_w, sp, src1.bit() | src2.bit(), cond);
230 Push(src3, src4, cond); 242 Push(src3, src4, cond);
231 } 243 }
232 } else { 244 } else {
233 str(src1, MemOperand(sp, 4, NegPreIndex), cond); 245 str(src1, MemOperand(sp, 4, NegPreIndex), cond);
234 Push(src2, src3, src4, cond); 246 Push(src2, src3, src4, cond);
235 } 247 }
236 } 248 }
237 249
250 // Pop two registers. Pops rightmost register first (from lower address).
251 void Pop(Register src1, Register src2, Condition cond = al) {
252 ASSERT(!src1.is(src2));
253 if (src1.code() > src2.code()) {
254 ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
255 } else {
256 ldr(src2, MemOperand(sp, 4, PostIndex), cond);
257 ldr(src1, MemOperand(sp, 4, PostIndex), cond);
258 }
259 }
260
238 // Push and pop the registers that can hold pointers, as defined by the 261 // Push and pop the registers that can hold pointers, as defined by the
239 // RegList constant kSafepointSavedRegisters. 262 // RegList constant kSafepointSavedRegisters.
240 void PushSafepointRegisters(); 263 void PushSafepointRegisters();
241 void PopSafepointRegisters(); 264 void PopSafepointRegisters();
242 void PushSafepointRegistersAndDoubles(); 265 void PushSafepointRegistersAndDoubles();
243 void PopSafepointRegistersAndDoubles(); 266 void PopSafepointRegistersAndDoubles();
244 void StoreToSafepointRegisterSlot(Register reg); 267 // Store value in register src in the safepoint stack slot for
245 void StoreToSafepointRegistersAndDoublesSlot(Register reg); 268 // register dst.
246 void LoadFromSafepointRegisterSlot(Register reg); 269 void StoreToSafepointRegisterSlot(Register src, Register dst);
247 static int SafepointRegisterStackIndex(int reg_code); 270 void StoreToSafepointRegistersAndDoublesSlot(Register src, Register dst);
248 static MemOperand SafepointRegisterSlot(Register reg); 271 // Load the value of the src register from its safepoint stack slot
249 static MemOperand SafepointRegistersAndDoublesSlot(Register reg); 272 // into register dst.
273 void LoadFromSafepointRegisterSlot(Register dst, Register src);
250 274
251 // Load two consecutive registers with two consecutive memory locations. 275 // Load two consecutive registers with two consecutive memory locations.
252 void Ldrd(Register dst1, 276 void Ldrd(Register dst1,
253 Register dst2, 277 Register dst2,
254 const MemOperand& src, 278 const MemOperand& src,
255 Condition cond = al); 279 Condition cond = al);
256 280
257 // Store two consecutive registers to two consecutive memory locations. 281 // Store two consecutive registers to two consecutive memory locations.
258 void Strd(Register src1, 282 void Strd(Register src1,
259 Register src2, 283 Register src2,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 Register scratch); 340 Register scratch);
317 341
318 // --------------------------------------------------------------------------- 342 // ---------------------------------------------------------------------------
319 // JavaScript invokes 343 // JavaScript invokes
320 344
321 // Invoke the JavaScript function code by either calling or jumping. 345 // Invoke the JavaScript function code by either calling or jumping.
322 void InvokeCode(Register code, 346 void InvokeCode(Register code,
323 const ParameterCount& expected, 347 const ParameterCount& expected,
324 const ParameterCount& actual, 348 const ParameterCount& actual,
325 InvokeFlag flag, 349 InvokeFlag flag,
326 PostCallGenerator* post_call_generator = NULL); 350 CallWrapper* call_wrapper = NULL);
327 351
328 void InvokeCode(Handle<Code> code, 352 void InvokeCode(Handle<Code> code,
329 const ParameterCount& expected, 353 const ParameterCount& expected,
330 const ParameterCount& actual, 354 const ParameterCount& actual,
331 RelocInfo::Mode rmode, 355 RelocInfo::Mode rmode,
332 InvokeFlag flag); 356 InvokeFlag flag);
333 357
334 // Invoke the JavaScript function in the given register. Changes the 358 // Invoke the JavaScript function in the given register. Changes the
335 // current context to the context in the function before invoking. 359 // current context to the context in the function before invoking.
336 void InvokeFunction(Register function, 360 void InvokeFunction(Register function,
337 const ParameterCount& actual, 361 const ParameterCount& actual,
338 InvokeFlag flag, 362 InvokeFlag flag,
339 PostCallGenerator* post_call_generator = NULL); 363 CallWrapper* call_wrapper = NULL);
340 364
341 void InvokeFunction(JSFunction* function, 365 void InvokeFunction(JSFunction* function,
342 const ParameterCount& actual, 366 const ParameterCount& actual,
343 InvokeFlag flag); 367 InvokeFlag flag);
344 368
345 void IsObjectJSObjectType(Register heap_object, 369 void IsObjectJSObjectType(Register heap_object,
346 Register map, 370 Register map,
347 Register scratch, 371 Register scratch,
348 Label* fail); 372 Label* fail);
349 373
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 void AllocateHeapNumberWithValue(Register result, 514 void AllocateHeapNumberWithValue(Register result,
491 DwVfpRegister value, 515 DwVfpRegister value,
492 Register scratch1, 516 Register scratch1,
493 Register scratch2, 517 Register scratch2,
494 Register heap_number_map, 518 Register heap_number_map,
495 Label* gc_required); 519 Label* gc_required);
496 520
497 // Copies a fixed number of fields of heap objects from src to dst. 521 // Copies a fixed number of fields of heap objects from src to dst.
498 void CopyFields(Register dst, Register src, RegList temps, int field_count); 522 void CopyFields(Register dst, Register src, RegList temps, int field_count);
499 523
524 // Copies a number of bytes from src to dst. All registers are clobbered. On
525 // exit src and dst will point to the place just after where the last byte was
526 // read or written and length will be zero.
527 void CopyBytes(Register src,
528 Register dst,
529 Register length,
530 Register scratch);
531
500 // --------------------------------------------------------------------------- 532 // ---------------------------------------------------------------------------
501 // Support functions. 533 // Support functions.
502 534
503 // Try to get function prototype of a function and puts the value in 535 // Try to get function prototype of a function and puts the value in
504 // the result register. Checks that the function really is a 536 // the result register. Checks that the function really is a
505 // function and jumps to the miss label if the fast checks fail. The 537 // function and jumps to the miss label if the fast checks fail. The
506 // function register will be untouched; the other registers may be 538 // function register will be untouched; the other registers may be
507 // clobbered. 539 // clobbered.
508 void TryGetFunctionPrototype(Register function, 540 void TryGetFunctionPrototype(Register function,
509 Register result, 541 Register result,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 Label* fail, 574 Label* fail,
543 bool is_heap_object); 575 bool is_heap_object);
544 576
545 void CheckMap(Register obj, 577 void CheckMap(Register obj,
546 Register scratch, 578 Register scratch,
547 Heap::RootListIndex index, 579 Heap::RootListIndex index,
548 Label* fail, 580 Label* fail,
549 bool is_heap_object); 581 bool is_heap_object);
550 582
551 583
584 // Compare the object in a register to a value from the root list.
585 // Uses the ip register as scratch.
586 void CompareRoot(Register obj, Heap::RootListIndex index);
587
588
552 // Load and check the instance type of an object for being a string. 589 // Load and check the instance type of an object for being a string.
553 // Loads the type into the second argument register. 590 // Loads the type into the second argument register.
554 // Returns a condition that will be enabled if the object was a string. 591 // Returns a condition that will be enabled if the object was a string.
555 Condition IsObjectStringType(Register obj, 592 Condition IsObjectStringType(Register obj,
556 Register type) { 593 Register type) {
557 ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset)); 594 ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset));
558 ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); 595 ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
559 tst(type, Operand(kIsNotStringMask)); 596 tst(type, Operand(kIsNotStringMask));
560 ASSERT_EQ(0, kStringTag); 597 ASSERT_EQ(0, kStringTag);
561 return eq; 598 return eq;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 // dest. If the HeapNumber does not fit into a 32bits signed integer branch 643 // dest. If the HeapNumber does not fit into a 32bits signed integer branch
607 // to not_int32 label. If VFP3 is available double_scratch is used but not 644 // to not_int32 label. If VFP3 is available double_scratch is used but not
608 // scratch2. 645 // scratch2.
609 void ConvertToInt32(Register source, 646 void ConvertToInt32(Register source,
610 Register dest, 647 Register dest,
611 Register scratch, 648 Register scratch,
612 Register scratch2, 649 Register scratch2,
613 DwVfpRegister double_scratch, 650 DwVfpRegister double_scratch,
614 Label *not_int32); 651 Label *not_int32);
615 652
653 // Truncates a double using a specific rounding mode.
654 // Clears the z flag (ne condition) if an overflow occurs.
655 // If exact_conversion is true, the z flag is also cleared if the conversion
656 // was inexact, ie. if the double value could not be converted exactly
657 // to a 32bit integer.
658 void EmitVFPTruncate(VFPRoundingMode rounding_mode,
659 SwVfpRegister result,
660 DwVfpRegister double_input,
661 Register scratch1,
662 Register scratch2,
663 CheckForInexactConversion check
664 = kDontCheckForInexactConversion);
665
666 // Helper for EmitECMATruncate.
667 // This will truncate a floating-point value outside of the singed 32bit
668 // integer range to a 32bit signed integer.
669 // Expects the double value loaded in input_high and input_low.
670 // Exits with the answer in 'result'.
671 // Note that this code does not work for values in the 32bit range!
672 void EmitOutOfInt32RangeTruncate(Register result,
673 Register input_high,
674 Register input_low,
675 Register scratch);
676
677 // Performs a truncating conversion of a floating point number as used by
678 // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
679 // Exits with 'result' holding the answer and all other registers clobbered.
680 void EmitECMATruncate(Register result,
681 DwVfpRegister double_input,
682 SwVfpRegister single_scratch,
683 Register scratch,
684 Register scratch2,
685 Register scratch3);
686
616 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz 687 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
617 // instruction. On pre-ARM5 hardware this routine gives the wrong answer 688 // instruction. On pre-ARM5 hardware this routine gives the wrong answer
618 // for 0 (31 instead of 32). Source and scratch can be the same in which case 689 // for 0 (31 instead of 32). Source and scratch can be the same in which case
619 // the source is clobbered. Source and zeros can also be the same in which 690 // the source is clobbered. Source and zeros can also be the same in which
620 // case scratch should be a different register. 691 // case scratch should be a different register.
621 void CountLeadingZeros(Register zeros, 692 void CountLeadingZeros(Register zeros,
622 Register source, 693 Register source,
623 Register scratch); 694 Register scratch);
624 695
625 // --------------------------------------------------------------------------- 696 // ---------------------------------------------------------------------------
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 void PrepareCallCFunction(int num_arguments, Register scratch); 748 void PrepareCallCFunction(int num_arguments, Register scratch);
678 749
679 // Calls a C function and cleans up the space for arguments allocated 750 // Calls a C function and cleans up the space for arguments allocated
680 // by PrepareCallCFunction. The called function is not allowed to trigger a 751 // by PrepareCallCFunction. The called function is not allowed to trigger a
681 // garbage collection, since that might move the code and invalidate the 752 // garbage collection, since that might move the code and invalidate the
682 // return address (unless this is somehow accounted for by the called 753 // return address (unless this is somehow accounted for by the called
683 // function). 754 // function).
684 void CallCFunction(ExternalReference function, int num_arguments); 755 void CallCFunction(ExternalReference function, int num_arguments);
685 void CallCFunction(Register function, int num_arguments); 756 void CallCFunction(Register function, int num_arguments);
686 757
758 void GetCFunctionDoubleResult(const DoubleRegister dst);
759
687 // Calls an API function. Allocates HandleScope, extracts returned value 760 // Calls an API function. Allocates HandleScope, extracts returned value
688 // from handle and propagates exceptions. Restores context. 761 // from handle and propagates exceptions. Restores context.
689 // stack_space - space to be unwound on exit (includes the call js 762 // stack_space - space to be unwound on exit (includes the call js
690 // arguments space and the additional space allocated for the fast call). 763 // arguments space and the additional space allocated for the fast call).
691 MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function, 764 MaybeObject* TryCallApiFunctionAndReturn(ExternalReference function,
692 int stack_space); 765 int stack_space);
693 766
694 // Jump to a runtime routine. 767 // Jump to a runtime routine.
695 void JumpToExternalReference(const ExternalReference& builtin); 768 void JumpToExternalReference(const ExternalReference& builtin);
696 769
697 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext); 770 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext);
698 771
699 // Invoke specified builtin JavaScript function. Adds an entry to 772 // Invoke specified builtin JavaScript function. Adds an entry to
700 // the unresolved list if the name does not resolve. 773 // the unresolved list if the name does not resolve.
701 void InvokeBuiltin(Builtins::JavaScript id, 774 void InvokeBuiltin(Builtins::JavaScript id,
702 InvokeJSFlags flags, 775 InvokeJSFlags flags,
703 PostCallGenerator* post_call_generator = NULL); 776 CallWrapper* call_wrapper = NULL);
704 777
705 // Store the code object for the given builtin in the target register and 778 // Store the code object for the given builtin in the target register and
706 // setup the function in r1. 779 // setup the function in r1.
707 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 780 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
708 781
709 // Store the function for the given builtin in the target register. 782 // Store the function for the given builtin in the target register.
710 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 783 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
711 784
712 Handle<Object> CodeObject() { return code_object_; } 785 Handle<Object> CodeObject() { return code_object_; }
713 786
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 // Try to convert int32 to smi. If the value is to large, preserve 841 // Try to convert int32 to smi. If the value is to large, preserve
769 // the original value and jump to not_a_smi. Destroys scratch and 842 // the original value and jump to not_a_smi. Destroys scratch and
770 // sets flags. 843 // sets flags.
771 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) { 844 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
772 mov(scratch, reg); 845 mov(scratch, reg);
773 SmiTag(scratch, SetCC); 846 SmiTag(scratch, SetCC);
774 b(vs, not_a_smi); 847 b(vs, not_a_smi);
775 mov(reg, scratch); 848 mov(reg, scratch);
776 } 849 }
777 850
778 void SmiUntag(Register reg) { 851 void SmiUntag(Register reg, SBit s = LeaveCC) {
779 mov(reg, Operand(reg, ASR, kSmiTagSize)); 852 mov(reg, Operand(reg, ASR, kSmiTagSize), s);
780 } 853 }
781 void SmiUntag(Register dst, Register src) { 854 void SmiUntag(Register dst, Register src, SBit s = LeaveCC) {
782 mov(dst, Operand(src, ASR, kSmiTagSize)); 855 mov(dst, Operand(src, ASR, kSmiTagSize), s);
783 } 856 }
784 857
785 // Jump the register contains a smi. 858 // Jump the register contains a smi.
786 inline void JumpIfSmi(Register value, Label* smi_label) { 859 inline void JumpIfSmi(Register value, Label* smi_label) {
787 tst(value, Operand(kSmiTagMask)); 860 tst(value, Operand(kSmiTagMask));
788 b(eq, smi_label); 861 b(eq, smi_label);
789 } 862 }
790 // Jump if either of the registers contain a non-smi. 863 // Jump if either of the registers contain a non-smi.
791 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { 864 inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
792 tst(value, Operand(kSmiTagMask)); 865 tst(value, Operand(kSmiTagMask));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 // Patching helpers. 929 // Patching helpers.
857 930
858 // Get the location of a relocated constant (its address in the constant pool) 931 // Get the location of a relocated constant (its address in the constant pool)
859 // from its load site. 932 // from its load site.
860 void GetRelocatedValueLocation(Register ldr_location, 933 void GetRelocatedValueLocation(Register ldr_location,
861 Register result); 934 Register result);
862 935
863 936
864 private: 937 private:
865 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 938 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
939 int CallSize(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
866 void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 940 void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
867 941
868 // Helper functions for generating invokes. 942 // Helper functions for generating invokes.
869 void InvokePrologue(const ParameterCount& expected, 943 void InvokePrologue(const ParameterCount& expected,
870 const ParameterCount& actual, 944 const ParameterCount& actual,
871 Handle<Code> code_constant, 945 Handle<Code> code_constant,
872 Register code_reg, 946 Register code_reg,
873 Label* done, 947 Label* done,
874 InvokeFlag flag, 948 InvokeFlag flag,
875 PostCallGenerator* post_call_generator = NULL); 949 CallWrapper* call_wrapper = NULL);
876 950
877 // Activation support. 951 // Activation support.
878 void EnterFrame(StackFrame::Type type); 952 void EnterFrame(StackFrame::Type type);
879 void LeaveFrame(StackFrame::Type type); 953 void LeaveFrame(StackFrame::Type type);
880 954
881 void InitializeNewString(Register string, 955 void InitializeNewString(Register string,
882 Register length, 956 Register length,
883 Heap::RootListIndex map_index, 957 Heap::RootListIndex map_index,
884 Register scratch1, 958 Register scratch1,
885 Register scratch2); 959 Register scratch2);
886 960
961 // Compute memory operands for safepoint stack slots.
962 static int SafepointRegisterStackIndex(int reg_code);
963 MemOperand SafepointRegisterSlot(Register reg);
964 MemOperand SafepointRegistersAndDoublesSlot(Register reg);
965
887 bool generating_stub_; 966 bool generating_stub_;
888 bool allow_stub_calls_; 967 bool allow_stub_calls_;
889 // This handle will be patched with the code object on installation. 968 // This handle will be patched with the code object on installation.
890 Handle<Object> code_object_; 969 Handle<Object> code_object_;
970
971 // Needs access to SafepointRegisterStackIndex for optimized frame
972 // traversal.
973 friend class OptimizedFrame;
891 }; 974 };
892 975
893 976
894 #ifdef ENABLE_DEBUGGER_SUPPORT 977 #ifdef ENABLE_DEBUGGER_SUPPORT
895 // The code patcher is used to patch (typically) small parts of code e.g. for 978 // The code patcher is used to patch (typically) small parts of code e.g. for
896 // debugging and other types of instrumentation. When using the code patcher 979 // debugging and other types of instrumentation. When using the code patcher
897 // the exact number of bytes specified must be emitted. It is not legal to emit 980 // the exact number of bytes specified must be emitted. It is not legal to emit
898 // relocation information. If any of these constraints are violated it causes 981 // relocation information. If any of these constraints are violated it causes
899 // an assertion to fail. 982 // an assertion to fail.
900 class CodePatcher { 983 class CodePatcher {
(...skipping 19 matching lines...) Expand all
920 int instructions_; // Number of instructions of the expected patch size. 1003 int instructions_; // Number of instructions of the expected patch size.
921 int size_; // Number of bytes of the expected patch size. 1004 int size_; // Number of bytes of the expected patch size.
922 MacroAssembler masm_; // Macro assembler used to generate the code. 1005 MacroAssembler masm_; // Macro assembler used to generate the code.
923 }; 1006 };
924 #endif // ENABLE_DEBUGGER_SUPPORT 1007 #endif // ENABLE_DEBUGGER_SUPPORT
925 1008
926 1009
927 // Helper class for generating code or data associated with the code 1010 // Helper class for generating code or data associated with the code
928 // right after a call instruction. As an example this can be used to 1011 // right after a call instruction. As an example this can be used to
929 // generate safepoint data after calls for crankshaft. 1012 // generate safepoint data after calls for crankshaft.
930 class PostCallGenerator { 1013 class CallWrapper {
931 public: 1014 public:
932 PostCallGenerator() { } 1015 CallWrapper() { }
933 virtual ~PostCallGenerator() { } 1016 virtual ~CallWrapper() { }
934 virtual void Generate() = 0; 1017 // Called just before emitting a call. Argument is the size of the generated
1018 // call code.
1019 virtual void BeforeCall(int call_size) = 0;
1020 // Called just after emitting a call, i.e., at the return site for the call.
1021 virtual void AfterCall() = 0;
935 }; 1022 };
936 1023
937 1024
938 // ----------------------------------------------------------------------------- 1025 // -----------------------------------------------------------------------------
939 // Static helper functions. 1026 // Static helper functions.
940 1027
941 static MemOperand ContextOperand(Register context, int index) { 1028 static MemOperand ContextOperand(Register context, int index) {
942 return MemOperand(context, Context::SlotOffset(index)); 1029 return MemOperand(context, Context::SlotOffset(index));
943 } 1030 }
944 1031
945 1032
946 static inline MemOperand GlobalObjectOperand() { 1033 static inline MemOperand GlobalObjectOperand() {
947 return ContextOperand(cp, Context::GLOBAL_INDEX); 1034 return ContextOperand(cp, Context::GLOBAL_INDEX);
948 } 1035 }
949 1036
950 1037
951 #ifdef GENERATED_CODE_COVERAGE 1038 #ifdef GENERATED_CODE_COVERAGE
952 #define CODE_COVERAGE_STRINGIFY(x) #x 1039 #define CODE_COVERAGE_STRINGIFY(x) #x
953 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 1040 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
954 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 1041 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
955 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 1042 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
956 #else 1043 #else
957 #define ACCESS_MASM(masm) masm-> 1044 #define ACCESS_MASM(masm) masm->
958 #endif 1045 #endif
959 1046
960 1047
961 } } // namespace v8::internal 1048 } } // namespace v8::internal
962 1049
963 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_ 1050 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/lithium-gap-resolver-arm.cc ('k') | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698