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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 605024: Port arguments object allocation in generated code to ARM and x64.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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 | « no previous file | src/ia32/codegen-ia32.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 4457 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698