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

Side by Side Diff: src/x64/codegen-x64.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 | « src/x64/assembler-x64.cc ('k') | no next file » | 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 7383 matching lines...) Expand 10 before | Expand all | Expand 10 after
7394 __ movl(rax, Immediate(1)); 7394 __ movl(rax, Immediate(1));
7395 __ ret(2 * kPointerSize); 7395 __ ret(2 * kPointerSize);
7396 7396
7397 // Slow-case: Go through the JavaScript implementation. 7397 // Slow-case: Go through the JavaScript implementation.
7398 __ bind(&slow); 7398 __ bind(&slow);
7399 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 7399 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
7400 } 7400 }
7401 7401
7402 7402
7403 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { 7403 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
7404 // rsp[0] : return address
7405 // rsp[8] : number of parameters
7406 // rsp[16] : receiver displacement
7407 // rsp[24] : function
7408
7404 // The displacement is used for skipping the return address and the 7409 // The displacement is used for skipping the return address and the
7405 // frame pointer on the stack. It is the offset of the last 7410 // frame pointer on the stack. It is the offset of the last
7406 // parameter (if any) relative to the frame pointer. 7411 // parameter (if any) relative to the frame pointer.
7407 static const int kDisplacement = 2 * kPointerSize; 7412 static const int kDisplacement = 2 * kPointerSize;
7408 7413
7409 // Check if the calling frame is an arguments adaptor frame. 7414 // Check if the calling frame is an arguments adaptor frame.
7410 Label runtime; 7415 Label adaptor_frame, try_allocate, runtime;
7411 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 7416 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
7412 __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset), 7417 __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
7413 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 7418 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
7414 __ j(not_equal, &runtime); 7419 __ j(equal, &adaptor_frame);
7415 // Value in rcx is Smi encoded. 7420
7421 // Get the length from the frame.
7422 __ movq(rcx, Operand(rsp, 1 * kPointerSize));
7423 __ jmp(&try_allocate);
7416 7424
7417 // Patch the arguments.length and the parameters pointer. 7425 // Patch the arguments.length and the parameters pointer.
7426 __ bind(&adaptor_frame);
7418 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 7427 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
7419 __ movq(Operand(rsp, 1 * kPointerSize), rcx); 7428 __ movq(Operand(rsp, 1 * kPointerSize), rcx);
7420 SmiIndex index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2); 7429 // Do not clobber the length index for the indexing operation since
7430 // it is used compute the size for allocation later.
7431 SmiIndex index = masm->SmiToIndex(rbx, rcx, kPointerSizeLog2);
7421 __ lea(rdx, Operand(rdx, index.reg, index.scale, kDisplacement)); 7432 __ lea(rdx, Operand(rdx, index.reg, index.scale, kDisplacement));
7422 __ movq(Operand(rsp, 2 * kPointerSize), rdx); 7433 __ movq(Operand(rsp, 2 * kPointerSize), rdx);
7423 7434
7435 // Try the new space allocation. Start out with computing the size of
7436 // the arguments object and the elements array.
7437 Label add_arguments_object;
7438 __ bind(&try_allocate);
7439 __ testq(rcx, rcx);
7440 __ j(zero, &add_arguments_object);
7441 index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2);
7442 __ lea(rcx, Operand(index.reg, index.scale, FixedArray::kHeaderSize));
7443 __ bind(&add_arguments_object);
7444 __ addq(rcx, Immediate(Heap::kArgumentsObjectSize));
7445
7446 // Do the allocation of both objects in one go.
7447 __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
7448
7449 // Get the arguments boilerplate from the current (global) context.
7450 int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
7451 __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
7452 __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
7453 __ movq(rdi, Operand(rdi, offset));
7454
7455 // Copy the JS object part.
7456 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
7457 __ movq(kScratchRegister, FieldOperand(rdi, i));
7458 __ movq(FieldOperand(rax, i), kScratchRegister);
7459 }
7460
7461 // Setup the callee in-object property.
7462 ASSERT(Heap::arguments_callee_index == 0);
7463 __ movq(kScratchRegister, Operand(rsp, 3 * kPointerSize));
7464 __ movq(FieldOperand(rax, JSObject::kHeaderSize), kScratchRegister);
7465
7466 // Get the length (smi tagged) and set that as an in-object property too.
7467 ASSERT(Heap::arguments_length_index == 1);
7468 __ movq(rcx, Operand(rsp, 1 * kPointerSize));
7469 __ movq(FieldOperand(rax, JSObject::kHeaderSize + kPointerSize), rcx);
7470
7471 // If there are no actual arguments, we're done.
7472 Label done;
7473 __ testq(rcx, rcx);
7474 __ j(zero, &done);
7475
7476 // Get the parameters pointer from the stack and untag the length.
7477 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
7478 __ SmiToInteger32(rcx, rcx);
7479
7480 // Setup the elements pointer in the allocated arguments object and
7481 // initialize the header in the elements fixed array.
7482 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
7483 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
7484 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
7485 __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
7486 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
7487
7488 // Copy the fixed array slots.
7489 Label loop;
7490 __ bind(&loop);
7491 __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize)); // Skip receiver.
7492 __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
7493 __ addq(rdi, Immediate(kPointerSize));
7494 __ subq(rdx, Immediate(kPointerSize));
7495 __ decq(rcx);
7496 __ j(not_zero, &loop);
7497
7498 // Return and remove the on-stack parameters.
7499 __ bind(&done);
7500 __ ret(3 * kPointerSize);
7501
7424 // Do the runtime call to allocate the arguments object. 7502 // Do the runtime call to allocate the arguments object.
7425 __ bind(&runtime); 7503 __ bind(&runtime);
7426 Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast); 7504 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
7427 __ TailCallRuntime(ExternalReference(f), 3, f->result_size);
7428 } 7505 }
7429 7506
7430 7507
7431 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 7508 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
7432 // The key is in rdx and the parameter count is in rax. 7509 // The key is in rdx and the parameter count is in rax.
7433 7510
7434 // The displacement is used for skipping the frame pointer on the 7511 // The displacement is used for skipping the frame pointer on the
7435 // stack. It is the offset of the last parameter (if any) relative 7512 // stack. It is the offset of the last parameter (if any) relative
7436 // to the frame pointer. 7513 // to the frame pointer.
7437 static const int kDisplacement = 1 * kPointerSize; 7514 static const int kDisplacement = 1 * kPointerSize;
(...skipping 1937 matching lines...) Expand 10 before | Expand all | Expand 10 after
9375 // Call the function from C++. 9452 // Call the function from C++.
9376 return FUNCTION_CAST<ModuloFunction>(buffer); 9453 return FUNCTION_CAST<ModuloFunction>(buffer);
9377 } 9454 }
9378 9455
9379 #endif 9456 #endif
9380 9457
9381 9458
9382 #undef __ 9459 #undef __
9383 9460
9384 } } // namespace v8::internal 9461 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698