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 7383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |