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 4457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4468 | 4468 |
4469 // Attempt to allocate the context in new space. | 4469 // Attempt to allocate the context in new space. |
4470 __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize), | 4470 __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize), |
4471 r0, | 4471 r0, |
4472 r1, | 4472 r1, |
4473 r2, | 4473 r2, |
4474 &gc, | 4474 &gc, |
4475 TAG_OBJECT); | 4475 TAG_OBJECT); |
4476 | 4476 |
4477 // Load the function from the stack. | 4477 // Load the function from the stack. |
4478 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); | 4478 __ ldr(r3, MemOperand(sp, 0)); |
4479 | 4479 |
4480 // Setup the object header. | 4480 // Setup the object header. |
4481 __ LoadRoot(r2, Heap::kContextMapRootIndex); | 4481 __ LoadRoot(r2, Heap::kContextMapRootIndex); |
4482 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4482 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); |
4483 __ mov(r2, Operand(length)); | 4483 __ mov(r2, Operand(length)); |
4484 __ str(r2, FieldMemOperand(r0, Array::kLengthOffset)); | 4484 __ str(r2, FieldMemOperand(r0, Array::kLengthOffset)); |
4485 | 4485 |
4486 // Setup the fixed slots. | 4486 // Setup the fixed slots. |
4487 __ mov(r1, Operand(Smi::FromInt(0))); | 4487 __ mov(r1, Operand(Smi::FromInt(0))); |
4488 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX))); | 4488 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX))); |
(...skipping 2146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6635 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); | 6635 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); |
6636 __ BranchOnSmi(r0, &slow); | 6636 __ BranchOnSmi(r0, &slow); |
6637 | 6637 |
6638 // Check that the left hand is a JS object and put map in r3. | 6638 // Check that the left hand is a JS object and put map in r3. |
6639 __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE); | 6639 __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE); |
6640 __ b(lt, &slow); | 6640 __ b(lt, &slow); |
6641 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); | 6641 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); |
6642 __ b(gt, &slow); | 6642 __ b(gt, &slow); |
6643 | 6643 |
6644 // Get the prototype of the function (r4 is result, r2 is scratch). | 6644 // Get the prototype of the function (r4 is result, r2 is scratch). |
6645 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); | 6645 __ ldr(r1, MemOperand(sp, 0)); |
6646 __ TryGetFunctionPrototype(r1, r4, r2, &slow); | 6646 __ TryGetFunctionPrototype(r1, r4, r2, &slow); |
6647 | 6647 |
6648 // Check that the function prototype is a JS object. | 6648 // Check that the function prototype is a JS object. |
6649 __ BranchOnSmi(r4, &slow); | 6649 __ BranchOnSmi(r4, &slow); |
6650 __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE); | 6650 __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE); |
6651 __ b(lt, &slow); | 6651 __ b(lt, &slow); |
6652 __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE)); | 6652 __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE)); |
6653 __ b(gt, &slow); | 6653 __ b(gt, &slow); |
6654 | 6654 |
6655 // Register mapping: r3 is object map and r4 is function prototype. | 6655 // Register mapping: r3 is object map and r4 is function prototype. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6750 | 6750 |
6751 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 6751 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
6752 // by calling the runtime system. | 6752 // by calling the runtime system. |
6753 __ bind(&slow); | 6753 __ bind(&slow); |
6754 __ push(r1); | 6754 __ push(r1); |
6755 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1); | 6755 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1); |
6756 } | 6756 } |
6757 | 6757 |
6758 | 6758 |
6759 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { | 6759 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
| 6760 // sp[0] : number of parameters |
| 6761 // sp[4] : receiver displacement |
| 6762 // sp[8] : function |
| 6763 |
6760 // Check if the calling frame is an arguments adaptor frame. | 6764 // Check if the calling frame is an arguments adaptor frame. |
6761 Label runtime; | 6765 Label adaptor_frame, try_allocate, runtime; |
6762 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 6766 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
6763 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); | 6767 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
6764 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 6768 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
6765 __ b(ne, &runtime); | 6769 __ b(eq, &adaptor_frame); |
| 6770 |
| 6771 // Get the length from the frame. |
| 6772 __ ldr(r1, MemOperand(sp, 0)); |
| 6773 __ b(&try_allocate); |
6766 | 6774 |
6767 // Patch the arguments.length and the parameters pointer. | 6775 // Patch the arguments.length and the parameters pointer. |
6768 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 6776 __ bind(&adaptor_frame); |
6769 __ str(r0, MemOperand(sp, 0 * kPointerSize)); | 6777 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
6770 __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6778 __ str(r1, MemOperand(sp, 0)); |
| 6779 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
6771 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); | 6780 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); |
6772 __ str(r3, MemOperand(sp, 1 * kPointerSize)); | 6781 __ str(r3, MemOperand(sp, 1 * kPointerSize)); |
6773 | 6782 |
| 6783 // Try the new space allocation. Start out with computing the size |
| 6784 // of the arguments object and the elements array (in words, not |
| 6785 // bytes because AllocateInNewSpace expects words). |
| 6786 Label add_arguments_object; |
| 6787 __ bind(&try_allocate); |
| 6788 __ cmp(r1, Operand(0)); |
| 6789 __ b(eq, &add_arguments_object); |
| 6790 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); |
| 6791 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize)); |
| 6792 __ bind(&add_arguments_object); |
| 6793 __ add(r1, r1, Operand(Heap::kArgumentsObjectSize / kPointerSize)); |
| 6794 |
| 6795 // Do the allocation of both objects in one go. |
| 6796 __ AllocateInNewSpace(r1, r0, r2, r3, &runtime, TAG_OBJECT); |
| 6797 |
| 6798 // Get the arguments boilerplate from the current (global) context. |
| 6799 int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX); |
| 6800 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 6801 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset)); |
| 6802 __ ldr(r4, MemOperand(r4, offset)); |
| 6803 |
| 6804 // Copy the JS object part. |
| 6805 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
| 6806 __ ldr(r3, FieldMemOperand(r4, i)); |
| 6807 __ str(r3, FieldMemOperand(r0, i)); |
| 6808 } |
| 6809 |
| 6810 // Setup the callee in-object property. |
| 6811 ASSERT(Heap::arguments_callee_index == 0); |
| 6812 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); |
| 6813 __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize)); |
| 6814 |
| 6815 // Get the length (smi tagged) and set that as an in-object property too. |
| 6816 ASSERT(Heap::arguments_length_index == 1); |
| 6817 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); |
| 6818 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize)); |
| 6819 |
| 6820 // If there are no actual arguments, we're done. |
| 6821 Label done; |
| 6822 __ cmp(r1, Operand(0)); |
| 6823 __ b(eq, &done); |
| 6824 |
| 6825 // Get the parameters pointer from the stack and untag the length. |
| 6826 __ ldr(r2, MemOperand(sp, 1 * kPointerSize)); |
| 6827 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); |
| 6828 |
| 6829 // Setup the elements pointer in the allocated arguments object and |
| 6830 // initialize the header in the elements fixed array. |
| 6831 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize)); |
| 6832 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); |
| 6833 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex); |
| 6834 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset)); |
| 6835 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
| 6836 |
| 6837 // Copy the fixed array slots. |
| 6838 Label loop; |
| 6839 // Setup r4 to point to the first array slot. |
| 6840 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 6841 __ bind(&loop); |
| 6842 // Pre-decrement r2 with kPointerSize on each iteration. |
| 6843 // Pre-decrement in order to skip receiver. |
| 6844 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex)); |
| 6845 // Post-increment r4 with kPointerSize on each iteration. |
| 6846 __ str(r3, MemOperand(r4, kPointerSize, PostIndex)); |
| 6847 __ sub(r1, r1, Operand(1)); |
| 6848 __ cmp(r1, Operand(0)); |
| 6849 __ b(ne, &loop); |
| 6850 |
| 6851 // Return and remove the on-stack parameters. |
| 6852 __ bind(&done); |
| 6853 __ add(sp, sp, Operand(3 * kPointerSize)); |
| 6854 __ Ret(); |
| 6855 |
6774 // Do the runtime call to allocate the arguments object. | 6856 // Do the runtime call to allocate the arguments object. |
6775 __ bind(&runtime); | 6857 __ bind(&runtime); |
6776 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); | 6858 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); |
6777 } | 6859 } |
6778 | 6860 |
6779 | 6861 |
6780 void CallFunctionStub::Generate(MacroAssembler* masm) { | 6862 void CallFunctionStub::Generate(MacroAssembler* masm) { |
6781 Label slow; | 6863 Label slow; |
6782 | 6864 |
6783 // If the receiver might be a value (string, number or boolean) check for this | 6865 // If the receiver might be a value (string, number or boolean) check for this |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7519 | 7601 |
7520 // Just jump to runtime to add the two strings. | 7602 // Just jump to runtime to add the two strings. |
7521 __ bind(&string_add_runtime); | 7603 __ bind(&string_add_runtime); |
7522 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); | 7604 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); |
7523 } | 7605 } |
7524 | 7606 |
7525 | 7607 |
7526 #undef __ | 7608 #undef __ |
7527 | 7609 |
7528 } } // namespace v8::internal | 7610 } } // namespace v8::internal |
OLD | NEW |