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

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

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 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-codegen-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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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.
37 class PostCallGenerator;
38
36 // ---------------------------------------------------------------------------- 39 // ----------------------------------------------------------------------------
37 // Static helper functions 40 // Static helper functions
38 41
39 // Generate a MemOperand for loading a field from an object. 42 // Generate a MemOperand for loading a field from an object.
40 static inline MemOperand FieldMemOperand(Register object, int offset) { 43 static inline MemOperand FieldMemOperand(Register object, int offset) {
41 return MemOperand(object, offset - kHeapObjectTag); 44 return MemOperand(object, offset - kHeapObjectTag);
42 } 45 }
43 46
44 47
48 static inline Operand SmiUntagOperand(Register object) {
49 return Operand(object, ASR, kSmiTagSize);
50 }
51
52
53
45 // Give alias names to registers 54 // Give alias names to registers
46 const Register cp = { 8 }; // JavaScript context pointer 55 const Register cp = { 8 }; // JavaScript context pointer
47 const Register roots = { 10 }; // Roots array pointer. 56 const Register roots = { 10 }; // Roots array pointer.
48 57
49 enum InvokeJSFlags { 58 enum InvokeJSFlags {
50 CALL_JS, 59 CALL_JS,
51 JUMP_JS 60 JUMP_JS
52 }; 61 };
53 62
54 63
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // Store an object to the root table. 138 // Store an object to the root table.
130 void StoreRoot(Register source, 139 void StoreRoot(Register source,
131 Heap::RootListIndex index, 140 Heap::RootListIndex index,
132 Condition cond = al); 141 Condition cond = al);
133 142
134 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER 143 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER
135 // Check if object is in new space. 144 // Check if object is in new space.
136 // scratch can be object itself, but it will be clobbered. 145 // scratch can be object itself, but it will be clobbered.
137 void InNewSpace(Register object, 146 void InNewSpace(Register object,
138 Register scratch, 147 Register scratch,
139 Condition cc, // eq for new space, ne otherwise 148 Condition cond, // eq for new space, ne otherwise
140 Label* branch); 149 Label* branch);
141 150
142 151
143 // For the page containing |object| mark the region covering [address] 152 // For the page containing |object| mark the region covering [address]
144 // dirty. The object address must be in the first 8K of an allocated page. 153 // dirty. The object address must be in the first 8K of an allocated page.
145 void RecordWriteHelper(Register object, 154 void RecordWriteHelper(Register object,
146 Register address, 155 Register address,
147 Register scratch); 156 Register scratch);
148 157
149 // For the page containing |object| mark the region covering 158 // For the page containing |object| mark the region covering
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } else { 232 } else {
224 str(src1, MemOperand(sp, 4, NegPreIndex), cond); 233 str(src1, MemOperand(sp, 4, NegPreIndex), cond);
225 Push(src2, src3, src4, cond); 234 Push(src2, src3, src4, cond);
226 } 235 }
227 } 236 }
228 237
229 // Push and pop the registers that can hold pointers, as defined by the 238 // Push and pop the registers that can hold pointers, as defined by the
230 // RegList constant kSafepointSavedRegisters. 239 // RegList constant kSafepointSavedRegisters.
231 void PushSafepointRegisters(); 240 void PushSafepointRegisters();
232 void PopSafepointRegisters(); 241 void PopSafepointRegisters();
242 void PushSafepointRegistersAndDoubles();
243 void PopSafepointRegistersAndDoubles();
244 void StoreToSafepointRegisterSlot(Register reg);
245 void StoreToSafepointRegistersAndDoublesSlot(Register reg);
246 void LoadFromSafepointRegisterSlot(Register reg);
233 static int SafepointRegisterStackIndex(int reg_code); 247 static int SafepointRegisterStackIndex(int reg_code);
248 static MemOperand SafepointRegisterSlot(Register reg);
249 static MemOperand SafepointRegistersAndDoublesSlot(Register reg);
234 250
235 // Load two consecutive registers with two consecutive memory locations. 251 // Load two consecutive registers with two consecutive memory locations.
236 void Ldrd(Register dst1, 252 void Ldrd(Register dst1,
237 Register dst2, 253 Register dst2,
238 const MemOperand& src, 254 const MemOperand& src,
239 Condition cond = al); 255 Condition cond = al);
240 256
241 // Store two consecutive registers to two consecutive memory locations. 257 // Store two consecutive registers to two consecutive memory locations.
242 void Strd(Register src1, 258 void Strd(Register src1,
243 Register src2, 259 Register src2,
244 const MemOperand& dst, 260 const MemOperand& dst,
245 Condition cond = al); 261 Condition cond = al);
246 262
263 // Clear specified FPSCR bits.
264 void ClearFPSCRBits(const uint32_t bits_to_clear,
265 const Register scratch,
266 const Condition cond = al);
267
268 // Compare double values and move the result to the normal condition flags.
269 void VFPCompareAndSetFlags(const DwVfpRegister src1,
270 const DwVfpRegister src2,
271 const Condition cond = al);
272 void VFPCompareAndSetFlags(const DwVfpRegister src1,
273 const double src2,
274 const Condition cond = al);
275
276 // Compare double values and then load the fpscr flags to a register.
277 void VFPCompareAndLoadFlags(const DwVfpRegister src1,
278 const DwVfpRegister src2,
279 const Register fpscr_flags,
280 const Condition cond = al);
281 void VFPCompareAndLoadFlags(const DwVfpRegister src1,
282 const double src2,
283 const Register fpscr_flags,
284 const Condition cond = al);
285
286
247 // --------------------------------------------------------------------------- 287 // ---------------------------------------------------------------------------
248 // Activation frames 288 // Activation frames
249 289
250 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } 290 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
251 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } 291 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
252 292
253 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 293 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
254 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 294 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
255 295
256 // Enter exit frame. 296 // Enter exit frame.
257 // Expects the number of arguments in register r0 and 297 // stack_space - extra stack space, used for alignment before call to C.
258 // the builtin function to call in register r1. Exits with argc in 298 void EnterExitFrame(bool save_doubles, int stack_space = 0);
259 // r4, argv in r6, and and the builtin function to call in r5.
260 void EnterExitFrame(bool save_doubles);
261 299
262 // Leave the current exit frame. Expects the return value in r0. 300 // Leave the current exit frame. Expects the return value in r0.
263 void LeaveExitFrame(bool save_doubles); 301 // Expect the number of values, pushed prior to the exit frame, to
302 // remove in a register (or no_reg, if there is nothing to remove).
303 void LeaveExitFrame(bool save_doubles, Register argument_count);
264 304
265 // Get the actual activation frame alignment for target environment. 305 // Get the actual activation frame alignment for target environment.
266 static int ActivationFrameAlignment(); 306 static int ActivationFrameAlignment();
267 307
268 void LoadContext(Register dst, int context_chain_length); 308 void LoadContext(Register dst, int context_chain_length);
269 309
270 void LoadGlobalFunction(int index, Register function); 310 void LoadGlobalFunction(int index, Register function);
271 311
272 // Load the initial map from the global function. The registers 312 // Load the initial map from the global function. The registers
273 // function and map can be the same, function is then overwritten. 313 // function and map can be the same, function is then overwritten.
274 void LoadGlobalFunctionInitialMap(Register function, 314 void LoadGlobalFunctionInitialMap(Register function,
275 Register map, 315 Register map,
276 Register scratch); 316 Register scratch);
277 317
278 // --------------------------------------------------------------------------- 318 // ---------------------------------------------------------------------------
279 // JavaScript invokes 319 // JavaScript invokes
280 320
281 // Invoke the JavaScript function code by either calling or jumping. 321 // Invoke the JavaScript function code by either calling or jumping.
282 void InvokeCode(Register code, 322 void InvokeCode(Register code,
283 const ParameterCount& expected, 323 const ParameterCount& expected,
284 const ParameterCount& actual, 324 const ParameterCount& actual,
285 InvokeFlag flag); 325 InvokeFlag flag,
326 PostCallGenerator* post_call_generator = NULL);
286 327
287 void InvokeCode(Handle<Code> code, 328 void InvokeCode(Handle<Code> code,
288 const ParameterCount& expected, 329 const ParameterCount& expected,
289 const ParameterCount& actual, 330 const ParameterCount& actual,
290 RelocInfo::Mode rmode, 331 RelocInfo::Mode rmode,
291 InvokeFlag flag); 332 InvokeFlag flag);
292 333
293 // Invoke the JavaScript function in the given register. Changes the 334 // Invoke the JavaScript function in the given register. Changes the
294 // current context to the context in the function before invoking. 335 // current context to the context in the function before invoking.
295 void InvokeFunction(Register function, 336 void InvokeFunction(Register function,
296 const ParameterCount& actual, 337 const ParameterCount& actual,
297 InvokeFlag flag); 338 InvokeFlag flag,
339 PostCallGenerator* post_call_generator = NULL);
298 340
299 void InvokeFunction(JSFunction* function, 341 void InvokeFunction(JSFunction* function,
300 const ParameterCount& actual, 342 const ParameterCount& actual,
301 InvokeFlag flag); 343 InvokeFlag flag);
302 344
303 void IsObjectJSObjectType(Register heap_object, 345 void IsObjectJSObjectType(Register heap_object,
304 Register map, 346 Register map,
305 Register scratch, 347 Register scratch,
306 Label* fail); 348 Label* fail);
307 349
(...skipping 17 matching lines...) Expand all
325 367
326 // Push a new try handler and link into try handler chain. 368 // Push a new try handler and link into try handler chain.
327 // The return address must be passed in register lr. 369 // The return address must be passed in register lr.
328 // On exit, r0 contains TOS (code slot). 370 // On exit, r0 contains TOS (code slot).
329 void PushTryHandler(CodeLocation try_location, HandlerType type); 371 void PushTryHandler(CodeLocation try_location, HandlerType type);
330 372
331 // Unlink the stack handler on top of the stack from the try handler chain. 373 // Unlink the stack handler on top of the stack from the try handler chain.
332 // Must preserve the result register. 374 // Must preserve the result register.
333 void PopTryHandler(); 375 void PopTryHandler();
334 376
377 // Passes thrown value (in r0) to the handler of top of the try handler chain.
378 void Throw(Register value);
379
380 // Propagates an uncatchable exception to the top of the current JS stack's
381 // handler chain.
382 void ThrowUncatchable(UncatchableExceptionType type, Register value);
383
335 // --------------------------------------------------------------------------- 384 // ---------------------------------------------------------------------------
336 // Inline caching support 385 // Inline caching support
337 386
338 // Generate code for checking access rights - used for security checks 387 // Generate code for checking access rights - used for security checks
339 // on access to global objects across environments. The holder register 388 // on access to global objects across environments. The holder register
340 // is left untouched, whereas both scratch registers are clobbered. 389 // is left untouched, whereas both scratch registers are clobbered.
341 void CheckAccessGlobalProxy(Register holder_reg, 390 void CheckAccessGlobalProxy(Register holder_reg,
342 Register scratch, 391 Register scratch,
343 Label* miss); 392 Label* miss);
344 393
(...skipping 28 matching lines...) Expand all
373 : -1; 422 : -1;
374 ASSERT((type == -1) || 423 ASSERT((type == -1) ||
375 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER))); 424 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
376 return type; 425 return type;
377 } 426 }
378 427
379 428
380 // --------------------------------------------------------------------------- 429 // ---------------------------------------------------------------------------
381 // Allocation support 430 // Allocation support
382 431
383 // Allocate an object in new space. The object_size is specified in words (not 432 // Allocate an object in new space. The object_size is specified
384 // bytes). If the new space is exhausted control continues at the gc_required 433 // either in bytes or in words if the allocation flag SIZE_IN_WORDS
385 // label. The allocated object is returned in result. If the flag 434 // is passed. If the new space is exhausted control continues at the
386 // tag_allocated_object is true the result is tagged as as a heap object. All 435 // gc_required label. The allocated object is returned in result. If
387 // registers are clobbered also when control continues at the gc_required 436 // the flag tag_allocated_object is true the result is tagged as as
388 // label. 437 // a heap object. All registers are clobbered also when control
438 // continues at the gc_required label.
389 void AllocateInNewSpace(int object_size, 439 void AllocateInNewSpace(int object_size,
390 Register result, 440 Register result,
391 Register scratch1, 441 Register scratch1,
392 Register scratch2, 442 Register scratch2,
393 Label* gc_required, 443 Label* gc_required,
394 AllocationFlags flags); 444 AllocationFlags flags);
395 void AllocateInNewSpace(Register object_size, 445 void AllocateInNewSpace(Register object_size,
396 Register result, 446 Register result,
397 Register scratch1, 447 Register scratch1,
398 Register scratch2, 448 Register scratch2,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 Condition IsObjectStringType(Register obj, 555 Condition IsObjectStringType(Register obj,
506 Register type) { 556 Register type) {
507 ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset)); 557 ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset));
508 ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); 558 ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
509 tst(type, Operand(kIsNotStringMask)); 559 tst(type, Operand(kIsNotStringMask));
510 ASSERT_EQ(0, kStringTag); 560 ASSERT_EQ(0, kStringTag);
511 return eq; 561 return eq;
512 } 562 }
513 563
514 564
515 inline void BranchOnSmi(Register value, Label* smi_label) {
516 tst(value, Operand(kSmiTagMask));
517 b(eq, smi_label);
518 }
519
520 inline void BranchOnNotSmi(Register value, Label* not_smi_label) {
521 tst(value, Operand(kSmiTagMask));
522 b(ne, not_smi_label);
523 }
524
525 // Generates code for reporting that an illegal operation has 565 // Generates code for reporting that an illegal operation has
526 // occurred. 566 // occurred.
527 void IllegalOperation(int num_arguments); 567 void IllegalOperation(int num_arguments);
528 568
529 // Picks out an array index from the hash field. 569 // Picks out an array index from the hash field.
530 // Register use: 570 // Register use:
531 // hash - holds the index's hash. Clobbered. 571 // hash - holds the index's hash. Clobbered.
532 // index - holds the overwritten index on exit. 572 // index - holds the overwritten index on exit.
533 void IndexFromHash(Register hash, Register index); 573 void IndexFromHash(Register hash, Register index);
534 574
535 // Get the number of least significant bits from a register 575 // Get the number of least significant bits from a register
536 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits); 576 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
577 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
537 578
538 // Uses VFP instructions to Convert a Smi to a double. 579 // Uses VFP instructions to Convert a Smi to a double.
539 void IntegerToDoubleConversionWithVFP3(Register inReg, 580 void IntegerToDoubleConversionWithVFP3(Register inReg,
540 Register outHighReg, 581 Register outHighReg,
541 Register outLowReg); 582 Register outLowReg);
542 583
543 // Load the value of a number object into a VFP double register. If the object 584 // Load the value of a number object into a VFP double register. If the object
544 // is not a number a jump to the label not_number is performed and the VFP 585 // is not a number a jump to the label not_number is performed and the VFP
545 // double register is unchanged. 586 // double register is unchanged.
546 void ObjectToDoubleVFPRegister( 587 void ObjectToDoubleVFPRegister(
547 Register object, 588 Register object,
548 DwVfpRegister value, 589 DwVfpRegister value,
549 Register scratch1, 590 Register scratch1,
550 Register scratch2, 591 Register scratch2,
551 Register heap_number_map, 592 Register heap_number_map,
552 SwVfpRegister scratch3, 593 SwVfpRegister scratch3,
553 Label* not_number, 594 Label* not_number,
554 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS); 595 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
555 596
556 // Load the value of a smi object into a VFP double register. The register 597 // Load the value of a smi object into a VFP double register. The register
557 // scratch1 can be the same register as smi in which case smi will hold the 598 // scratch1 can be the same register as smi in which case smi will hold the
558 // untagged value afterwards. 599 // untagged value afterwards.
559 void SmiToDoubleVFPRegister(Register smi, 600 void SmiToDoubleVFPRegister(Register smi,
560 DwVfpRegister value, 601 DwVfpRegister value,
561 Register scratch1, 602 Register scratch1,
562 SwVfpRegister scratch2); 603 SwVfpRegister scratch2);
563 604
564 // Convert the HeapNumber pointed to by source to a 32bits signed integer 605 // Convert the HeapNumber pointed to by source to a 32bits signed integer
565 // dest. If the HeapNumber does not fit into a 32bits signed integer branch 606 // dest. If the HeapNumber does not fit into a 32bits signed integer branch
566 // to not_int32 label. 607 // to not_int32 label. If VFP3 is available double_scratch is used but not
608 // scratch2.
567 void ConvertToInt32(Register source, 609 void ConvertToInt32(Register source,
568 Register dest, 610 Register dest,
569 Register scratch, 611 Register scratch,
570 Register scratch2, 612 Register scratch2,
613 DwVfpRegister double_scratch,
571 Label *not_int32); 614 Label *not_int32);
572 615
573 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz 616 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
574 // instruction. On pre-ARM5 hardware this routine gives the wrong answer 617 // instruction. On pre-ARM5 hardware this routine gives the wrong answer
575 // for 0 (31 instead of 32). Source and scratch can be the same in which case 618 // for 0 (31 instead of 32). Source and scratch can be the same in which case
576 // the source is clobbered. Source and zeros can also be the same in which 619 // the source is clobbered. Source and zeros can also be the same in which
577 // case scratch should be a different register. 620 // case scratch should be a different register.
578 void CountLeadingZeros(Register zeros, 621 void CountLeadingZeros(Register zeros,
579 Register source, 622 Register source,
580 Register scratch); 623 Register scratch);
581 624
582 // --------------------------------------------------------------------------- 625 // ---------------------------------------------------------------------------
583 // Runtime calls 626 // Runtime calls
584 627
585 // Call a code stub. 628 // Call a code stub.
586 void CallStub(CodeStub* stub, Condition cond = al); 629 void CallStub(CodeStub* stub, Condition cond = al);
587 630
588 // Call a code stub. 631 // Call a code stub.
589 void TailCallStub(CodeStub* stub, Condition cond = al); 632 void TailCallStub(CodeStub* stub, Condition cond = al);
590 633
634 // Tail call a code stub (jump) and return the code object called. Try to
635 // generate the code if necessary. Do not perform a GC but instead return
636 // a retry after GC failure.
637 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub,
638 Condition cond = al);
639
591 // Call a runtime routine. 640 // Call a runtime routine.
592 void CallRuntime(Runtime::Function* f, int num_arguments); 641 void CallRuntime(Runtime::Function* f, int num_arguments);
593 void CallRuntimeSaveDoubles(Runtime::FunctionId id); 642 void CallRuntimeSaveDoubles(Runtime::FunctionId id);
594 643
595 // Convenience function: Same as above, but takes the fid instead. 644 // Convenience function: Same as above, but takes the fid instead.
596 void CallRuntime(Runtime::FunctionId fid, int num_arguments); 645 void CallRuntime(Runtime::FunctionId fid, int num_arguments);
597 646
598 // Convenience function: call an external reference. 647 // Convenience function: call an external reference.
599 void CallExternalReference(const ExternalReference& ext, 648 void CallExternalReference(const ExternalReference& ext,
600 int num_arguments); 649 int num_arguments);
601 650
602 // Tail call of a runtime routine (jump). 651 // Tail call of a runtime routine (jump).
603 // Like JumpToExternalReference, but also takes care of passing the number 652 // Like JumpToExternalReference, but also takes care of passing the number
604 // of parameters. 653 // of parameters.
605 void TailCallExternalReference(const ExternalReference& ext, 654 void TailCallExternalReference(const ExternalReference& ext,
606 int num_arguments, 655 int num_arguments,
607 int result_size); 656 int result_size);
608 657
658 // Tail call of a runtime routine (jump). Try to generate the code if
659 // necessary. Do not perform a GC but instead return a retry after GC
660 // failure.
661 MUST_USE_RESULT MaybeObject* TryTailCallExternalReference(
662 const ExternalReference& ext, int num_arguments, int result_size);
663
609 // Convenience function: tail call a runtime routine (jump). 664 // Convenience function: tail call a runtime routine (jump).
610 void TailCallRuntime(Runtime::FunctionId fid, 665 void TailCallRuntime(Runtime::FunctionId fid,
611 int num_arguments, 666 int num_arguments,
612 int result_size); 667 int result_size);
613 668
614 // Before calling a C-function from generated code, align arguments on stack. 669 // Before calling a C-function from generated code, align arguments on stack.
615 // After aligning the frame, non-register arguments must be stored in 670 // After aligning the frame, non-register arguments must be stored in
616 // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments 671 // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
617 // are word sized. 672 // are word sized.
618 // Some compilers/platforms require the stack to be aligned when calling 673 // Some compilers/platforms require the stack to be aligned when calling
619 // C++ code. 674 // C++ code.
620 // Needs a scratch register to do some arithmetic. This register will be 675 // Needs a scratch register to do some arithmetic. This register will be
621 // trashed. 676 // trashed.
622 void PrepareCallCFunction(int num_arguments, Register scratch); 677 void PrepareCallCFunction(int num_arguments, Register scratch);
623 678
624 // Calls a C function and cleans up the space for arguments allocated 679 // Calls a C function and cleans up the space for arguments allocated
625 // by PrepareCallCFunction. The called function is not allowed to trigger a 680 // by PrepareCallCFunction. The called function is not allowed to trigger a
626 // garbage collection, since that might move the code and invalidate the 681 // garbage collection, since that might move the code and invalidate the
627 // return address (unless this is somehow accounted for by the called 682 // return address (unless this is somehow accounted for by the called
628 // function). 683 // function).
629 void CallCFunction(ExternalReference function, int num_arguments); 684 void CallCFunction(ExternalReference function, int num_arguments);
630 void CallCFunction(Register function, int num_arguments); 685 void CallCFunction(Register function, int num_arguments);
631 686
687 // Calls an API function. Allocates HandleScope, extracts returned value
688 // from handle and propagates exceptions. Restores context.
689 // stack_space - space to be unwound on exit (includes the call js
690 // arguments space and the additional space allocated for the fast call).
691 MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function,
692 int stack_space);
693
632 // Jump to a runtime routine. 694 // Jump to a runtime routine.
633 void JumpToExternalReference(const ExternalReference& builtin); 695 void JumpToExternalReference(const ExternalReference& builtin);
634 696
697 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext);
698
635 // Invoke specified builtin JavaScript function. Adds an entry to 699 // Invoke specified builtin JavaScript function. Adds an entry to
636 // the unresolved list if the name does not resolve. 700 // the unresolved list if the name does not resolve.
637 void InvokeBuiltin(Builtins::JavaScript id, InvokeJSFlags flags); 701 void InvokeBuiltin(Builtins::JavaScript id,
702 InvokeJSFlags flags,
703 PostCallGenerator* post_call_generator = NULL);
638 704
639 // Store the code object for the given builtin in the target register and 705 // Store the code object for the given builtin in the target register and
640 // setup the function in r1. 706 // setup the function in r1.
641 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 707 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
642 708
643 // Store the function for the given builtin in the target register. 709 // Store the function for the given builtin in the target register.
644 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 710 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
645 711
646 Handle<Object> CodeObject() { return code_object_; } 712 Handle<Object> CodeObject() { return code_object_; }
647 713
648 714
649 // --------------------------------------------------------------------------- 715 // ---------------------------------------------------------------------------
650 // StatsCounter support 716 // StatsCounter support
651 717
652 void SetCounter(StatsCounter* counter, int value, 718 void SetCounter(StatsCounter* counter, int value,
653 Register scratch1, Register scratch2); 719 Register scratch1, Register scratch2);
654 void IncrementCounter(StatsCounter* counter, int value, 720 void IncrementCounter(StatsCounter* counter, int value,
655 Register scratch1, Register scratch2); 721 Register scratch1, Register scratch2);
656 void DecrementCounter(StatsCounter* counter, int value, 722 void DecrementCounter(StatsCounter* counter, int value,
657 Register scratch1, Register scratch2); 723 Register scratch1, Register scratch2);
658 724
659 725
660 // --------------------------------------------------------------------------- 726 // ---------------------------------------------------------------------------
661 // Debugging 727 // Debugging
662 728
663 // Calls Abort(msg) if the condition cc is not satisfied. 729 // Calls Abort(msg) if the condition cond is not satisfied.
664 // Use --debug_code to enable. 730 // Use --debug_code to enable.
665 void Assert(Condition cc, const char* msg); 731 void Assert(Condition cond, const char* msg);
666 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index); 732 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
667 void AssertFastElements(Register elements); 733 void AssertFastElements(Register elements);
668 734
669 // Like Assert(), but always enabled. 735 // Like Assert(), but always enabled.
670 void Check(Condition cc, const char* msg); 736 void Check(Condition cond, const char* msg);
671 737
672 // Print a message to stdout and abort execution. 738 // Print a message to stdout and abort execution.
673 void Abort(const char* msg); 739 void Abort(const char* msg);
674 740
675 // Verify restrictions about code generated in stubs. 741 // Verify restrictions about code generated in stubs.
676 void set_generating_stub(bool value) { generating_stub_ = value; } 742 void set_generating_stub(bool value) { generating_stub_ = value; }
677 bool generating_stub() { return generating_stub_; } 743 bool generating_stub() { return generating_stub_; }
678 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 744 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
679 bool allow_stub_calls() { return allow_stub_calls_; } 745 bool allow_stub_calls() { return allow_stub_calls_; }
680 746
681 // --------------------------------------------------------------------------- 747 // ---------------------------------------------------------------------------
748 // Number utilities
749
750 // Check whether the value of reg is a power of two and not zero. If not
751 // control continues at the label not_power_of_two. If reg is a power of two
752 // the register scratch contains the value of (reg - 1) when control falls
753 // through.
754 void JumpIfNotPowerOfTwoOrZero(Register reg,
755 Register scratch,
756 Label* not_power_of_two_or_zero);
757
758 // ---------------------------------------------------------------------------
682 // Smi utilities 759 // Smi utilities
683 760
684 void SmiTag(Register reg, SBit s = LeaveCC) { 761 void SmiTag(Register reg, SBit s = LeaveCC) {
685 add(reg, reg, Operand(reg), s); 762 add(reg, reg, Operand(reg), s);
686 } 763 }
764 void SmiTag(Register dst, Register src, SBit s = LeaveCC) {
765 add(dst, src, Operand(src), s);
766 }
767
768 // 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
770 // sets flags.
771 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
772 mov(scratch, reg);
773 SmiTag(scratch, SetCC);
774 b(vs, not_a_smi);
775 mov(reg, scratch);
776 }
687 777
688 void SmiUntag(Register reg) { 778 void SmiUntag(Register reg) {
689 mov(reg, Operand(reg, ASR, kSmiTagSize)); 779 mov(reg, Operand(reg, ASR, kSmiTagSize));
690 } 780 }
781 void SmiUntag(Register dst, Register src) {
782 mov(dst, Operand(src, ASR, kSmiTagSize));
783 }
691 784
785 // Jump the register contains a smi.
786 inline void JumpIfSmi(Register value, Label* smi_label) {
787 tst(value, Operand(kSmiTagMask));
788 b(eq, smi_label);
789 }
790 // Jump if either of the registers contain a non-smi.
791 inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
792 tst(value, Operand(kSmiTagMask));
793 b(ne, not_smi_label);
794 }
692 // Jump if either of the registers contain a non-smi. 795 // Jump if either of the registers contain a non-smi.
693 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); 796 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
694 // Jump if either of the registers contain a smi. 797 // Jump if either of the registers contain a smi.
695 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); 798 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
696 799
697 // Abort execution if argument is a smi. Used in debug code. 800 // Abort execution if argument is a smi. Used in debug code.
698 void AbortIfSmi(Register object); 801 void AbortIfSmi(Register object);
802 void AbortIfNotSmi(Register object);
803
804 // Abort execution if argument is a string. Used in debug code.
805 void AbortIfNotString(Register object);
806
807 // Abort execution if argument is not the root value with the given index.
808 void AbortIfNotRootValue(Register src,
809 Heap::RootListIndex root_value_index,
810 const char* message);
811
812 // ---------------------------------------------------------------------------
813 // HeapNumber utilities
814
815 void JumpIfNotHeapNumber(Register object,
816 Register heap_number_map,
817 Register scratch,
818 Label* on_not_heap_number);
699 819
700 // --------------------------------------------------------------------------- 820 // ---------------------------------------------------------------------------
701 // String utilities 821 // String utilities
702 822
703 // Checks if both objects are sequential ASCII strings and jumps to label 823 // Checks if both objects are sequential ASCII strings and jumps to label
704 // if either is not. Assumes that neither object is a smi. 824 // if either is not. Assumes that neither object is a smi.
705 void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1, 825 void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1,
706 Register object2, 826 Register object2,
707 Register scratch1, 827 Register scratch1,
708 Register scratch2, 828 Register scratch2,
(...skipping 16 matching lines...) Expand all
725 Register scratch2, 845 Register scratch2,
726 Label* failure); 846 Label* failure);
727 847
728 // Check if instance type is sequential ASCII string and jump to label if 848 // Check if instance type is sequential ASCII string and jump to label if
729 // it is not. 849 // it is not.
730 void JumpIfInstanceTypeIsNotSequentialAscii(Register type, 850 void JumpIfInstanceTypeIsNotSequentialAscii(Register type,
731 Register scratch, 851 Register scratch,
732 Label* failure); 852 Label* failure);
733 853
734 854
855 // ---------------------------------------------------------------------------
856 // Patching helpers.
857
858 // Get the location of a relocated constant (its address in the constant pool)
859 // from its load site.
860 void GetRelocatedValueLocation(Register ldr_location,
861 Register result);
862
863
735 private: 864 private:
736 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 865 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
737 void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 866 void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
738 867
739 // Helper functions for generating invokes. 868 // Helper functions for generating invokes.
740 void InvokePrologue(const ParameterCount& expected, 869 void InvokePrologue(const ParameterCount& expected,
741 const ParameterCount& actual, 870 const ParameterCount& actual,
742 Handle<Code> code_constant, 871 Handle<Code> code_constant,
743 Register code_reg, 872 Register code_reg,
744 Label* done, 873 Label* done,
745 InvokeFlag flag); 874 InvokeFlag flag,
875 PostCallGenerator* post_call_generator = NULL);
746 876
747 // Activation support. 877 // Activation support.
748 void EnterFrame(StackFrame::Type type); 878 void EnterFrame(StackFrame::Type type);
749 void LeaveFrame(StackFrame::Type type); 879 void LeaveFrame(StackFrame::Type type);
750 880
751 void InitializeNewString(Register string, 881 void InitializeNewString(Register string,
752 Register length, 882 Register length,
753 Heap::RootListIndex map_index, 883 Heap::RootListIndex map_index,
754 Register scratch1, 884 Register scratch1,
755 Register scratch2); 885 Register scratch2);
(...skipping 13 matching lines...) Expand all
769 // an assertion to fail. 899 // an assertion to fail.
770 class CodePatcher { 900 class CodePatcher {
771 public: 901 public:
772 CodePatcher(byte* address, int instructions); 902 CodePatcher(byte* address, int instructions);
773 virtual ~CodePatcher(); 903 virtual ~CodePatcher();
774 904
775 // Macro assembler to emit code. 905 // Macro assembler to emit code.
776 MacroAssembler* masm() { return &masm_; } 906 MacroAssembler* masm() { return &masm_; }
777 907
778 // Emit an instruction directly. 908 // Emit an instruction directly.
779 void Emit(Instr x); 909 void Emit(Instr instr);
780 910
781 // Emit an address directly. 911 // Emit an address directly.
782 void Emit(Address addr); 912 void Emit(Address addr);
783 913
914 // Emit the condition part of an instruction leaving the rest of the current
915 // instruction unchanged.
916 void EmitCondition(Condition cond);
917
784 private: 918 private:
785 byte* address_; // The address of the code being patched. 919 byte* address_; // The address of the code being patched.
786 int instructions_; // Number of instructions of the expected patch size. 920 int instructions_; // Number of instructions of the expected patch size.
787 int size_; // Number of bytes of the expected patch size. 921 int size_; // Number of bytes of the expected patch size.
788 MacroAssembler masm_; // Macro assembler used to generate the code. 922 MacroAssembler masm_; // Macro assembler used to generate the code.
789 }; 923 };
790 #endif // ENABLE_DEBUGGER_SUPPORT 924 #endif // ENABLE_DEBUGGER_SUPPORT
791 925
792 926
793 // Helper class for generating code or data associated with the code 927 // Helper class for generating code or data associated with the code
(...skipping 26 matching lines...) Expand all
820 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 954 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
821 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 955 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
822 #else 956 #else
823 #define ACCESS_MASM(masm) masm-> 957 #define ACCESS_MASM(masm) masm->
824 #endif 958 #endif
825 959
826 960
827 } } // namespace v8::internal 961 } } // namespace v8::internal
828 962
829 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_ 963 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698